aboutsummaryrefslogtreecommitdiff
path: root/template/en/default
diff options
context:
space:
mode:
Diffstat (limited to 'template/en/default')
-rw-r--r--template/en/default/account/auth/login-small.html.tmpl115
-rw-r--r--template/en/default/account/auth/login.html.tmpl118
-rw-r--r--template/en/default/account/cancel-token.txt.tmpl91
-rw-r--r--template/en/default/account/create.html.tmpl75
-rw-r--r--template/en/default/account/created.html.tmpl25
-rw-r--r--template/en/default/account/email/change-new.txt.tmpl27
-rw-r--r--template/en/default/account/email/change-old.txt.tmpl27
-rw-r--r--template/en/default/account/email/confirm-new.html.tmpl72
-rw-r--r--template/en/default/account/email/confirm.html.tmpl35
-rw-r--r--template/en/default/account/email/request-new.txt.tmpl47
-rw-r--r--template/en/default/account/password/forgotten-password.txt.tmpl26
-rw-r--r--template/en/default/account/password/set-forgotten-password.html.tmpl53
-rw-r--r--template/en/default/account/prefs/account.html.tmpl91
-rw-r--r--template/en/default/account/prefs/email.html.tmpl292
-rw-r--r--template/en/default/account/prefs/permissions.html.tmpl79
-rw-r--r--template/en/default/account/prefs/prefs.html.tmpl102
-rw-r--r--template/en/default/account/prefs/saved-searches.html.tmpl197
-rw-r--r--template/en/default/account/prefs/settings.html.tmpl68
-rw-r--r--template/en/default/account/profile-activity.html.tmpl73
-rw-r--r--template/en/default/admin/admin.html.tmpl127
-rw-r--r--template/en/default/admin/classifications/add.html.tmpl27
-rw-r--r--template/en/default/admin/classifications/del.html.tmpl51
-rw-r--r--template/en/default/admin/classifications/edit-common.html.tmpl35
-rw-r--r--template/en/default/admin/classifications/edit.html.tmpl55
-rw-r--r--template/en/default/admin/classifications/footer.html.tmpl10
-rw-r--r--template/en/default/admin/classifications/reclassify.html.tmpl77
-rw-r--r--template/en/default/admin/classifications/select.html.tmpl54
-rw-r--r--template/en/default/admin/components/confirm-delete.html.tmpl149
-rw-r--r--template/en/default/admin/components/create.html.tmpl36
-rw-r--r--template/en/default/admin/components/edit-common.html.tmpl77
-rw-r--r--template/en/default/admin/components/edit.html.tmpl66
-rw-r--r--template/en/default/admin/components/footer.html.tmpl42
-rw-r--r--template/en/default/admin/components/list.html.tmpl133
-rw-r--r--template/en/default/admin/components/select-product.html.tmpl54
-rw-r--r--template/en/default/admin/confirm-action.html.tmpl87
-rw-r--r--template/en/default/admin/custom_fields/cf-js.js.tmpl66
-rw-r--r--template/en/default/admin/custom_fields/confirm-delete.html.tmpl60
-rw-r--r--template/en/default/admin/custom_fields/create.html.tmpl179
-rw-r--r--template/en/default/admin/custom_fields/edit.html.tmpl195
-rw-r--r--template/en/default/admin/custom_fields/list.html.tmpl99
-rw-r--r--template/en/default/admin/fieldvalues/confirm-delete.html.tmpl154
-rw-r--r--template/en/default/admin/fieldvalues/create.html.tmpl92
-rw-r--r--template/en/default/admin/fieldvalues/edit.html.tmpl105
-rw-r--r--template/en/default/admin/fieldvalues/footer.html.tmpl48
-rw-r--r--template/en/default/admin/fieldvalues/list.html.tmpl90
-rw-r--r--template/en/default/admin/fieldvalues/select-field.html.tmpl37
-rw-r--r--template/en/default/admin/flag-type/confirm-delete.html.tmpl49
-rw-r--r--template/en/default/admin/flag-type/edit.html.tmpl265
-rw-r--r--template/en/default/admin/flag-type/list.html.tmpl159
-rw-r--r--template/en/default/admin/groups/confirm-remove.html.tmpl50
-rw-r--r--template/en/default/admin/groups/create.html.tmpl94
-rw-r--r--template/en/default/admin/groups/delete.html.tmpl172
-rw-r--r--template/en/default/admin/groups/edit.html.tmpl233
-rw-r--r--template/en/default/admin/groups/list.html.tmpl153
-rw-r--r--template/en/default/admin/keywords/confirm-delete.html.tmpl39
-rw-r--r--template/en/default/admin/keywords/create.html.tmpl45
-rw-r--r--template/en/default/admin/keywords/edit.html.tmpl57
-rw-r--r--template/en/default/admin/keywords/list.html.tmpl54
-rw-r--r--template/en/default/admin/milestones/confirm-delete.html.tmpl83
-rw-r--r--template/en/default/admin/milestones/create.html.tmpl46
-rw-r--r--template/en/default/admin/milestones/edit.html.tmpl53
-rw-r--r--template/en/default/admin/milestones/footer.html.tmpl55
-rw-r--r--template/en/default/admin/milestones/list.html.tmpl98
-rw-r--r--template/en/default/admin/milestones/select-product.html.tmpl54
-rw-r--r--template/en/default/admin/params/admin.html.tmpl28
-rw-r--r--template/en/default/admin/params/advanced.html.tmpl68
-rw-r--r--template/en/default/admin/params/attachment.html.tmpl62
-rw-r--r--template/en/default/admin/params/auth.html.tmpl130
-rw-r--r--template/en/default/admin/params/bugchange.html.tmpl42
-rw-r--r--template/en/default/admin/params/bugfields.html.tmpl45
-rw-r--r--template/en/default/admin/params/common.html.tmpl125
-rw-r--r--template/en/default/admin/params/core.html.tmpl35
-rw-r--r--template/en/default/admin/params/dependencygraph.html.tmpl36
-rw-r--r--template/en/default/admin/params/editparams.html.tmpl103
-rw-r--r--template/en/default/admin/params/general.html.tmpl73
-rw-r--r--template/en/default/admin/params/groupsecurity.html.tmpl46
-rw-r--r--template/en/default/admin/params/index.html.tmpl38
-rw-r--r--template/en/default/admin/params/ldap.html.tmpl45
-rw-r--r--template/en/default/admin/params/mta.html.tmpl67
-rw-r--r--template/en/default/admin/params/patchviewer.html.tmpl51
-rw-r--r--template/en/default/admin/params/query.html.tmpl64
-rw-r--r--template/en/default/admin/params/radius.html.tmpl43
-rw-r--r--template/en/default/admin/params/shadowdb.html.tmpl36
-rw-r--r--template/en/default/admin/params/usermatch.html.tmpl29
-rw-r--r--template/en/default/admin/products/confirm-delete.html.tmpl259
-rw-r--r--template/en/default/admin/products/create.html.tmpl74
-rw-r--r--template/en/default/admin/products/edit-common.html.tmpl72
-rw-r--r--template/en/default/admin/products/edit.html.tmpl142
-rw-r--r--template/en/default/admin/products/footer.html.tmpl79
-rw-r--r--template/en/default/admin/products/groupcontrol/confirm-edit.html.tmpl42
-rw-r--r--template/en/default/admin/products/groupcontrol/edit.html.tmpl303
-rw-r--r--template/en/default/admin/products/groupcontrol/updated.html.tmpl42
-rw-r--r--template/en/default/admin/products/list-classifications.html.tmpl58
-rw-r--r--template/en/default/admin/products/list.html.tmpl86
-rw-r--r--template/en/default/admin/products/updated.html.tmpl90
-rw-r--r--template/en/default/admin/sanitycheck/list.html.tmpl26
-rw-r--r--template/en/default/admin/sanitycheck/messages.html.tmpl312
-rw-r--r--template/en/default/admin/settings/edit.html.tmpl93
-rw-r--r--template/en/default/admin/sudo.html.tmpl91
-rw-r--r--template/en/default/admin/table.html.tmpl164
-rw-r--r--template/en/default/admin/users/confirm-delete.html.tmpl471
-rw-r--r--template/en/default/admin/users/create.html.tmpl51
-rw-r--r--template/en/default/admin/users/edit.html.tmpl173
-rw-r--r--template/en/default/admin/users/list.html.tmpl111
-rw-r--r--template/en/default/admin/users/listselectvars.html.tmpl26
-rw-r--r--template/en/default/admin/users/responsibilities.html.tmpl57
-rw-r--r--template/en/default/admin/users/search.html.tmpl79
-rw-r--r--template/en/default/admin/users/userdata.html.tmpl109
-rw-r--r--template/en/default/admin/versions/confirm-delete.html.tmpl89
-rw-r--r--template/en/default/admin/versions/create.html.tmpl40
-rw-r--r--template/en/default/admin/versions/edit.html.tmpl47
-rw-r--r--template/en/default/admin/versions/footer.html.tmpl53
-rw-r--r--template/en/default/admin/versions/list.html.tmpl79
-rw-r--r--template/en/default/admin/versions/select-product.html.tmpl54
-rw-r--r--template/en/default/admin/workflow/comment.html.tmpl82
-rw-r--r--template/en/default/admin/workflow/edit.html.tmpl100
-rw-r--r--template/en/default/attachment/choose.html.tmpl29
-rw-r--r--template/en/default/attachment/confirm-delete.html.tmpl83
-rw-r--r--template/en/default/attachment/create.html.tmpl133
-rw-r--r--template/en/default/attachment/created.html.tmpl54
-rw-r--r--template/en/default/attachment/createformcontents.html.tmpl98
-rw-r--r--template/en/default/attachment/delete_reason.txt.tmpl18
-rw-r--r--template/en/default/attachment/diff-file.html.tmpl164
-rw-r--r--template/en/default/attachment/diff-footer.html.tmpl21
-rw-r--r--template/en/default/attachment/diff-header.html.tmpl139
-rw-r--r--template/en/default/attachment/edit.html.tmpl331
-rw-r--r--template/en/default/attachment/list.html.tmpl165
-rw-r--r--template/en/default/attachment/midair.html.tmpl64
-rw-r--r--template/en/default/attachment/show-multiple.html.tmpl106
-rw-r--r--template/en/default/attachment/updated.html.tmpl32
-rw-r--r--template/en/default/bug/activity/show.html.tmpl35
-rw-r--r--template/en/default/bug/activity/table.html.tmpl103
-rw-r--r--template/en/default/bug/choose.html.tmpl21
-rw-r--r--template/en/default/bug/comments.html.tmpl196
-rw-r--r--template/en/default/bug/create/comment-guided.txt.tmpl34
-rw-r--r--template/en/default/bug/create/comment.txt.tmpl12
-rw-r--r--template/en/default/bug/create/create-guided.html.tmpl511
-rw-r--r--template/en/default/bug/create/create.html.tmpl727
-rw-r--r--template/en/default/bug/create/created.html.tmpl47
-rw-r--r--template/en/default/bug/create/make-template.html.tmpl31
-rw-r--r--template/en/default/bug/create/user-message.html.tmpl22
-rw-r--r--template/en/default/bug/dependency-graph.html.tmpl89
-rw-r--r--template/en/default/bug/dependency-tree.html.tmpl265
-rw-r--r--template/en/default/bug/edit.html.tmpl1172
-rw-r--r--template/en/default/bug/field-events.js.tmpl59
-rw-r--r--template/en/default/bug/field-help.none.tmpl243
-rw-r--r--template/en/default/bug/field-label.html.tmpl41
-rw-r--r--template/en/default/bug/field.html.tmpl242
-rw-r--r--template/en/default/bug/format_comment.txt.tmpl48
-rw-r--r--template/en/default/bug/knob.html.tmpl84
-rw-r--r--template/en/default/bug/link.html.tmpl51
-rw-r--r--template/en/default/bug/navigate.html.tmpl73
-rw-r--r--template/en/default/bug/process/bugmail.html.tmpl45
-rw-r--r--template/en/default/bug/process/confirm-duplicate.html.tmpl62
-rw-r--r--template/en/default/bug/process/header.html.tmpl32
-rw-r--r--template/en/default/bug/process/midair.html.tmpl97
-rw-r--r--template/en/default/bug/process/results.html.tmpl45
-rw-r--r--template/en/default/bug/process/verify-new-product.html.tmpl232
-rw-r--r--template/en/default/bug/show-header.html.tmpl58
-rw-r--r--template/en/default/bug/show-multiple.html.tmpl366
-rw-r--r--template/en/default/bug/show.html.tmpl36
-rw-r--r--template/en/default/bug/show.xml.tmpl161
-rw-r--r--template/en/default/bug/summarize-time.html.tmpl341
-rw-r--r--template/en/default/bug/time.html.tmpl34
-rw-r--r--template/en/default/config.js.tmpl137
-rw-r--r--template/en/default/config.rdf.tmpl288
-rw-r--r--template/en/default/email/bugmail-common.txt.tmpl25
-rw-r--r--template/en/default/email/bugmail-header.txt.tmpl36
-rw-r--r--template/en/default/email/bugmail.html.tmpl119
-rw-r--r--template/en/default/email/bugmail.txt.tmpl66
-rw-r--r--template/en/default/email/flagmail.txt.tmpl74
-rw-r--r--template/en/default/email/lockout.txt.tmpl25
-rw-r--r--template/en/default/email/sanitycheck.txt.tmpl23
-rw-r--r--template/en/default/email/sudo.txt.tmpl29
-rw-r--r--template/en/default/email/whine.txt.tmpl51
-rw-r--r--template/en/default/extensions/config.pm.tmpl26
-rw-r--r--template/en/default/extensions/extension.pm.tmpl31
-rw-r--r--template/en/default/extensions/hook-readme.txt.tmpl13
-rw-r--r--template/en/default/extensions/license.txt.tmpl18
-rw-r--r--template/en/default/extensions/name-readme.txt.tmpl24
-rw-r--r--template/en/default/extensions/util.pm.tmpl27
-rw-r--r--template/en/default/extensions/web-readme.txt.tmpl15
-rw-r--r--template/en/default/filterexceptions.pl468
-rw-r--r--template/en/default/flag/list.html.tmpl167
-rw-r--r--template/en/default/global/banner.html.tmpl12
-rw-r--r--template/en/default/global/calendar.js.tmpl33
-rw-r--r--template/en/default/global/choose-classification.html.tmpl54
-rw-r--r--template/en/default/global/choose-product.html.tmpl61
-rw-r--r--template/en/default/global/code-error.html.tmpl463
-rw-r--r--template/en/default/global/common-links.html.tmpl111
-rw-r--r--template/en/default/global/confirm-action.html.tmpl53
-rw-r--r--template/en/default/global/confirm-user-match.html.tmpl191
-rw-r--r--template/en/default/global/docslinks.html.tmpl45
-rw-r--r--template/en/default/global/field-descs.none.tmpl142
-rw-r--r--template/en/default/global/footer.html.tmpl36
-rw-r--r--template/en/default/global/header.html.tmpl313
-rw-r--r--template/en/default/global/hidden-fields.html.tmpl46
-rw-r--r--template/en/default/global/js-products.html.tmpl21
-rw-r--r--template/en/default/global/message.html.tmpl28
-rw-r--r--template/en/default/global/message.txt.tmpl12
-rw-r--r--template/en/default/global/messages.html.tmpl927
-rw-r--r--template/en/default/global/reason-descs.none.tmpl28
-rw-r--r--template/en/default/global/select-menu.html.tmpl52
-rw-r--r--template/en/default/global/setting-descs.none.tmpl49
-rw-r--r--template/en/default/global/site-navigation.html.tmpl75
-rw-r--r--template/en/default/global/tabs.html.tmpl42
-rw-r--r--template/en/default/global/textarea.html.tmpl55
-rw-r--r--template/en/default/global/useful-links.html.tmpl74
-rw-r--r--template/en/default/global/user-error.html.tmpl1964
-rw-r--r--template/en/default/global/user.html.tmpl26
-rw-r--r--template/en/default/global/userselect.html.tmpl99
-rw-r--r--template/en/default/global/value-descs.js.tmpl21
-rw-r--r--template/en/default/global/value-descs.none.tmpl24
-rw-r--r--template/en/default/global/variables.none.tmpl33
-rw-r--r--template/en/default/index.html.tmpl173
-rw-r--r--template/en/default/list/change-columns.html.tmpl131
-rw-r--r--template/en/default/list/edit-multiple.html.tmpl435
-rw-r--r--template/en/default/list/list-simple.html.tmpl32
-rw-r--r--template/en/default/list/list.atom.tmpl82
-rw-r--r--template/en/default/list/list.csv.tmpl38
-rw-r--r--template/en/default/list/list.html.tmpl342
-rw-r--r--template/en/default/list/list.ics.tmpl90
-rw-r--r--template/en/default/list/list.rdf.tmpl44
-rw-r--r--template/en/default/list/quips.html.tmpl159
-rw-r--r--template/en/default/list/server-push.html.tmpl30
-rw-r--r--template/en/default/list/table.html.tmpl250
-rw-r--r--template/en/default/pages/bug-writing.html.tmpl162
-rw-r--r--template/en/default/pages/bugzilla.dtd.tmpl162
-rw-r--r--template/en/default/pages/fields.html.tmpl227
-rw-r--r--template/en/default/pages/linked.html.tmpl42
-rw-r--r--template/en/default/pages/linkify.html.tmpl28
-rw-r--r--template/en/default/pages/quicksearch.html.tmpl325
-rw-r--r--template/en/default/pages/release-notes.html.tmpl2349
-rw-r--r--template/en/default/pages/release-notes3.html.tmpl3474
-rw-r--r--template/en/default/pages/sudo.html.tmpl55
-rw-r--r--template/en/default/reports/chart.csv.tmpl32
-rw-r--r--template/en/default/reports/chart.html.tmpl55
-rw-r--r--template/en/default/reports/chart.png.tmpl47
-rw-r--r--template/en/default/reports/components.html.tmpl94
-rw-r--r--template/en/default/reports/create-chart.html.tmpl258
-rw-r--r--template/en/default/reports/delete-series.html.tmpl47
-rw-r--r--template/en/default/reports/duplicates-simple.html.tmpl35
-rw-r--r--template/en/default/reports/duplicates-table.html.tmpl109
-rw-r--r--template/en/default/reports/duplicates.html.tmpl165
-rw-r--r--template/en/default/reports/edit-series.html.tmpl63
-rw-r--r--template/en/default/reports/keywords.html.tmpl71
-rw-r--r--template/en/default/reports/menu.html.tmpl75
-rw-r--r--template/en/default/reports/old-charts.html.tmpl62
-rw-r--r--template/en/default/reports/report-bar.png.tmpl48
-rw-r--r--template/en/default/reports/report-line.png.tmpl50
-rw-r--r--template/en/default/reports/report-pie.png.tmpl25
-rw-r--r--template/en/default/reports/report-simple.html.tmpl25
-rw-r--r--template/en/default/reports/report-table.csv.tmpl61
-rw-r--r--template/en/default/reports/report-table.html.tmpl256
-rw-r--r--template/en/default/reports/report.csv.tmpl12
-rw-r--r--template/en/default/reports/report.html.tmpl152
-rw-r--r--template/en/default/reports/series-common.html.tmpl107
-rw-r--r--template/en/default/reports/series.html.tmpl85
-rw-r--r--template/en/default/request/queue.html.tmpl263
-rw-r--r--template/en/default/search/boolean-charts.html.tmpl185
-rw-r--r--template/en/default/search/field.html.tmpl184
-rw-r--r--template/en/default/search/form.html.tmpl341
-rw-r--r--template/en/default/search/knob.html.tmpl74
-rw-r--r--template/en/default/search/search-advanced.html.tmpl55
-rw-r--r--template/en/default/search/search-create-series.html.tmpl57
-rw-r--r--template/en/default/search/search-plugin.xml.tmpl19
-rw-r--r--template/en/default/search/search-report-graph.html.tmpl128
-rw-r--r--template/en/default/search/search-report-select.html.tmpl29
-rw-r--r--template/en/default/search/search-report-table.html.tmpl81
-rw-r--r--template/en/default/search/search-specific.html.tmpl122
-rw-r--r--template/en/default/search/tabs.html.tmpl23
-rw-r--r--template/en/default/search/type-select.html.tmpl18
-rw-r--r--template/en/default/setup/strings.txt.pl417
-rw-r--r--template/en/default/welcome-admin.html.tmpl77
-rw-r--r--template/en/default/whine/mail.html.tmpl80
-rw-r--r--template/en/default/whine/mail.txt.tmpl61
-rw-r--r--template/en/default/whine/multipart-mime.txt.tmpl39
-rw-r--r--template/en/default/whine/schedule.html.tmpl432
278 files changed, 37350 insertions, 0 deletions
diff --git a/template/en/default/account/auth/login-small.html.tmpl b/template/en/default/account/auth/login-small.html.tmpl
new file mode 100644
index 0000000..818aa6b
--- /dev/null
+++ b/template/en/default/account/auth/login-small.html.tmpl
@@ -0,0 +1,115 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# Use the current script name. If an empty name is returned,
+ # then we are accessing the home page. %]
+
+[% login_target = cgi.url("-relative" => 1, "-query" => 1) %]
+[% IF !login_target OR login_target.match("^token.cgi") %]
+ [% login_target = "index.cgi" %]
+[% END %]
+
+<li id="mini_login_container[% qs_suffix %]">
+ <span class="separator">| </span>
+ [% connector = "?" %]
+ [% IF cgi.request_method == "GET" AND cgi.query_string %]
+ [% connector = "&" %]
+ [% END %]
+ [% script_url = login_target _ connector _ "GoAheadAndLogIn=1" %]
+ <a id="login_link[% qs_suffix %]" href="[% script_url FILTER html %]"
+ onclick="return show_mini_login_form('[% qs_suffix %]')">Log In</a>
+
+ [% Hook.process('additional_methods') %]
+
+ <form action="[% login_target FILTER html %]" method="POST"
+ class="mini_login bz_default_hidden"
+ id="mini_login[% qs_suffix FILTER html %]"
+ onsubmit="return check_mini_login_fields( '[% qs_suffix FILTER html %]' );"
+ >
+ <input id="Bugzilla_login[% qs_suffix FILTER html %]"
+ class="bz_login"
+ name="Bugzilla_login"
+ title="Login"
+ onfocus="mini_login_on_focus('[% qs_suffix FILTER js %]')"
+ >
+ <input class="bz_password"
+ id="Bugzilla_password[% qs_suffix FILTER html %]"
+ name="Bugzilla_password"
+ type="password"
+ title="Password"
+ >
+ <input class="bz_password bz_default_hidden bz_mini_login_help" type="text"
+ id="Bugzilla_password_dummy[% qs_suffix %]" value="password"
+ title="Password"
+ onfocus="mini_login_on_focus('[% qs_suffix FILTER js %]')"
+ >
+ [% IF Param('rememberlogin') == 'defaulton' ||
+ Param('rememberlogin') == 'defaultoff'
+ %]
+ <input type="checkbox" id="Bugzilla_remember[% qs_suffix %]"
+ name="Bugzilla_remember" value="on" class="bz_remember"
+ [%+ "checked" IF Param('rememberlogin') == "defaulton" %]>
+ <label for="Bugzilla_remember[% qs_suffix %]">Remember</label>
+ [% END %]
+ <input type="hidden" name="Bugzilla_login_token"
+ value="[% get_login_request_token() FILTER html %]">
+ <input type="submit" name="GoAheadAndLogIn" value="Log in"
+ id="log_in[% qs_suffix %]">
+ <script type="text/javascript">
+ mini_login_constants = {
+ "login" : "login",
+ "warning" : "You must set the login and password before logging in."
+ };
+ [%# We need this event to fire after autocomplete, because it does
+ # something different depending on whether or not there's already
+ # data in the login and password box.
+ # However, autocomplete happens at all sorts of different times in
+ # different browsers (before or after onDOMReady, before or after
+ # window.onload, in almost all combinations you can imagine).
+ # The only good solution I found is to time the event 200
+ # milliseconds after window.onload for WebKit (doing it immediately
+ # at onload works in Chrome but not in Safari, but I can't detect
+ # them separately using YUI), and right after onDOMReady in Gecko.
+ # The WebKit solution is also fairly guaranteed to work on any
+ # browser (it's just strange, since the fields only populate 200 ms
+ # after the page loads), so it's the default. IE doesn't even
+ # recognize our forms as login forms, so I made it use the Gecko
+ # method also (since it's nicer visually). Opera never autocompletes
+ # forms without user interaction, so it also uses the Gecko method.
+ #%]
+ if (YAHOO.env.ua.gecko || YAHOO.env.ua.ie || YAHOO.env.ua.opera) {
+ YAHOO.util.Event.onDOMReady(function() {
+ init_mini_login_form('[% qs_suffix FILTER html %]');
+ });
+ }
+ else {
+ YAHOO.util.Event.on(window, 'load', function () {
+ window.setTimeout(function() {
+ init_mini_login_form('[% qs_suffix FILTER html %]');
+ }, 200);
+ });
+ }
+ </script>
+ <a href="#" onclick="return hide_mini_login_form('[% qs_suffix %]')">[x]</a>
+ </form>
+</li>
+<li id="forgot_container[% qs_suffix %]">
+ <span class="separator">| </span>
+ <a id="forgot_link[% qs_suffix %]" href="[% script_url FILTER html %]#forgot"
+ onclick="return show_forgot_form('[% qs_suffix %]')">Forgot Password</a>
+ <form action="token.cgi" method="post" id="forgot_form[% qs_suffix %]"
+ class="mini_forgot bz_default_hidden">
+ <label for="login[% qs_suffix FILTER html %]">Login:</label>
+ <input type="text" name="loginname" size="20" id="login[% qs_suffix FILTER html %]">
+ <input id="forgot_button[% qs_suffix %]" value="Reset Password"
+ type="submit">
+ <input type="hidden" name="a" value="reqpw">
+ <input type="hidden" id="token[% qs_suffix FILTER html %]" name="token" value="[% issue_hash_token(['reqpw']) FILTER html %]">
+ <a href="#" onclick="return hide_forgot_form('[% qs_suffix %]')">[x]</a>
+ </form>
+</li>
diff --git a/template/en/default/account/auth/login.html.tmpl b/template/en/default/account/auth/login.html.tmpl
new file mode 100644
index 0000000..77a1ba2
--- /dev/null
+++ b/template/en/default/account/auth/login.html.tmpl
@@ -0,0 +1,118 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # target: string. URL to go to after login.
+ #%]
+
+[% IF !target %]
+ [% target = "index.cgi" %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = "Log in to $terms.Bugzilla",
+ onload = "document.forms['login'].Bugzilla_login.focus()"
+%]
+
+[% USE Bugzilla %]
+
+<p>
+ [% terms.Bugzilla %] needs a legitimate login and password to continue.
+</p>
+
+<form name="login" action="[% target FILTER html %]" method="POST"
+[%- IF Bugzilla.cgi.param("data") %] enctype="multipart/form-data"[% END %]>
+ <table>
+ <tr>
+ <th align="right"><label for="Bugzilla_login">Login:</label></th>
+ <td>
+ <input size="35" id="Bugzilla_login" name="Bugzilla_login">
+ [% Param('emailsuffix') FILTER html %]
+ </td>
+ </tr>
+ <tr>
+ <th align="right"><label for="Bugzilla_password">Password:</label></th>
+ <td>
+ <input type="password" size="35" id="Bugzilla_password" name="Bugzilla_password">
+ </td>
+ </tr>
+
+ [% IF Param('rememberlogin') == 'defaulton' ||
+ Param('rememberlogin') == 'defaultoff' %]
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ <input type="checkbox" id="Bugzilla_remember" name="Bugzilla_remember" value="on"
+ [%+ "checked" IF Param('rememberlogin') == "defaulton" %]>
+ <label for="Bugzilla_remember">Remember my Login</label>
+ </td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ <input type="checkbox" id="Bugzilla_restrictlogin" name="Bugzilla_restrictlogin"
+ checked="checked">
+ <label for="Bugzilla_restrictlogin">Restrict this session to this IP address
+ (using this option improves security)</label>
+ </td>
+ </tr>
+ </table>
+
+ [% PROCESS "global/hidden-fields.html.tmpl"
+ exclude="^Bugzilla_(login|password|restrictlogin)$" %]
+
+ <input type="hidden" name="Bugzilla_login_token"
+ value="[% get_login_request_token() FILTER html %]">
+ <input type="submit" name="GoAheadAndLogIn" value="Log in" id="log_in">
+
+ <p>
+ (Note: you should make sure cookies are enabled for this site.
+ Otherwise, you will be required to log in frequently.)
+ </p>
+</form>
+
+[% Hook.process('additional_methods') %]
+
+[%# Allow the user to create a new account, or request a token to change
+ # their password, assuming that our auth method allows that.
+ #%]
+
+ [% IF Param("createemailregexp") && user.authorizer.user_can_create_account %]
+ <hr>
+
+ <p>
+ If you don't have a [% terms.Bugzilla %] account, you can
+ <a href="createaccount.cgi">create a new account</a>.
+ [% IF Param("requirelogin") %]
+ A user account is required because this [% terms.Bugzilla %]
+ installation is only accessible to authenticated users.
+ [% ELSIF target.match("_bug\.cgi$") %]
+ A user account is required to file a new [% terms.bug %] or to comment
+ into existing ones so that you can be contacted if more information is
+ needed.
+ [% END %]
+ </p>
+ [% END %]
+
+ [% IF user.authorizer.can_change_password %]
+ <hr>
+
+ <form id="forgot" method="get" action="token.cgi">
+ <input type="hidden" name="a" value="reqpw">
+ If you have an account, but have forgotten your password,
+ enter your login name below and submit a request
+ to change your password.<br>
+ <input size="35" name="loginname">
+ <input type="hidden" id="token" name="token" value="[% issue_hash_token(['reqpw']) FILTER html %]">
+ <input type="submit" id="request" value="Reset Password">
+ </form>
+ [% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/account/cancel-token.txt.tmpl b/template/en/default/account/cancel-token.txt.tmpl
new file mode 100644
index 0000000..b9a7dd8
--- /dev/null
+++ b/template/en/default/account/cancel-token.txt.tmpl
@@ -0,0 +1,91 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+From: [% Param('mailfrom') %]
+To: [% emailaddress %]
+Subject: [% PROCESS subject %]
+X-Bugzilla-Type: admin
+
+A request was canceled from [% remoteaddress %].
+
+If you did not request this, it could be either an honest
+mistake or someone attempting to break into your [% terms.Bugzilla %] account.
+
+Take a look at the information below and forward this email
+to [% Param('maintainer') %] if you suspect foul play.
+
+ Token: [% token %]
+ Token Type: [% tokentype %]
+ User: [% emailaddress %]
+ Issue Date: [% issuedate FILTER time("%Y-%m-%d %H:%M:%S %Z", timezone) %]
+ Event Data: [% eventdata %]
+Canceled Because: [% PROCESS cancelactionmessage %]
+
+[% BLOCK subject %]
+ [% IF tokentype == 'new_account' %]
+ User account creation request canceled
+ [% ELSIF tokentype == 'password' %]
+ Password change request canceled
+ [% ELSIF tokentype == 'emailnew' OR tokentype == 'emailold' %]
+ Email change request canceled
+ [% ELSE %]
+ [% tokentype %] token canceled
+ [% END %]
+[% END %]
+
+[% BLOCK cancelactionmessage %]
+ [% IF cancelaction == 'account_exists' %]
+ Account [% email %] already exists.
+
+ [% ELSIF cancelaction == 'email_change_canceled' %]
+ The request to change the email address for
+ the [% old_email %] account to [% new_email %] has
+ been canceled.
+
+ [% ELSIF cancelaction == 'email_change_canceled_reinstated' %]
+ The request to change the email address for your account
+ to [% new_email %] has been canceled. Your old account
+ settings have been reinstated.
+
+ [% ELSIF cancelaction == 'emailold_change_canceled' %]
+ The request to change the email address for your account
+ to [% new_email %] has been canceled.
+
+ [% ELSIF cancelaction == 'password_change_canceled' %]
+ You have requested cancellation.
+
+ [% ELSIF cancelaction == 'account_creation_canceled' %]
+ The creation of the user account [% emailaddress %]
+ has been canceled.
+
+ [% ELSIF cancelaction == 'user_logged_in' %]
+ You have logged in.
+
+ [% ELSIF cancelaction == 'wrong_token_for_changing_passwd' %]
+ You have tried to use the token to change the password.
+
+ [% ELSIF cancelaction == 'wrong_token_for_cancelling_email_change' %]
+ You have tried to use the token to cancel the email address change.
+
+ [% ELSIF cancelaction == 'wrong_token_for_confirming_email_change' %]
+ You have tried to use the token to confirm the email address change.
+
+ [% ELSIF cancelaction == 'wrong_token_for_creating_account' %]
+ You have tried to use the token to create a user account.
+
+ [% ELSE %]
+ [%# Give sensible error if the cancel-token function is used incorrectly.
+ #%]
+ You are using [% terms.Bugzilla %]'s cancel-token function incorrectly. You
+ passed in the string '[% cancelaction %]'. The correct use is to pass
+ in a tag, and define that tag in the file <kbd>cancel-token.txt.tmpl</kbd>.
+
+ If you are a [% terms.Bugzilla %] end-user seeing this message, please forward this
+ email to [% Param('maintainer') %].
+ [% END %]
+[% END %]
diff --git a/template/en/default/account/create.html.tmpl b/template/en/default/account/create.html.tmpl
new file mode 100644
index 0000000..bf2cf31
--- /dev/null
+++ b/template/en/default/account/create.html.tmpl
@@ -0,0 +1,75 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE
+ # none
+ #
+ # Param("maintainer") is used to display the maintainer's email.
+ # Param("emailsuffix") is used to pre-fill the email field.
+ #%]
+
+[% title = BLOCK %]
+ Create a new [% terms.Bugzilla %] account
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ onload = "document.forms['account_creation_form'].login.focus();" %]
+
+<p>
+ To create a [% terms.Bugzilla %] account, all you need to do is to enter
+[% IF Param('emailsuffix') == '' %]
+ a legitimate email address.
+[% ELSE %]
+ an account name which when combined with [% Param('emailsuffix') %]
+ corresponds to an address where you receive email.
+[% END %]
+ You will receive an email at this address to confirm the creation of your
+ account. <b>You will not be able to log in until you receive the email.</b>
+ If it doesn't arrive within a reasonable amount of time, you may contact
+ the maintainer of this [% terms.Bugzilla %] installation
+ at <a href="mailto:[% Param("maintainer") %]">[% Param("maintainer") %]</a>.
+</p>
+
+<p>
+ A user account is required to report new [% terms.bugs %] or to comment into
+ existing ones, as you may be contacted for more information if needed.
+ This also lets other users clearly identify who is the author of comments
+ or changes made into [% terms.bugs %]. <b>Note that your email address will
+ <u>never</u> be displayed to logged out users. Only registered users will be
+ able to see it.</b>
+</p>
+
+[% IF Param('createemailregexp') == '.*' && Param('emailsuffix') == '' %]
+<p>
+ <b>PRIVACY NOTICE:</b> [% terms.Bugzilla %] is an open [% terms.bug %]
+ tracking system. Activity on most [% terms.bugs %], including email
+ addresses, will be visible to registered users. We <b>recommend</b> using a
+ secondary account or free web email service (such as Gmail, Yahoo,
+ Hotmail, or similar) to avoid receiving spam at your primary email address.
+</p>
+[% END %]
+
+<form id="account_creation_form" method="get" action="createaccount.cgi">
+ <table>
+ <tr>
+ <td align="right">
+ <b>Email address:</b>
+ </td>
+ <td>
+ <input size="35" id="login" name="login">
+ [% Param('emailsuffix') FILTER html %]
+ </td>
+ </tr>
+ </table>
+ <br>
+ <input type="hidden" id="token" name="token" value="[% issue_hash_token(['create_account']) FILTER html %]">
+ <input type="submit" id="send" value="Send">
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/account/created.html.tmpl b/template/en/default/account/created.html.tmpl
new file mode 100644
index 0000000..f35deca
--- /dev/null
+++ b/template/en/default/account/created.html.tmpl
@@ -0,0 +1,25 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # login: string. The user's Bugzilla login email address.
+ #%]
+
+[% title = BLOCK %]
+ Request for new user account '[% login FILTER html %]' submitted
+[% END %]
+
+[% PROCESS global/header.html.tmpl title = title %]
+
+<p>
+ A confirmation email has been sent containing a link to continue
+ creating an account. The link will expire if an account is not
+ created within [% constants.MAX_TOKEN_AGE FILTER html %] days.
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/account/email/change-new.txt.tmpl b/template/en/default/account/email/change-new.txt.tmpl
new file mode 100644
index 0000000..a6c54a7
--- /dev/null
+++ b/template/en/default/account/email/change-new.txt.tmpl
@@ -0,0 +1,27 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+From: [% Param('mailfrom') %]
+To: [% emailaddress %]
+Subject: [% terms.Bugzilla %] Change Email Address Request
+X-Bugzilla-Type: admin
+
+[%+ terms.Bugzilla %] has received a request to change the email address
+for the account [% oldemailaddress %] to your address.
+
+To confirm the change, visit the following link:
+
+[%+ urlbase %]token.cgi?t=[% token FILTER uri %]&a=cfmem
+
+If you are not the person who made this request, or you wish to cancel
+this request, visit the following link:
+
+[%+ urlbase %]token.cgi?t=[% token FILTER uri %]&a=cxlem
+
+If you do nothing, the request will lapse after [% constants.MAX_TOKEN_AGE %] days
+(on [% expiration_ts FILTER time("%B %e, %Y at %H:%M %Z") %]).
diff --git a/template/en/default/account/email/change-old.txt.tmpl b/template/en/default/account/email/change-old.txt.tmpl
new file mode 100644
index 0000000..24b90a2
--- /dev/null
+++ b/template/en/default/account/email/change-old.txt.tmpl
@@ -0,0 +1,27 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+From: [% Param('mailfrom') %]
+To: [% emailaddress %]
+Subject: [% terms.Bugzilla %] Change Email Address Request
+Importance: High
+X-MSMail-Priority: High
+X-Priority: 1
+X-Bugzilla-Type: admin
+
+[%+ terms.Bugzilla %] has received a request to change the email address
+for your account to [%+ newemailaddress %].
+
+If you are not the person who made this request, or you wish to cancel
+this request, visit the following link:
+
+[%+ urlbase %]token.cgi?t=[% token FILTER uri %]&a=cxlem
+
+If you do nothing, and [%+ newemailaddress %] confirms this request,
+the change will be made permanent after [% constants.MAX_TOKEN_AGE %] days
+(on [% expiration_ts FILTER time("%B %e, %Y at %H:%M %Z") %]).
diff --git a/template/en/default/account/email/confirm-new.html.tmpl b/template/en/default/account/email/confirm-new.html.tmpl
new file mode 100644
index 0000000..0fb9b7e
--- /dev/null
+++ b/template/en/default/account/email/confirm-new.html.tmpl
@@ -0,0 +1,72 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # token: string. The token to be used in the user account creation.
+ # email: email address of the user account.
+ # expiration_ts: expiration date of the token.
+ #%]
+
+[% title = BLOCK %]Create a new user account for '[% email FILTER html %]'[% END %]
+[% PROCESS "global/header.html.tmpl"
+ title = title
+ onload = "document.forms['confirm_account_form'].realname.focus();" %]
+
+<p>
+ To create your account, you must enter a password in the form below.
+ Your email address and Real Name (if provided) will be shown with
+ changes you make.
+</p>
+
+<form id="confirm_account_form" method="post" action="token.cgi">
+ <input type="hidden" name="t" value="[% token FILTER html %]">
+ <input type="hidden" name="a" value="confirm_new_account">
+ <table>
+ <tr>
+ <th align="right">Email Address:</th>
+ <td>[% email FILTER html %]</td>
+ </tr>
+ <tr>
+ <th align="right"><small><i>(OPTIONAL)</i></small> <label for="realname">Real Name</label>:</th>
+ <td><input type="text" id="realname" name="realname" value=""></td>
+ </tr>
+ <tr>
+ <th align="right"><label for="passwd1">Type your password</label>:</th>
+ <td>
+ <input type="password" id="passwd1" name="passwd1" value="">
+ (minimum [% constants.USER_PASSWORD_MIN_LENGTH FILTER none %] characters)
+ </td>
+ </tr>
+ <tr>
+ <th align="right"><label for="passwd2">Confirm your password</label>:</th>
+ <td><input type="password" id="passwd2" name="passwd2" value=""></td>
+ </tr>
+ <tr>
+ <th align="right">&nbsp;</th>
+ <td><input type="submit" id="confirm" value="Create"></td>
+ </tr>
+ </table>
+</form>
+
+<p>
+ This account will not be created if this form is not completed by
+ <u>[% expiration_ts FILTER time("%B %e, %Y at %H:%M %Z") %]</u>.
+</p>
+
+<p>
+ If you do not wish to create an account with this email click the
+ cancel account button below and your details will be forgotten.
+</p>
+
+<form id="cancel_account_form" method="post" action="token.cgi">
+ <input type="hidden" name="t" value="[% token FILTER html %]">
+ <input type="hidden" name="a" value="cancel_new_account">
+ <input type="submit" id="confirm" value="Cancel Account">
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/account/email/confirm.html.tmpl b/template/en/default/account/email/confirm.html.tmpl
new file mode 100644
index 0000000..5b54778
--- /dev/null
+++ b/template/en/default/account/email/confirm.html.tmpl
@@ -0,0 +1,35 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # token: string. The token to be used in this address change.
+ #%]
+
+[% title = "Confirm Change Email" %]
+[% PROCESS global/header.html.tmpl %]
+
+<p>
+ To change your email address, please enter your current password:
+</p>
+
+<form method="post" action="token.cgi">
+ <input type="hidden" name="t" value="[% token FILTER html %]">
+ <input type="hidden" name="a" value="chgem">
+ <table>
+ <tr>
+ <th align="right">Password:</th>
+ <td><input type="password" name="password" size="36"></td>
+ </tr>
+ <tr>
+ <th align="right">&nbsp;</th>
+ <td><input type="submit" id="confirm" value="Submit"></td>
+ </tr>
+ </table>
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/account/email/request-new.txt.tmpl b/template/en/default/account/email/request-new.txt.tmpl
new file mode 100644
index 0000000..8ca0ff1
--- /dev/null
+++ b/template/en/default/account/email/request-new.txt.tmpl
@@ -0,0 +1,47 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # token: random string used to authenticate the transaction.
+ # expiration_ts: expiration date of the token.
+ # email: email address of the new account.
+ #%]
+
+From: [% Param('mailfrom') %]
+To: [% email %]
+Subject: [% terms.Bugzilla %]: confirm account creation
+X-Bugzilla-Type: admin
+
+[%+ terms.Bugzilla %] has received a request to create a user account
+using your email address ([% email %]).
+
+To continue creating an account using this email address, visit the
+following link by [% expiration_ts FILTER time("%B %e, %Y at %H:%M %Z") %]:
+
+[%+ urlbase %]token.cgi?t=[% token FILTER uri %]&a=request_new_account
+
+If you did not receive this email before [% expiration_ts FILTER time("%B %e, %Y at %H:%M %Z") %] or
+you wish to create an account using a different email address you can begin
+again by going to:
+
+[%+ urlbase %]createaccount.cgi
+
+[% IF Param('createemailregexp') == '.*' && Param('emailsuffix') == '' %]
+PRIVACY NOTICE: [% terms.Bugzilla %] is an open [% terms.bug %] tracking system. Activity on most
+[%+ terms.bugs %], including email addresses, will be visible to the public. We recommend
+using a secondary account or free web email service (such as Gmail, Yahoo,
+Hotmail, or similar) to avoid receiving spam at your primary email address.
+[% END %]
+
+If you do not wish to create an account, or if this request was made in
+error you can do nothing or visit the following link:
+
+[%+ urlbase %]token.cgi?t=[% token FILTER uri %]&a=cancel_new_account
+
+If the above links do not work, or you have any other issues regarding
+your account, please contact administration at [% Param('maintainer') %].
diff --git a/template/en/default/account/password/forgotten-password.txt.tmpl b/template/en/default/account/password/forgotten-password.txt.tmpl
new file mode 100644
index 0000000..0c135a9
--- /dev/null
+++ b/template/en/default/account/password/forgotten-password.txt.tmpl
@@ -0,0 +1,26 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+From: [% Param('mailfrom') %]
+To: [% emailaddress %]
+Subject: [% terms.Bugzilla %] Change Password Request
+X-Bugzilla-Type: admin
+
+You have (or someone impersonating you has) requested to change your
+[%+ terms.Bugzilla %] password. To complete the change, visit the following link:
+
+[%+ urlbase %]token.cgi?t=[% token FILTER uri %]&a=cfmpw
+
+If you are not the person who made this request, or you wish to cancel
+this request, visit the following link:
+
+[%+ urlbase %]token.cgi?t=[% token FILTER uri %]&a=cxlpw
+
+If you do nothing, the request will lapse after [% constants.MAX_TOKEN_AGE %] days
+(on [% expiration_ts FILTER time("%B %e, %Y at %H:%M %Z", timezone) %]) or when you
+log in successfully.
diff --git a/template/en/default/account/password/set-forgotten-password.html.tmpl b/template/en/default/account/password/set-forgotten-password.html.tmpl
new file mode 100644
index 0000000..95e4d3f
--- /dev/null
+++ b/template/en/default/account/password/set-forgotten-password.html.tmpl
@@ -0,0 +1,53 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% title = "Change Password" %]
+[% PROCESS global/header.html.tmpl %]
+[% password_complexity = Param('password_complexity') %]
+<p>
+ To change your password, enter a new password twice:<br>
+</p>
+<ul>
+ <li>Password must be at least [% constants.USER_PASSWORD_MIN_LENGTH FILTER none %] characters long.</li>
+ [% IF password_complexity == "mixed_letters" %]
+ <li>Password must contain at least one UPPER and one lowercase letter.</li>
+ [% ELSIF password_complexity == "letters_numbers" %]
+ <li>Password must contain at least one UPPER and one lower case letter and a number.</li>
+ [% ELSIF password_complexity == "letters_numbers_specialchars" %]
+ <li>Password must contain at least one letter, a number and a special character.</li>
+ [% END %]
+</ul>
+
+<form method="post" action="token.cgi">
+ <input type="hidden" name="t" value="[% token FILTER html %]">
+ <input type="hidden" name="a" value="chgpw">
+ <table>
+ <tr>
+ <th align="right">New Password:</th>
+ <td>
+ <input type="password" name="password">
+ </td>
+ </tr>
+
+ <tr>
+ <th align="right">New Password Again:</th>
+ <td>
+ <input type="password" name="matchpassword">
+ </td>
+ </tr>
+
+ <tr>
+ <th align="right">&nbsp;</th>
+ <td>
+ <input type="submit" id="update" value="Submit">
+ </td>
+ </tr>
+ </table>
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/account/prefs/account.html.tmpl b/template/en/default/account/prefs/account.html.tmpl
new file mode 100644
index 0000000..59e4ab7
--- /dev/null
+++ b/template/en/default/account/prefs/account.html.tmpl
@@ -0,0 +1,91 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # realname: string. The user's real name, if any.
+ # login_change_date: string. The date the email change will be complete. (optional)
+ # new_login_name: string. The user's new Bugzilla login whilst not confirmed. (optional)
+ #%]
+
+<table>
+ [% IF user.authorizer.can_change_password
+ || (user.authorizer.can_change_email && Param('allowemailchange')) %]
+ <tr>
+ <td colspan="3">
+ Please enter your existing password to confirm account changes.
+ </td>
+ </tr>
+ <tr>
+ <th align="right">Password:</th>
+ <td>
+ <input type="hidden" name="old_login" value="[% user.login FILTER html %]">
+ <input type="password" name="old_password">
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2"><hr></td>
+ </tr>
+ [% END %]
+
+ [% IF user.authorizer.can_change_password %]
+ <tr>
+ <th align="right">New password:</th>
+ <td>
+ <input type="password" name="new_password1">
+ </td>
+ </tr>
+
+ <tr>
+ <th align="right">Confirm new password:</th>
+ <td>
+ <input type="password" name="new_password2">
+ </td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <th align="right">Your real name (optional, but encouraged):</th>
+ <td>
+ <input size="35" name="realname" value="[% realname FILTER html %]">
+ </td>
+ </tr>
+
+ [% IF user.authorizer.can_change_email && Param('allowemailchange') %]
+ [% IF login_change_date %]
+ [% IF new_login_name %]
+ <tr>
+ <th align="right">Pending email address:</th>
+ <td>[% new_login_name FILTER html %]</td>
+ </tr>
+ <tr>
+ <th align="right">Change request expires:</th>
+ <td>[% login_change_date FILTER time %]</td>
+ </tr>
+ [% ELSE %]
+ <tr>
+ <th align="right">Confirmed email address:</th>
+ <td>[% user.login FILTER html %]</td>
+ </tr>
+ <tr>
+ <th align="right">Completion date:</th>
+ <td>[% login_change_date FILTER time %]</td>
+ </tr>
+ [% END %]
+ [% ELSE %]
+ <tr>
+ <th align="right">New email address:</th>
+ <td>
+ <input size="35" name="new_login_name">
+ </td>
+ </tr>
+ [% END %]
+ [% END %]
+
+ [% Hook.process('field') %]
+
+</table>
diff --git a/template/en/default/account/prefs/email.html.tmpl b/template/en/default/account/prefs/email.html.tmpl
new file mode 100644
index 0000000..57fa60f
--- /dev/null
+++ b/template/en/default/account/prefs/email.html.tmpl
@@ -0,0 +1,292 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # watchedusers: string.
+ # Comma-separated list of email addresses this user watches.
+ # watchers: array.
+ # Array of users watching this user's account.
+ # excludeself: boolean.
+ # True if user is not receiving self-generated mail.
+ # <rolename>: Multiple hashes, one for each rolename (e.g. assignee; see
+ # below), keyed by reasonname (e.g. comments; again, see
+ # below). The value is a boolean - true if the user is
+ # receiving mail for that reason when in that role.
+ #%]
+
+[%# If the user's bugmail has been disabled by admins, show a warning. %]
+[% IF user.email_disabled %]
+ <div class="warningmessages">
+ Your [% terms.bug %]mail has been disabled by the [% terms.Bugzilla %]
+ administrator. Please contact [% Param('maintainer') %] to enable
+ [%+ terms.bug %]mails.
+ </div>
+[% END %]
+
+[% IF user.authorizer.can_change_email && Param('allowemailchange') %]
+ <p>
+ If you want to change your e-mail address
+ <b>[% user.email FILTER html %]</b> to which [% terms.Bugzilla %] sends
+ notifications, click the "Account Information" tab above.
+ </p>
+[% END %]
+
+<p>
+ If you don't like getting a notification for "trivial"
+ changes to [% terms.bugs %], you can use the settings below to
+ filter some or all notifications.
+</p>
+
+<script type="text/javascript">
+<!--
+function SetCheckboxes(setting) {
+ for (var count = 0; count < document.userprefsform.elements.length; count++) {
+ var theinput = document.userprefsform.elements[count];
+ if (theinput.type == "checkbox" && !theinput.disabled) {
+ if (theinput.name.match("neg")) {
+ theinput.checked = !setting;
+ }
+ else {
+ theinput.checked = setting;
+ }
+ }
+ }
+}
+
+document.write('<input type="button" value="Enable All Mail" onclick="SetCheckboxes(true); return false;">\n');
+document.write('<input type="button" value="Disable All Mail" onclick="SetCheckboxes(false); return false;">\n');
+// -->
+</script>
+
+<hr>
+
+<table>
+ <tr>
+ <td colspan="2">
+ <b>Global options:</b>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="150"></td>
+ <td>
+ [% prefname = "email-$constants.REL_ANY-$constants.EVT_FLAG_REQUESTED" %]
+ <input type="checkbox" name="[% prefname %]" id="[% prefname %]"
+ value="1"
+ [% " checked"
+ IF user.mail_settings.${constants.REL_ANY}.${constants.EVT_FLAG_REQUESTED} %]>
+ <label for="[% prefname %]">Email me when someone asks me to set a flag</label>
+ <br>
+ </td>
+ </tr>
+ <tr>
+ <td width="150"></td>
+ <td>
+ [% prefname = "email-$constants.REL_ANY-$constants.EVT_REQUESTED_FLAG" %]
+ <input type="checkbox" name="[% prefname %]" id="[% prefname %]"
+ value="1"
+ [% " checked"
+ IF user.mail_settings.${constants.REL_ANY}.${constants.EVT_REQUESTED_FLAG} %]>
+ <label for="[% prefname %]">Email me when someone sets a flag I asked for</label>
+ <br>
+ </td>
+ </tr>
+[% IF user.is_global_watcher %]
+ <tr>
+ <td width="150"></td>
+ <td>
+ You are watching all [% terms.bugs %]. To be removed from this role,
+ contact
+ <a href="mailto:[% Param("maintainer") %]">[% Param("maintainer") %]</a>.
+ </td>
+ </tr>
+[% END %]
+</table>
+
+<hr>
+<b>Field/recipient specific options:</b>
+<br>
+<br>
+
+[% events = [
+ { id = constants.EVT_ADDED_REMOVED,
+ description = "I'm added to or removed from this capacity" },
+ { id = constants.EVT_BUG_CREATED,
+ description = "A new $terms.bug is created" },
+ { id = constants.EVT_OPENED_CLOSED,
+ description = "The $terms.bug is resolved or reopened" },
+ { id = constants.EVT_COMPONENT,
+ description = "The product or component changes" },
+ { id = constants.EVT_PROJ_MANAGEMENT,
+ description = "The priority, status, severity, or milestone changes" },
+ { id = constants.EVT_COMMENT,
+ description = "New comments are added" },
+ { id = constants.EVT_ATTACHMENT,
+ description = "New attachments are added" },
+ { id = constants.EVT_ATTACHMENT_DATA,
+ description = "Some attachment data changes" },
+ { id = constants.EVT_KEYWORD,
+ description = "The keywords field changes" },
+ { id = constants.EVT_CC,
+ description = "The CC field changes" },
+ { id = constants.EVT_DEPEND_BLOCK,
+ description = "The dependency tree changes" },
+ { id = constants.EVT_OTHER,
+ description = "Any field not mentioned above changes" },
+] %]
+
+[% neg_events = [
+ { id = constants.EVT_UNCONFIRMED,
+ description = "The $terms.bug is in the UNCONFIRMED state" },
+ { id = constants.EVT_CHANGED_BY_ME,
+ description = "The change was made by me" },
+] %]
+
+[% relationships = [
+ { id = constants.REL_ASSIGNEE,
+ description = "Assignee" },
+ { id = constants.REL_REPORTER,
+ description = "Reporter" },
+ { id = constants.REL_CC,
+ description = "CCed" },
+] %]
+
+[% IF Param('useqacontact') %]
+ [% relationships.push({ id = constants.REL_QA,
+ description = "QA Contact" }) %]
+[% END %]
+
+
+[%# This is up here so that the "relationships" hook can modify it. %]
+[% no_added_removed = [constants.REL_REPORTER] %]
+
+[% Hook.process('relationships') %]
+
+[% num_columns = relationships.size %]
+
+<table class="bz_emailprefs" border="1">
+ <tr>
+ <td colspan="[% num_columns FILTER html %]" align="center" width="50%">
+ <b>When my relationship to this [% terms.bug %] is:</b>
+ </td>
+ <td rowspan="2" width="40%">
+ <b>I want to receive mail when:</b>
+ </td>
+ </tr>
+
+ <tr>
+ [% FOREACH relationship = relationships %]
+ <th align="center" width="9%">
+ [% relationship.description FILTER html %]
+ </th>
+ [% END %]
+ </tr>
+
+ [% FOREACH event = events %]
+ [% count = loop.count() %]
+ <tr class="bz_row_[% count % 2 == 1 ? "odd" : "even" %]">
+ [% FOREACH relationship = relationships %]
+ <td align="center">
+ <input type="checkbox"
+ name="email-[% relationship.id %]-[% event.id %]"
+ value="1"
+ [%# The combinations don't always make sense; disable a couple %]
+ [% IF event.id == constants.EVT_ADDED_REMOVED AND
+ no_added_removed.contains(relationship.id)
+ %]
+ disabled
+ [% ELSIF user.mail_settings.${relationship.id}.${event.id} %]
+ checked
+ [% END %]>
+ </td>
+ [% END %]
+ <td>
+ [% event.description FILTER html %]
+ </td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <td colspan="[% num_columns FILTER html %]"
+ align="center" width="50%">
+ &nbsp;
+ </td>
+ <td width="40%">
+ <b>but not when (overrides above):</b>
+ </td>
+ </tr>
+
+ [% FOREACH event = neg_events %]
+ [% count = loop.count() %]
+ <tr class="bz_row_[% count % 2 == 1 ? "odd" : "even" %]">
+ [% FOREACH relationship = relationships %]
+ <td align="center">
+ <input type="checkbox"
+ name="neg-email-[% relationship.id %]-[% event.id %]"
+ value="1"
+ [% " checked" IF NOT user.mail_settings.${relationship.id}.${event.id} %]>
+ </td>
+ [% END %]
+ <td>
+ [% event.description FILTER html %]
+ </td>
+ </tr>
+ [% END %]
+
+</table>
+
+<hr>
+<b>User Watching</b>
+
+<p>
+If you watch a user, it is as if you are standing in their shoes for the
+purposes of getting email. Email is sent or not according to <u>your</u>
+preferences for <u>their</u> relationship to the [% terms.bug %]
+(e.g. Assignee).
+</p>
+
+<p>
+[% IF watchedusers.size %]
+You are watching everyone in the following list:
+ </p>
+ <p>
+ <select id="watched_by_you" name="watched_by_you" multiple="multiple" size="5">
+ [% FOREACH w = watchedusers %]
+ <option value="[% w FILTER html %]">[% w FILTER html %]</option>
+ [% END %]
+ </select> <br />
+ <input type="checkbox" id="remove_watched_users" name="remove_watched_users">
+ <label for="remove_watched_users">Remove selected users from my watch list</label>
+[% ELSE %]
+You are currently not watching any users.
+[% END %]
+</p>
+
+<p id="new_watched_by_you">Add users to my watch list (comma separated list):
+ [% INCLUDE global/userselect.html.tmpl
+ id => "new_watchedusers"
+ name => "new_watchedusers"
+ value => ""
+ size => 60
+ multiple => 5
+ %]
+</p>
+
+<p id="watching_you">Users watching you:<br>
+ [% IF watchers.size %]
+ [% FOREACH watcher = watchers %]
+ [% watcher FILTER html %] <br>
+ [% END %]
+ [% ELSE %]
+ <i>No one</i>
+ [% END %]
+</p>
+
+<hr>
+
+<br>
diff --git a/template/en/default/account/prefs/permissions.html.tmpl b/template/en/default/account/prefs/permissions.html.tmpl
new file mode 100644
index 0000000..450765a
--- /dev/null
+++ b/template/en/default/account/prefs/permissions.html.tmpl
@@ -0,0 +1,79 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # has_bits: array of hashes. May be empty.
+ # name => Names of the permissions the user has.
+ # desc => Descriptions of the permissions the user has.
+ # set_bits: array of hashes. May be empty.
+ # name => Names of the permissions the user can set for
+ # other people.
+ # desc => Descriptions of the permissions the user can set for
+ # other people.
+ #%]
+
+<table align="center">
+ <tr>
+ <td>
+ [% IF has_bits.size %]
+ You have the following permission bits set on your account:
+ <table align="center">
+ [% FOREACH bit_description = has_bits %]
+ <tr>
+ <td>[% bit_description.name FILTER html %]</td>
+ <td>[% bit_description.desc FILTER html_light %]</td>
+ </tr>
+ [% END %]
+ </table>
+
+ [% FOREACH privs = ["editcomponents", "canconfirm", "editbugs"] %]
+ [% SET products = ${"local_$privs"} %]
+ [% IF products && products.size %]
+ <br>
+ <p>
+ You also have local '[% privs FILTER html %]' privileges
+ for the following products:
+ </p>
+ <p>
+ [% FOREACH product = products %]
+ [% product.name FILTER html %]<br>
+ [% END %]
+ </p>
+ [% END %]
+ [% END %]
+
+ [% ELSE %]
+ There are no permission bits set on your account.
+ [% END %]
+
+ [% IF user.in_group('editusers') %]
+ <br>
+ You have editusers privileges. You can turn on and off
+ all permissions for all users.
+ [% ELSIF set_bits.size %]
+ <br>
+ And you can turn on or off the following bits for
+ <a href="editusers.cgi">other users</a>:
+ <table align="center">
+ [% FOREACH bit_description = set_bits %]
+ <tr>
+ <td>[% bit_description.name FILTER html %]</td>
+ <td>[% bit_description.desc FILTER html_light %]</td>
+ </tr>
+ [% END %]
+ </table>
+ [% END %]
+
+ [% IF user.in_group('bz_sudoers') %]
+ <br>
+ You are a member of the <b>bz_sudoers</b> group, so you can
+ <a href="relogin.cgi?action=prepare-sudo">impersonate someone else</a>.
+ [% END %]
+ </td>
+ </tr>
+</table>
diff --git a/template/en/default/account/prefs/prefs.html.tmpl b/template/en/default/account/prefs/prefs.html.tmpl
new file mode 100644
index 0000000..4416c95
--- /dev/null
+++ b/template/en/default/account/prefs/prefs.html.tmpl
@@ -0,0 +1,102 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # tabs: List of hashes. May not be empty. Each hash has three members:
+ # name: string. Name of the tab (used internally.)
+ # description: string. Description of the tab (used in tab title).
+ # saveable: boolean. True if tab has a form which can be submitted.
+ # True if user is not receiving self-generated mail.
+ # Note: For each tab name, a template "prefs/${tab.name}.tmpl" must exist,
+ # and its interface must be fulfilled.
+ # current_tab: A direct reference to one of the hashes in the tabs list.
+ # This tab will be displayed.
+ # changes_saved: boolean/string. True if the CGI processed form data before
+ # displaying anything, and can contain an optional custom
+ # message if required (which Perl still evaluates as True).
+ # dont_show_button: boolean. Prevent the display of the "Submit Changes" button.
+ #%]
+
+[% filtered_login = user.login FILTER html %]
+[% PROCESS global/header.html.tmpl
+ title = "User Preferences"
+ subheader = filtered_login
+ style_urls = ['skins/standard/admin.css']
+ javascript_urls = ['js/util.js', 'js/field.js']
+ doc_section = "userpreferences.html"
+ yui = ['autocomplete']
+ %]
+
+[% tabs = [{ name => "settings", label => "General Preferences",
+ link => "userprefs.cgi?tab=settings", saveable => "1" },
+ { name => "email", label => "Email Preferences",
+ link => "userprefs.cgi?tab=email", saveable => "1" },
+ { name => "saved-searches", label => "Saved Searches",
+ link => "userprefs.cgi?tab=saved-searches", saveable => "1" },
+ { name => "account", label => "Account Information",
+ link => "userprefs.cgi?tab=account", saveable => "1" },
+ { name => "permissions", label => "Permissions",
+ link => "userprefs.cgi?tab=permissions", saveable => "0" } ] %]
+
+[% Hook.process('tabs') %]
+
+[% FOREACH tab IN tabs %]
+ [% IF tab.name == current_tab_name %]
+ [% current_tab = tab %]
+ [% LAST %]
+ [% END %]
+[% END %]
+
+[% WRAPPER global/tabs.html.tmpl
+ tabs = tabs
+ current_tab = current_tab
+%]
+
+[% IF changes_saved %]
+ <div id="message">
+ The changes to your [% current_tab.label FILTER lower %] have been saved.
+
+ [% IF email_changes_saved %]
+ <p>
+ An email has been sent to both old and new email
+ addresses to confirm the change of email address.
+ </p>
+ [% END %]
+ </div>
+[% END %]
+
+<h3>[% current_tab.label %]</h3>
+
+[% IF current_tab.saveable %]
+ <form name="userprefsform" method="post" action="userprefs.cgi">
+ <input type="hidden" name="tab" value="[% current_tab.name %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+[% END %]
+
+[% PROCESS "account/prefs/${current_tab.name}.html.tmpl"
+ IF current_tab.name.defined %]
+
+[% IF current_tab.saveable %]
+ <input type="hidden" name="dosave" value="1">
+
+ [% UNLESS dont_show_button %]
+ <table>
+ <tr>
+ <td width="150">&nbsp;</td>
+ <td>
+ <input type="submit" id="update" value="Submit Changes">
+ </td>
+ </tr>
+ </table>
+ [% END %]
+ </form>
+[% END %]
+
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/account/prefs/saved-searches.html.tmpl b/template/en/default/account/prefs/saved-searches.html.tmpl
new file mode 100644
index 0000000..11d7ef8
--- /dev/null
+++ b/template/en/default/account/prefs/saved-searches.html.tmpl
@@ -0,0 +1,197 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # queryshare_groups: list of groups the user may share queries with
+ # (id, name).
+ # bless_group_ids: list of group ids the user may bless.
+ #%]
+
+[% IF user.can_bless %]
+ <script type="text/javascript"><!--
+ function update_checkbox(group) {
+ var bless_groups = [[% bless_group_ids.join(",") FILTER js %]];
+ var checkbox = document.getElementById(group.name.replace(/share_(\d+)/, "force_$1"));
+
+ if (bz_isValueInArray(bless_groups, group.value)) {
+ YAHOO.util.Dom.removeClass(checkbox.parentNode, "bz_default_hidden");
+ } else {
+ YAHOO.util.Dom.addClass(checkbox.parentNode, "bz_default_hidden");
+ checkbox.checked = false;
+ }
+ } //-->
+ </script>
+[% END %]
+
+<p>Your saved searches are as follows:</p>
+
+<blockquote>
+ <table border="1" cellpadding="3">
+ <tr>
+ <th>
+ Search
+ </th>
+ <th>
+ Run
+ </th>
+ <th>
+ Edit
+ </th>
+ <th>
+ Forget
+ </th>
+ <th>
+ Show in
+ Footer
+ </th>
+ [% may_share = user.in_group(Param('querysharegroup')) && queryshare_groups.size %]
+ [% IF may_share %]
+ <th>
+ Share With a Group
+ </th>
+ [% END %]
+ </tr>
+ <tr>
+ <td>My [% terms.Bugs %]</td>
+ <td>
+ [% filtered_username = user.login FILTER uri %]
+ <a href="[% Param('mybugstemplate').replace('%userid%', filtered_username) %]">Run</a>
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ &nbsp;
+ </td>
+ <td align="center">
+ <input type="checkbox"
+ name="showmybugslink"
+ value="1"
+ [% " checked" IF user.showmybugslink %]>
+ </td>
+ [% IF may_share %]
+ <td>
+ &mdash;
+ </td>
+ [% END %]
+ </tr>
+ [% FOREACH q = user.queries %]
+ <tr>
+ <td>[% q.name FILTER html %]</td>
+ <td>
+ <a href="buglist.cgi?cmdtype=dorem&amp;remaction=run&amp;namedcmd=[% q.name FILTER uri %]
+ [% IF q.shared_with_group.id %]&amp;sharer_id=[% user.id FILTER uri %][% END %]">Run</a>
+ </td>
+ <td>
+ <a href="query.cgi?[% q.edit_link FILTER html %]&amp;known_name=
+ [% q.name FILTER uri %]">Edit</a>
+ </td>
+ <td>
+ [% IF q.used_in_whine %]
+ Remove from <a href="editwhines.cgi">whining</a> first
+ [% ELSE %]
+ <a href="buglist.cgi?cmdtype=dorem&amp;remaction=forget&amp;namedcmd=
+ [% q.name FILTER uri %]&amp;token=
+ [% issue_hash_token([q.id, q.name]) FILTER uri %]">Forget</a>
+ [% END %]
+ </td>
+ <td align="center">
+ <input type="checkbox"
+ name="link_in_footer_[% q.id FILTER html %]"
+ value="1"
+ alt="[% q.name FILTER html %]"
+ [% " checked" IF q.link_in_footer %]>
+ </td>
+ [% IF may_share %]
+ <td>
+ <select name="share_[% q.id FILTER html %]"
+ [% IF user.can_bless %] onchange="update_checkbox(this);"[% END %]>
+ <option value="">Don't share</option>
+ [% FOREACH group = queryshare_groups %]
+ <option value="[% group.id %]"
+ [% ' selected="selected"'
+ IF q.shared_with_group.id == group.id %]
+ >[% group.name FILTER html %]</option>
+ [% END %]
+ </select>
+ [% IF user.can_bless %]
+ <span [% IF !bless_group_ids.grep("^$q.shared_with_group.id\$").0
+ %]class="bz_default_hidden"[% END %]>
+ <input type="checkbox" id="force_[% q.id FILTER html %]"
+ name="force_[% q.id FILTER html %]" value="1">
+ <label for="force_[% q.id FILTER html %]">Add to footer</label>
+ </span>
+ [% END %]
+ [% IF q.shared_with_users %]
+ (shared with [% q.shared_with_users FILTER html %]
+ [%+ q.shared_with_users > 1 ? "users" : "user" %])
+ [% END %]
+ </td>
+ [% END %]
+ </tr>
+ [% END %]
+ </table>
+[% IF user.can_bless %]
+ <p>Note that for every search that has the "Add to footer" selected, a
+ link to the shared search is added to the footer of every user that is
+ a direct member of the group at the time you click Submit Changes.</p>
+[% END %]
+</blockquote>
+
+[% IF user.queries_available.size %]
+ <p>You may use these searches saved and shared by others:</p>
+
+ <table border="1" cellpadding="3">
+ <tr>
+ <th>
+ Search
+ </th>
+ <th>
+ Shared By
+ </th>
+ <th>
+ Shared To
+ </th>
+ <th>
+ Run
+ </th>
+ <th>
+ Edit
+ </th>
+ <th>
+ Show in
+ Footer
+ </th>
+ </tr>
+ [% FOREACH q = user.queries_available %]
+ <tr>
+ <td>[% q.name FILTER html %]</td>
+ <td>[% q.user.identity FILTER html %]</td>
+ <td>[% q.shared_with_group.name FILTER html %]</td>
+ <td>
+ <a href="buglist.cgi?cmdtype=dorem&amp;remaction=run&amp;namedcmd=
+ [% q.name FILTER uri %]&amp;sharer_id=
+ [% q.user.id FILTER uri %]">Run</a>
+ </td>
+ <td>
+ <a href="query.cgi?[% q.edit_link FILTER html %]&amp;known_name=
+ [% q.name FILTER uri %]">Edit</a>
+ </td>
+ <td align="center">
+ <input type="checkbox"
+ name="link_in_footer_[% q.id FILTER html %]"
+ value="1"
+ alt="[% q.name FILTER html %]"
+ [% " checked" IF q.link_in_footer %]>
+ </td>
+ </tr>
+ [% END %]
+ </table>
+[% ELSE %]
+ <p>No searches are shared with you by other users.</p>
+[% END %]
diff --git a/template/en/default/account/prefs/settings.html.tmpl b/template/en/default/account/prefs/settings.html.tmpl
new file mode 100644
index 0000000..5807958
--- /dev/null
+++ b/template/en/default/account/prefs/settings.html.tmpl
@@ -0,0 +1,68 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # setting_names: an array of strings
+ # settings: a hash of hashes, keyed by setting_name.
+ # Each hash contains:
+ # is_enabled - boolean
+ # default_value - string (global default for this setting)
+ # value - string (user-defined preference)
+ # is_default - boolean (true if user has no preference)
+ # has_settings_enabled : boolean; is true if there is at least one user pref
+ # enabled by the maintainer.
+ #%]
+
+[% PROCESS "global/setting-descs.none.tmpl" %]
+
+[% IF settings.size %]
+ [% UNLESS has_settings_enabled %]
+ <p class="criticalmessages">
+ All user preferences have been disabled by the
+ <a href="mailto:[% Param("maintainer") %]">maintainer</a>
+ of this installation, and so you cannot customize any.
+ </p>
+ [% END %]
+
+ <table border="0" cellpadding="8">
+ [% FOREACH name = setting_names %]
+ [% default_name = name _ '-isdefault' %]
+ [% default_val = settings.${name}.default_value %]
+ <tr>
+ <td align="right">
+ [% setting_descs.$name OR name FILTER html %]
+ </td>
+ <td>
+ [% IF settings.${name}.is_enabled %]
+ <select name="[% name FILTER html %]" id="[% name FILTER html %]">
+ <option value="[% default_name FILTER html %]"
+ [% ' selected="selected"' IF settings.${name}.is_default %]>
+ Site Default ([% setting_descs.${default_val} OR default_val FILTER html %])
+ </option>
+ [% FOREACH x = settings.${name}.legal_values %]
+ <option value="[% x FILTER html %]"
+ [% ' selected="selected"'
+ IF x == settings.${name}.value
+ AND NOT settings.${name}.is_default %]>
+ [% setting_descs.${x} OR x FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ [% ELSE %]
+ <select name="[% name FILTER html %]" id="[% name FILTER html %]" disabled="disabled">
+ <option value="[% default_name FILTER html %]">
+ Site Default ([% setting_descs.${default_val} OR default_val FILTER html %])
+ </option>
+ </select>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+ </table>
+[% END %]
+<br>
diff --git a/template/en/default/account/profile-activity.html.tmpl b/template/en/default/account/profile-activity.html.tmpl
new file mode 100644
index 0000000..3f8030a
--- /dev/null
+++ b/template/en/default/account/profile-activity.html.tmpl
@@ -0,0 +1,73 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # otheruser: Bugzilla User Object; The user whose profile activity
+ # we are viewing.
+ #
+ # listselectionvalues: selection values to recreate the current user list.
+ #
+ # profile_changes: An array of hashes containing the following fields:
+ #
+ # who: string; login name of who made the change
+ # activity_when: string; when the change was made
+ # what: string; the description of the field which was changed
+ # removed: string; the removed value (maybe empty string)
+ # added: string; the added value (maybe empty string)
+ #%]
+
+[% title = BLOCK %]
+ Account History for '[% otheruser.login FILTER html %]'
+[% END %]
+
+
+[% PROCESS global/header.html.tmpl
+ title = title
+%]
+
+[% PROCESS admin/users/listselectvars.html.tmpl
+ listselectionvalues = listselectionvalues
+%]
+
+[% columns =
+ [{name => 'who'
+ heading => 'Who'
+ }
+ {name => 'activity_when'
+ heading => 'When'
+ }
+ {name => 'what'
+ heading => 'What'
+ content_use_field => 1
+ }
+ {name => 'removed'
+ heading => 'Removed'
+ }
+ {name => 'added'
+ heading => 'Added'
+ }
+ ]
+%]
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ data = profile_changes
+%]
+
+<p><a href="editusers.cgi?action=edit&amp;userid=
+ [%- otheruser.id FILTER uri %]"
+ title="Edit user '[% otheruser.login FILTER html %]'">Edit this user</a> or
+ <a title="Search For Users" href="editusers.cgi">search for other accounts</a>
+ [% IF listselectionvalues.matchtype != 'exact' %]
+ or go <a title="Return to the user list"
+ href="editusers.cgi?action=list[% INCLUDE listselectionurlparams %]">back
+ to the user list</a>
+ [% END %]
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/admin.html.tmpl b/template/en/default/admin/admin.html.tmpl
new file mode 100644
index 0000000..38194e9
--- /dev/null
+++ b/template/en/default/admin/admin.html.tmpl
@@ -0,0 +1,127 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% title = BLOCK %]
+ Administer your installation ([% terms.Bugzilla %]
+ [%+ constants.BUGZILLA_VERSION FILTER html %])
+[% END %]
+
+[% PROCESS global/header.html.tmpl title = title
+ style_urls = ['skins/standard/admin.css']
+ doc_section = "administration.html"
+%]
+
+<div>
+ This page is only accessible to empowered users. You can access administrative pages
+ from here (based on your privileges), letting you configure different aspects of
+ this installation. Note: some sections may not be accessible to you and are marked
+ using a lighter color.
+</div>
+
+<table>
+ <tr>
+ <td class="admin_links">
+ <dl>
+ [% class = user.in_group('tweakparams') ? "" : "forbidden" %]
+ <dt id="parameters" class="[% class %]"><a href="editparams.cgi">Parameters</a></dt>
+ <dd class="[% class %]">Set core parameters of the installation. That's the
+ place where you specify the URL to access this installation, determine how
+ users authenticate, choose which [% terms.bug %] fields to display, select
+ the mail transfer agent to send email notifications, choose which group of
+ users can use charts and share queries, and much more.</dd>
+
+ <dt id="preferences" class="[% class %]"><a href="editsettings.cgi">Default Preferences</a></dt>
+ <dd class="[% class %]">Set the default user preferences. These are the values
+ which will be used by default for all users. Users will be able to edit their
+ own preferences from the <a href="userprefs.cgi?tab=settings">Preferences</a>.</dd>
+
+ [% class = user.in_group('editcomponents') ? "" : "forbidden" %]
+ <dt id="sanitycheck" class="[% class %]"><a href="sanitycheck.cgi">Sanity Check</a></dt>
+ <dd class="[% class %]">Run sanity checks to locate problems in your database.
+ This may take several tens of minutes depending on the size of your installation.
+ You can also automate this check by running <tt>sanitycheck.pl</tt> from a cron job.
+ A notification will be sent per email to the specified user if errors are detected.</dd>
+
+ [% class = (user.in_group('editusers') || user.can_bless) ? "" : "forbidden" %]
+ <dt id="users" class="[% class %]"><a href="editusers.cgi">Users</a></dt>
+ <dd class="[% class %]">Create new user accounts or edit existing ones. You can
+ also add and remove users from groups (also known as "user privileges").</dd>
+
+ [% class = (Param('useclassification') && user.in_group('editclassifications')) ? "" : "forbidden" %]
+ <dt id="classifications" class="[% class %]"><a href="editclassifications.cgi">Classifications</a></dt>
+ <dd class="[% class %]">If your installation has to manage many products at once,
+ it's a good idea to group these products into distinct categories. This lets users
+ find information more easily when doing searches or when filing new [% terms.bugs %].</dd>
+
+ [% class = (user.in_group('editcomponents')
+ || user.get_products_by_permission("editcomponents").size) ? "" : "forbidden" %]
+ <dt id="products" class="[% class %]"><a href="editproducts.cgi">Products</a></dt>
+ <dd class="[% class %]">Edit all aspects of products, including group restrictions
+ which let you define who can access [% terms.bugs %] being in these products. You
+ can also edit some specific attributes of products such as
+ <a href="editcomponents.cgi">components</a>, <a href="editversions.cgi">versions</a>
+ and <a href="editmilestones.cgi">milestones</a> directly.</dd>
+
+ [% class = (user.in_group('editcomponents')
+ || user.get_products_by_permission('editcomponents').size) ? "" : "forbidden" %]
+ <dt id="flags" class="[% class %]"><a href="editflagtypes.cgi">Flags</a></dt>
+ <dd class="[% class %]">A flag is a custom 4-states attribute of [% terms.bugs %]
+ and/or attachments. These states are: granted, denied, requested and undefined.
+ You can set as many flags as desired per [% terms.bug %], and define which users
+ are allowed to edit them.</dd>
+
+ [% Hook.process('end_links_left') %]
+ </dl>
+ </td>
+
+ <td class="admin_links">
+ <dl>
+ [% class = user.in_group('admin') ? "" : "forbidden" %]
+ <dt id="custom_fields" class="[% class %]"><a href="editfields.cgi">Custom Fields</a></dt>
+ <dd class="[% class %]">[% terms.Bugzilla %] lets you define fields which are
+ not implemented by default, based on your local and specific requirements.
+ These fields can then be used as any other field, meaning that you can set
+ them in [% terms.bugs %] and run any search involving them.<br>
+ Before creating new fields, keep in mind that too many fields may make the user
+ interface more complex and harder to use. Be sure you have investigated other ways
+ to satisfy your needs before doing this.</dd>
+
+ <dt id="field_values" class="[% class %]"><a href="editvalues.cgi">Field Values</a></dt>
+ <dd class="[% class %]">Define legal values for fields whose values must belong
+ to some given list. This is also the place where you define legal values for some
+ types of custom fields.</dd>
+
+ <dt id="status_workflow" class="[% class %]"><a href="editworkflow.cgi">[%terms.Bug %] Status Workflow</a></dt>
+ <dd class="[% class %]">Customize your workflow and choose initial [% terms.bug %]
+ statuses available on [% terms.bug %] creation and allowed [% terms.bug %] status
+ transitions when editing existing [% terms.bugs %].</dd>
+
+ [% class = user.in_group('creategroups') ? "" : "forbidden" %]
+ <dt id="groups" class="[% class %]"><a href="editgroups.cgi">Groups</a></dt>
+ <dd class="[% class %]">Define groups which will be used in the installation.
+ They can either be used to define new user privileges or to restrict the access
+ to some [% terms.bugs %].</dd>
+
+ [% class = user.in_group('editkeywords') ? "" : "forbidden" %]
+ <dt id="keywords" class="[% class %]"><a href="editkeywords.cgi">Keywords</a></dt>
+ <dd class="[% class %]">Set keywords to be used with [% terms.bugs %]. Keywords
+ are an easy way to "tag" [% terms.bugs %] to let you find them more easily later.</dd>
+
+ [% class = user.in_group('bz_canusewhines') ? "" : "forbidden" %]
+ <dt id="whining" class="[% class %]"><a href="editwhines.cgi">Whining</a></dt>
+ <dd class="[% class %]">Set queries which will be run at some specified date
+ and time, and get the result of these queries directly per email. This is a
+ good way to create reminders and to keep track of the activity in your installation.</dd>
+
+ [% Hook.process('end_links_right') %]
+ </dl>
+ </td>
+ </tr>
+</table>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/classifications/add.html.tmpl b/template/en/default/admin/classifications/add.html.tmpl
new file mode 100644
index 0000000..d818d31
--- /dev/null
+++ b/template/en/default/admin/classifications/add.html.tmpl
@@ -0,0 +1,27 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Add new classification"
+%]
+
+<form method=post action="editclassifications.cgi">
+ <table border=0 cellpadding=4 cellspacing=0>
+
+ [% PROCESS "admin/classifications/edit-common.html.tmpl" %]
+
+ </table>
+ <hr>
+ <input type=submit value="Add">
+ <input type=hidden name="action" value="new">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+</FORM>
+
+[% PROCESS admin/classifications/footer.html.tmpl %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/classifications/del.html.tmpl b/template/en/default/admin/classifications/del.html.tmpl
new file mode 100644
index 0000000..215db84
--- /dev/null
+++ b/template/en/default/admin/classifications/del.html.tmpl
@@ -0,0 +1,51 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Delete classification"
+%]
+
+<table border=1 cellpadding=4 cellspacing=0>
+<tr bgcolor="#6666ff">
+ <th valign="top" align="left">Part</th>
+ <th valign="top" align="left">Value</th>
+
+</tr><tr>
+ <td valign="top">Classification:</td>
+ <td valign="top">[% classification.name FILTER html %]</td>
+
+</tr><tr>
+ <td valign="top">Description:</td>
+ <td valign="top">
+ [% IF classification.description %]
+ [% classification.description FILTER html_light %]
+ [% ELSE %]
+ <font color="red">description missing</font>
+ [% END %]
+ </td>
+
+</tr><tr>
+ <td valign="top">Sortkey:</td>
+ <td valign="top">[% classification.sortkey FILTER html %]</td>
+
+</tr>
+</table>
+
+<h2>Confirmation</h2>
+
+<p>Do you really want to delete this classification?</p>
+<form method=post action="editclassifications.cgi">
+ <input type=submit value="Yes, delete">
+ <input type=hidden name="action" value="delete">
+ <input type=hidden name="classification" value="[% classification.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+</form>
+
+[% PROCESS admin/classifications/footer.html.tmpl %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/classifications/edit-common.html.tmpl b/template/en/default/admin/classifications/edit-common.html.tmpl
new file mode 100644
index 0000000..6f038fc
--- /dev/null
+++ b/template/en/default/admin/classifications/edit-common.html.tmpl
@@ -0,0 +1,35 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # classification: Bugzilla::Classifiation object.
+ #%]
+
+<tr>
+ <th align="right">Classification:</th>
+ <td><input size=64 maxlength=64 name="classification"
+ value="[% classification.name FILTER html %]"></td>
+</tr>
+<tr>
+ <th align="right">Description:</th>
+ <td>
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'description'
+ minrows = 4
+ cols = 64
+ defaultcontent = classification.description
+ %]
+ </td>
+</tr>
+<tr>
+ <th align="right"><label for="sortkey">Sortkey:</label></th>
+ <td><input id="sortkey" size="20" maxlength="20" name="sortkey"
+ value="[%- classification.sortkey FILTER html %]"></td>
+</tr>
+
+[% Hook.process('rows') %]
diff --git a/template/en/default/admin/classifications/edit.html.tmpl b/template/en/default/admin/classifications/edit.html.tmpl
new file mode 100644
index 0000000..429eefc
--- /dev/null
+++ b/template/en/default/admin/classifications/edit.html.tmpl
@@ -0,0 +1,55 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Edit classification"
+%]
+
+<form method=post action="editclassifications.cgi">
+ <table border=0 cellpadding=4 cellspacing=0>
+
+ [% PROCESS "admin/classifications/edit-common.html.tmpl" %]
+
+ <tr valign=top>
+ <th align="right">
+ <a href="editproducts.cgi?classification=[% classification.name FILTER uri %]">
+ Edit Products</a>:
+ </th>
+ <td>
+ [% IF classification.products.size > 0 %]
+ <table>
+ [% FOREACH product = classification.products %]
+ <tr>
+ <th align=right valign=top>[% product.name FILTER html %]</th>
+ <td valign=top>
+ [% IF product.description %]
+ [% product.description FILTER html_light %]
+ [% ELSE %]
+ <font color="red">description missing</font>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+ </table>
+ [% ELSE %]
+ <font color="red">none</font>
+ [% END %]
+ </td>
+ </tr>
+ </table>
+
+ <input type=hidden name="classificationold"
+ value="[% classification.name FILTER html %]">
+ <input type=hidden name="action" value="update">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type=submit value="Update">
+</form>
+
+[% PROCESS admin/classifications/footer.html.tmpl %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/classifications/footer.html.tmpl b/template/en/default/admin/classifications/footer.html.tmpl
new file mode 100644
index 0000000..39adb5c
--- /dev/null
+++ b/template/en/default/admin/classifications/footer.html.tmpl
@@ -0,0 +1,10 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+<p>Back to the <a href="./">main [% terms.bugs %] page</a>
+or <a href="editclassifications.cgi"> edit</a> more classifications.</p>
diff --git a/template/en/default/admin/classifications/reclassify.html.tmpl b/template/en/default/admin/classifications/reclassify.html.tmpl
new file mode 100644
index 0000000..13fb3a3
--- /dev/null
+++ b/template/en/default/admin/classifications/reclassify.html.tmpl
@@ -0,0 +1,77 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Reclassify products"
+%]
+
+<form method=post action="editclassifications.cgi">
+ <table border=0 cellpadding=4 cellspacing=0>
+ <tr>
+ <th align="right">Classification:</th>
+ <td valign="top" colspan=3>[% classification.name FILTER html %]</td>
+
+ </tr><tr>
+ <th align="right">Description:</th>
+ <td valign="top" colspan=3>
+ [% IF classification.description %]
+ [% classification.description FILTER html_light %]
+ [% ELSE %]
+ <font color="red">description missing</font>
+ [% END %]
+ </td>
+
+ </tr><tr>
+ <th align="right">Sortkey:</th>
+ <td valign="top" colspan=3>[% classification.sortkey FILTER html %]</td>
+
+ </tr><tr>
+ <th align="right">Products:</th>
+ <td valign="top">Other Classifications</td>
+ <td></td>
+ <td valign="top">This Classification</td>
+
+ </tr><tr>
+ <td></td>
+ <td valign="top">
+ <select name="prodlist" id="prodlist" multiple="multiple" size="20">
+ [% FOREACH class = classifications %]
+ [% IF class.id != classification.id %]
+ [% FOREACH product = class.products %]
+ <option value="[% product.name FILTER html %]">
+ [[% class.name FILTER html %]]&nbsp;[% product.name FILTER html %]
+ </option>
+ [% END %]
+ [% END %]
+ [% END %]
+ </select></td>
+
+ <td align="center">
+ <input type=submit value=" Add &gt;&gt; " name="add_products"><br><br>
+ <input type=submit value="&lt;&lt; Remove" name="remove_products">
+ </td>
+
+ <td valign="middle" rowspan=2>
+ <select name="myprodlist" id="myprodlist" multiple="multiple" size="20">
+ [% FOREACH product = classification.products %]
+ <option value="[% product.name FILTER html %]">
+ [% product.name FILTER html %]
+ </option>
+ [% END %]
+ </select></td>
+ </tr>
+ </table>
+
+ <input type=hidden name="action" value="reclassify">
+ <input type=hidden name="classification" value="[% classification.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+</form>
+
+[% PROCESS admin/classifications/footer.html.tmpl %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/classifications/select.html.tmpl b/template/en/default/admin/classifications/select.html.tmpl
new file mode 100644
index 0000000..541ded9
--- /dev/null
+++ b/template/en/default/admin/classifications/select.html.tmpl
@@ -0,0 +1,54 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Select classification"
+%]
+
+<table border=1 cellpadding=4 cellspacing=0>
+ <tr bgcolor="#6666ff">
+ <th align="left">Edit Classification ...</th>
+ <th align="left">Description</th>
+ <th align="left">Sortkey</th>
+ <th align="left">Products</th>
+ <th align="left">Action</th>
+ </tr>
+
+ [% FOREACH cl = classifications %]
+ <tr>
+ <td valign="top"><a href="editclassifications.cgi?action=edit&amp;classification=[% cl.name FILTER uri %]"><b>[% cl.name FILTER html %]</b></a></td>
+ <td valign="top">
+ [% IF cl.description %]
+ [% cl.description FILTER html_light %]
+ [% ELSE %]
+ <font color="red">none</font>
+ [% END %]
+ </td>
+ <td valign="top">[% cl.sortkey FILTER html %]</td>
+ [% IF (cl.id == 1) %]
+ <td valign="top">[% cl.product_count FILTER html %]</td>
+ [% ELSE %]
+ <td valign="top"><a href="editclassifications.cgi?action=reclassify&amp;classification=[% cl.name FILTER uri %]">reclassify ([% cl.product_count FILTER html %])</a></td>
+ [% END %]
+
+ [%# don't allow user to delete the default id. %]
+ [% IF (cl.id == 1) %]
+ <td valign="top">&nbsp;</td>
+ [% ELSE %]
+ <td valign="top"><a href="editclassifications.cgi?action=del&amp;classification=[% cl.name FILTER uri %]">delete</a></td>
+ [% END %]
+ </tr>
+ [% END %]
+
+</table>
+
+<p>
+ <a href="editclassifications.cgi?action=add">Add a new classification</a>.
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/components/confirm-delete.html.tmpl b/template/en/default/admin/components/confirm-delete.html.tmpl
new file mode 100644
index 0000000..82bf018
--- /dev/null
+++ b/template/en/default/admin/components/confirm-delete.html.tmpl
@@ -0,0 +1,149 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # comp: object; Bugzilla::Component object representing the component the
+ # user wants to delete.
+ # product: object; Bugzilla::Product object representing the product to
+ # which the component belongs.
+ #%]
+
+[% title = BLOCK %]Delete component '[% comp.name FILTER html %]'
+from '[% product.name FILTER html %]' product
+ [% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+%]
+
+<table border="1" cellpadding="4" cellspacing="0">
+<tr bgcolor="#6666FF">
+ <th valign="top" align="left">Field</th>
+ <th valign="top" align="left">Value</th>
+</tr>
+<tr>
+ <td valign="top">Component:</td>
+ <td valign="top">[% comp.name FILTER html %]</td>
+</tr>
+<tr>
+ <td valign="top">Component Description:</td>
+ <td valign="top">[% comp.description FILTER html_light %]</td>
+</tr>
+<tr>
+ <td valign="top">Default assignee:</td>
+ <td valign="top">[% comp.default_assignee.login FILTER html %]</td>
+
+[% IF Param('useqacontact') %]
+</tr>
+<tr>
+ <td valign="top">Default QA contact:</td>
+ <td valign="top">[% comp.default_qa_contact.login FILTER html %]</td>
+[% END %]
+
+</tr>
+<tr>
+ <td valign="top">Component of Product:</td>
+ <td valign="top">[% product.name FILTER html %]</td>
+
+[% IF product.description %]
+</tr>
+<tr>
+ <td valign="top">Product Description:</td>
+ <td valign="top">[% product.description FILTER html_light %]</td>
+[% END %]
+
+[% IF Param('usetargetmilestone') %]
+</tr>
+<tr>
+ <td valign="top">Product Milestone URL:</td>
+ <td valign="top">
+ <a href="[% product.milestone_url FILTER html %]">
+ [% product.milestone_url FILTER html %]
+ </a>
+ </td>
+[% END %]
+
+</tr>
+<tr>
+ <TD VALIGN="top">Open for [% terms.bugs %]:</TD>
+ <TD VALIGN="top">[% IF product.is_active && comp.isactive %]Yes[% ELSE %]No[% END %]</td>
+</tr>
+<tr>
+ <td valign="top">[% terms.Bugs %]:</td>
+ <td valign="top">
+[% IF comp.bug_count %]
+ <a title="List of [% terms.bugs %] for component '[% comp.name FILTER html %]'"
+ href="buglist.cgi?component=[% comp.name FILTER uri %]&amp;product=
+ [%- product.name FILTER uri %]">[% comp.bug_count %]</a>
+[% ELSE %]
+ None
+[% END %]
+ </td>
+</tr>
+</table>
+
+<h2>Confirmation</h2>
+
+[% IF comp.bug_count %]
+
+ [% IF !Param("allowbugdeletion") %]
+ <p class="confirmation">
+ Sorry, there
+
+ [% IF comp.bug_count > 1 %]
+ are [% comp.bug_count %] [%+ terms.bugs %]
+ [% ELSE %]
+ is [% comp.bug_count %] [%+ terms.bug %]
+ [% END %]
+
+ outstanding for this component. You must reassign
+
+ [% IF comp.bug_count > 1 %]
+ those [% terms.bugs %]
+ [% ELSE %]
+ that [% terms.bug %]
+ [% END %]
+
+ to another component before you can delete this one.
+ </p>
+ [% ELSE %]
+
+ <table border="0" cellpadding="20" width="70%" bgcolor="red"><tr><td>
+
+ There [% IF comp.bug_count > 1 %]
+ are [% comp.bug_count %] [%+ terms.bugs %]
+ [% ELSE %]
+ is 1 [% terms.bug %]
+ [% END %]
+ entered for this component! When you delete this
+ component, <b>ALL</b> stored [% terms.bugs %] and
+ their history will be deleted too.
+ </td></tr></table>
+
+ [% END %]
+
+[% END %]
+
+[% IF comp.bug_count == 0 || Param('allowbugdeletion') %]
+
+ <p>Do you really want to delete this component?</p>
+
+ <form method="post" action="editcomponents.cgi">
+ <input type="submit" id="delete" value="Yes, delete">
+ <input type="hidden" name="action" value="delete">
+ <input type="hidden" name="product" value="[% product.name FILTER html %]">
+ <input type="hidden" name="component" value="[% comp.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ </form>
+
+[% END %]
+
+[% PROCESS admin/components/footer.html.tmpl %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/components/create.html.tmpl b/template/en/default/admin/components/create.html.tmpl
new file mode 100644
index 0000000..f281160
--- /dev/null
+++ b/template/en/default/admin/components/create.html.tmpl
@@ -0,0 +1,36 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: object; Bugzilla::Product object representing the product to
+ # which the component belongs.
+ #%]
+
+[% title = BLOCK %]Add component to the [% product.name FILTER html %] product[% END %]
+[% PROCESS global/header.html.tmpl
+ yui = [ 'autocomplete' ]
+ javascript_urls = [ "js/field.js" ]
+ title = title
+%]
+
+<form method="post" action="editcomponents.cgi">
+ <table border="0" cellpadding="4" cellspacing="0">
+
+ [% PROCESS "admin/components/edit-common.html.tmpl" %]
+
+ </table>
+ <hr>
+ <input type="submit" id="create" value="Add">
+ <input type="hidden" name="action" value="new">
+ <input type="hidden" name='product' value="[% product.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+</form>
+
+[% PROCESS admin/components/footer.html.tmpl %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/components/edit-common.html.tmpl b/template/en/default/admin/components/edit-common.html.tmpl
new file mode 100644
index 0000000..6ff4e07
--- /dev/null
+++ b/template/en/default/admin/components/edit-common.html.tmpl
@@ -0,0 +1,77 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # comp: object; Bugzilla::Component object.
+ #%]
+
+[%# When called from the "New Product" page, the component description field
+ # must have a name different from the product description field. %]
+[% DEFAULT desc_name = "description" %]
+
+<tr>
+ <th class="field_label"><label for="component">Component:</label></th>
+ <td><input size="64" maxlength="64" name="component" id="component"
+ value="[%- comp.name FILTER html %]"></td>
+</tr>
+<tr>
+ <th class="field_label"><label for="[% desc_name FILTER html %]">Component Description:</label></th>
+ <td>
+ [% INCLUDE global/textarea.html.tmpl
+ name = desc_name
+ id = desc_name
+ minrows = 4
+ cols = 64
+ wrap = 'virtual'
+ defaultcontent = comp.description
+ %]
+ </td>
+</tr>
+<tr>
+ <th class="field_label"><label for="initialowner">Default Assignee:</label></th>
+ <td>
+ [% INCLUDE global/userselect.html.tmpl
+ name => "initialowner"
+ id => "initialowner"
+ value => comp.default_assignee.login
+ size => 64
+ %]
+ </td>
+</tr>
+[% IF Param('useqacontact') %]
+ <tr>
+ <th class="field_label"><label for="initialqacontact">Default QA contact:</label></th>
+ <td>
+ [% INCLUDE global/userselect.html.tmpl
+ name => "initialqacontact"
+ id => "initialqacontact"
+ value => comp.default_qa_contact.login
+ size => 64
+ emptyok => 1
+ %]
+ </td>
+ </tr>
+[% END %]
+<tr>
+ <th class="field_label"><label for="initialcc">Default CC List:</label></th>
+ <td>
+ [% INCLUDE global/userselect.html.tmpl
+ name => "initialcc"
+ id => "initialcc"
+ value => initial_cc_names
+ size => 64
+ multiple => 5
+ %]
+ <br>
+ [% IF !Param("usemenuforusers") %]
+ <em>Enter user names for the CC list as a comma-separated list.</em>
+ [% END %]
+ </td>
+</tr>
+
+[% Hook.process('rows') %]
diff --git a/template/en/default/admin/components/edit.html.tmpl b/template/en/default/admin/components/edit.html.tmpl
new file mode 100644
index 0000000..748175b
--- /dev/null
+++ b/template/en/default/admin/components/edit.html.tmpl
@@ -0,0 +1,66 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # comp: object; Bugzilla::Component object representing the component the
+ # user wants to edit.
+ # product: object; Bugzilla::Product object representing the product to
+ # which the component belongs.
+ #%]
+
+[% title = BLOCK %]
+ Edit component '[% comp.name FILTER html %]' of product '[% product.name FILTER html %]'
+[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+ yui = [ 'autocomplete' ]
+ javascript_urls = [ "js/field.js" ]
+%]
+
+<form method="post" action="editcomponents.cgi">
+ <table border="0" cellpadding="4" cellspacing="0">
+
+ [% PROCESS "admin/components/edit-common.html.tmpl" %]
+
+ <tr>
+ <th class="field_label"><label for="isactive">Enabled For [% terms.Bugs %]:</label></th>
+ <td><input id="isactive" name="isactive" type="checkbox" value="1"
+ [% 'checked="checked"' IF comp.isactive %]></td>
+ </tr>
+ <tr>
+ <th class="field_label">[% terms.Bugs %]:</th>
+ <td>
+[% IF comp.bug_count > 0 %]
+ <a title="[% terms.Bugs %] in component '[% comp.name FILTER html %]'"
+ href="buglist.cgi?component=
+ [%- comp.name FILTER uri %]&amp;product=
+ [%- product.name FILTER uri %]">[% comp.bug_count %]</a>
+[% ELSE %]
+ None
+[% END %]
+ </td>
+ </tr>
+
+ </table>
+
+ <input type="hidden" name="action" value="update">
+ <input type="hidden" name="componentold" value="[% comp.name FILTER html %]">
+ <input type="hidden" name="product" value="[% product.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="submit" value="Save Changes" id="update"> or <a
+ href="editcomponents.cgi?action=del&amp;product=
+ [%- product.name FILTER uri %]&amp;component=
+ [%- comp.name FILTER uri %]">Delete</a> this component.
+
+</form>
+
+[% PROCESS admin/components/footer.html.tmpl
+ no_edit_component_link = 1
+%]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/components/footer.html.tmpl b/template/en/default/admin/components/footer.html.tmpl
new file mode 100644
index 0000000..86d0afb
--- /dev/null
+++ b/template/en/default/admin/components/footer.html.tmpl
@@ -0,0 +1,42 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # comp: object; Bugzilla::Component object representing the component
+ # product: object; Bugzilla::Product object representing the product to
+ # which the component belongs.
+ #%]
+
+<hr>
+
+<p>
+Edit
+
+[% IF comp && !no_edit_component_link %]
+ component <a
+ title="Edit Component '[% comp.name FILTER html %]'"
+ href="editcomponents.cgi?action=edit&amp;product=
+ [%- product.name FILTER uri %]&amp;component=[% comp.name FILTER uri %]">
+ '[% comp.name FILTER html %]'</a>
+ or edit
+[% END %]
+
+[% IF !no_edit_other_components_link %]
+other components of product <a
+ title="Choose a component from product '[% product.name FILTER html %]' to edit"
+ href="editcomponents.cgi?product=
+ [%- product.name FILTER uri %]">'[% product.name FILTER html %]'</a>,
+ or edit
+[% END %]
+
+product <a
+ title="Edit Product '[% product.name FILTER html %]'"
+ href="editproducts.cgi?action=edit&amp;product=
+ [%- product.name FILTER uri %]">'[% product.name FILTER html %]'</a>.
+
+</p>
diff --git a/template/en/default/admin/components/list.html.tmpl b/template/en/default/admin/components/list.html.tmpl
new file mode 100644
index 0000000..fc36bcd
--- /dev/null
+++ b/template/en/default/admin/components/list.html.tmpl
@@ -0,0 +1,133 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # showbugcounts: if defined, then bug counts should be included in the table
+ # product: object; Bugzilla::Product object representing the product to
+ # which the component belongs.
+ #%]
+
+[% title = BLOCK %]Select component of product
+ '[% product.name FILTER html %]'[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+%]
+
+[% edit_contentlink = BLOCK %]editcomponents.cgi?action=edit&amp;product=
+ [%- product.name FILTER uri %]&amp;component=%%name%%[% END %]
+[% delete_contentlink = BLOCK %]editcomponents.cgi?action=del&amp;product=
+ [%- product.name FILTER uri %]&amp;component=%%name%%[% END %]
+[% bug_count_contentlink = BLOCK %]buglist.cgi?component=%%name%%&amp;product=
+ [%- product.name FILTER uri %][% END %]
+
+
+[% columns = [
+ {
+ name => "name"
+ heading => "Edit component..."
+ contentlink => edit_contentlink
+ },
+ {
+ name => "description"
+ heading => "Description"
+ allow_html_content => 1
+ },
+ {
+ name => "initialowner"
+ heading => "Default Assignee"
+ },
+ ]
+%]
+
+[% IF Param('useqacontact') %]
+
+ [% columns.push({
+ name => 'initialqacontact'
+ heading => 'Default QA Contact'
+ }) %]
+
+[% END %]
+
+[% columns.push({
+ name => "initial_cc_names"
+ heading => "Default CC list"
+ },
+ {
+ name => "isactive"
+ heading => "Active"
+ yesno_field => 1
+ }) %]
+
+[% IF showbugcounts %]
+
+ [% columns.push({
+ name => 'bug_count'
+ heading => "$terms.Bugs"
+ align => "right"
+ contentlink => bug_count_contentlink
+ }) %]
+
+[% END %]
+
+[% columns.push({
+ heading => "Action"
+ content => "Delete"
+ contentlink => delete_contentlink
+ }) %]
+
+[%# Overrides the initialowner, the initialqacontact, and the initial_cc_names with right values %]
+[% overrides.initialowner = {} %]
+[% overrides.initialqacontact = {} %]
+[% overrides.initial_cc_names = {} %]
+
+[%# "component" is a reserved word in Template Toolkit. %]
+[% FOREACH my_component = product.components %]
+ [% overrides.initialowner.name.${my_component.name} = {
+ override_content => 1
+ content => my_component.default_assignee.login
+ }
+ %]
+ [% overrides.initialqacontact.name.${my_component.name} = {
+ override_content => 1
+ content => my_component.default_qa_contact.login
+ }
+ %]
+ [% SET initial_cc_list = [] %]
+ [% FOREACH cc_user = my_component.initial_cc %]
+ [% initial_cc_list.push(cc_user.login) %]
+ [% END %]
+ [% overrides.initial_cc_names.name.${my_component.name} = {
+ override_content => 1
+ content => initial_cc_list.join(', ')
+ }
+ %]
+[% END %]
+
+[% Hook.process('before_table') %]
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ data = product.components
+ overrides = overrides
+%]
+
+<p><a href="editcomponents.cgi?action=add&amp;product=[% product.name FILTER uri %]">Add</a>
+ a new component to product '[% product.name FILTER html %]'</p>
+
+[% IF ! showbugcounts %]
+
+ <p><a href="editcomponents.cgi?product=[% product.name FILTER uri %]&amp;showbugcounts=1">
+ Redisplay table with [% terms.bug %] counts (slower)</a></p>
+
+[% END %]
+
+[% PROCESS admin/components/footer.html.tmpl
+ no_edit_other_components_link = 1
+ %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/components/select-product.html.tmpl b/template/en/default/admin/components/select-product.html.tmpl
new file mode 100644
index 0000000..55600d9
--- /dev/null
+++ b/template/en/default/admin/components/select-product.html.tmpl
@@ -0,0 +1,54 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # products: array of product objects
+ # showbugcounts: if defined, then bug counts should be included in the table
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Edit components for which product?"
+%]
+
+[% columns = [
+ {
+ name => "name"
+ heading => "Edit components of..."
+ contentlink => "editcomponents.cgi?product=%%name%%"
+ },
+ {
+ name => "description"
+ heading => "Description"
+ allow_html_content => 1
+ }
+ ]
+%]
+
+[% IF showbugcounts %]
+
+ [% columns.push({
+ name => 'bug_count'
+ heading => "$terms.Bugs"
+ align => "right"
+ contentlink => "buglist.cgi?product=%%name%%"
+ })
+ %]
+
+[% END %]
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ data = products
+%]
+
+[% IF !showbugcounts %]
+ <p><a href="editcomponents.cgi?showbugcounts=1">
+ Redisplay table with [% terms.bug %] counts (slower)</a></p>
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/confirm-action.html.tmpl b/template/en/default/admin/confirm-action.html.tmpl
new file mode 100644
index 0000000..e3b9ef5
--- /dev/null
+++ b/template/en/default/admin/confirm-action.html.tmpl
@@ -0,0 +1,87 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # abuser: identity of the user who created the (invalid?) token.
+ # token_action: the action the token was supposed to serve.
+ # expected_action: the action the user was going to do.
+ # script_name: the script generating this warning.
+ # alternate_script: the suggested script to redirect the user to
+ # if he declines submission.
+ #%]
+
+[% PROCESS global/header.html.tmpl title = "Suspicious Action"
+ style_urls = ['skins/standard/global.css'] %]
+
+[% IF abuser %]
+ <div class="throw_error">
+ <p>When you view an administrative form in [% terms.Bugzilla %], a token string
+ is randomly generated and stored both in the database and in the form you loaded,
+ to make sure that the requested changes are being made as a result of submitting
+ a form generated by [% terms.Bugzilla %]. Unfortunately, the token used right now
+ is incorrect, meaning that it looks like you didn't come from the right page.
+ The following token has been used :</p>
+
+ <table border="0" cellpadding="5" cellspacing="0">
+ [% IF token_action != expected_action %]
+ <tr>
+ <th>Action&nbsp;stored:</th>
+ <td>[% token_action FILTER html %]</td>
+ </tr>
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ This action doesn't match the one expected ([% expected_action FILTER html %]).
+ </td>
+ </tr>
+ [% END %]
+
+ [% IF abuser != user.identity %]
+ <tr>
+ <th>Generated&nbsp;by:</th>
+ <td>[% abuser FILTER html %]</td>
+ </tr>
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ This token has not been generated by you. It is possible that someone
+ tried to trick you!
+ </td>
+ </tr>
+ [% END %]
+ </table>
+
+ <p>Please report this problem to [%+ Param("maintainer") FILTER html %].</p>
+ </div>
+[% ELSE %]
+ <div class="throw_error">
+ It looks like you didn't come from the right page (you have no valid token for
+ the <em>[% expected_action FILTER html %]</em> action while processing the
+ '[% script_name FILTER html%]' script). The reason could be one of:<br>
+ <ul>
+ <li>You clicked the "Back" button of your web browser after having successfully
+ submitted changes, which is generally not a good idea (but harmless).</li>
+ <li>You entered the URL in the address bar of your web browser directly,
+ which should be safe.</li>
+ <li>You clicked on a URL which redirected you here <b>without your consent</b>,
+ in which case this action is much more critical.</li>
+ </ul>
+ Are you sure you want to commit these changes anyway? This may result in
+ unexpected and undesired results.
+ </div>
+
+ <form name="check" id="check" method="post" action="[% script_name FILTER html %]">
+ [% PROCESS "global/hidden-fields.html.tmpl"
+ exclude="^(Bugzilla_login|Bugzilla_password)$" %]
+ <input type="submit" id="confirm" value="Confirm Changes">
+ </form>
+ <p>Or throw away these changes and go back to <a href="[% alternate_script FILTER html %]">
+ [%- alternate_script FILTER html %]</a>.</p>
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/custom_fields/cf-js.js.tmpl b/template/en/default/admin/custom_fields/cf-js.js.tmpl
new file mode 100644
index 0000000..bfdacb8
--- /dev/null
+++ b/template/en/default/admin/custom_fields/cf-js.js.tmpl
@@ -0,0 +1,66 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+// Disable a checkbox based on the state of another one.
+function toggleCheckbox(this_checkbox, other_checkbox_id) {
+ var other_checkbox = document.getElementById(other_checkbox_id);
+ other_checkbox.disabled = !this_checkbox.checked;
+}
+
+var select_values = new Array();
+[% USE Bugzilla %]
+[% FOREACH sel_field = Bugzilla.fields({ is_select => 1 }) %]
+ select_values[[% sel_field.id FILTER js %]] = [
+ [% FOREACH legal_value = sel_field.legal_values %]
+ [%# Prefix components with the name of their product so that admins
+ know which component we're talking about. #%]
+ [% IF sel_field.name == 'component' %]
+ [% SET value_name = display_value('product', legal_value.product.name) _ ': '
+ _ display_value(sel_field.name, legal_value.name) %]
+ [% ELSE %]
+ [% SET value_name = display_value(sel_field.name, legal_value.name) %]
+ [% END %]
+ [[% legal_value.id FILTER js %], '[% value_name FILTER js %]'][% ',' UNLESS loop.last %]
+ [% END %]
+ ];
+[% END %]
+
+function onChangeType(type_field) {
+ var value_field = document.getElementById('value_field_id');
+ if (type_field.value == [% constants.FIELD_TYPE_SINGLE_SELECT %]
+ || type_field.value == [% constants.FIELD_TYPE_MULTI_SELECT %])
+ {
+ value_field.disabled = false;
+ }
+ else {
+ value_field.disabled = true;
+ }
+
+ var reverse_desc = document.getElementById('reverse_desc');
+ if (type_field.value == [% constants.FIELD_TYPE_BUG_ID %])
+ {
+ reverse_desc.disabled = false;
+ }
+ else {
+ reverse_desc.disabled = true;
+ reverse_desc.value = '';
+ }
+}
+
+function onChangeVisibilityField() {
+ var vis_field = document.getElementById('visibility_field_id');
+ var vis_value = document.getElementById('visibility_values');
+
+ if (vis_field.value) {
+ var values = select_values[vis_field.value];
+ bz_populateSelectFromArray(vis_value, values);
+ }
+ else {
+ bz_clearOptions(vis_value);
+ }
+}
diff --git a/template/en/default/admin/custom_fields/confirm-delete.html.tmpl b/template/en/default/admin/custom_fields/confirm-delete.html.tmpl
new file mode 100644
index 0000000..85338c0
--- /dev/null
+++ b/template/en/default/admin/custom_fields/confirm-delete.html.tmpl
@@ -0,0 +1,60 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # field: object; the field object that you are trying to delete.
+ # token: string; the delete_field token required to complete deletion.
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+
+[% title = BLOCK %]
+ Delete the Custom Field '[% field.name FILTER html %]' ([% field.description FILTER html %])
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+ doc_section = "custom-fields.html#delete-custom-fields"
+%]
+
+<table border="1" cellpadding="4" cellspacing="0">
+<tr bgcolor="#6666FF">
+ <th valign="top" align="left">Field</th>
+ <th valign="top" align="left">Value</th>
+</tr>
+<tr>
+ <td valign="top">Custom Field:</td>
+ <td valign="top">[% field.name FILTER html %]</td>
+</tr>
+<tr>
+ <td valign="top">Description:</td>
+ <td valign="top">[% field.description FILTER html %]</td>
+</tr>
+<tr>
+ <td valign="top">Type:</td>
+ <td valign="top">[% field_types.${field.type} FILTER html %]</td>
+</tr>
+</table>
+
+<h2>Confirmation</h2>
+
+<p class="confirmation">
+ Are you sure you want to remove this field from the database?<br>
+ <em>This action will only be successful if the field is obsolete,
+ and has never been used in [% terms.abug FILTER html %].</em>
+</p>
+
+<a href="editfields.cgi?action=delete&amp;name=[% field.name FILTER html %]&amp;token=[% token FILTER html %]">
+ Delete field '[% field.description FILTER html %]'</a>
+
+<p>
+ <a href="editfields.cgi">Back to the list of existing custom fields</a>
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/custom_fields/create.html.tmpl b/template/en/default/admin/custom_fields/create.html.tmpl
new file mode 100644
index 0000000..fb7f06f
--- /dev/null
+++ b/template/en/default/admin/custom_fields/create.html.tmpl
@@ -0,0 +1,179 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # none
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+
+[% javascript = BLOCK %]
+ [% INCLUDE "admin/custom_fields/cf-js.js.tmpl" %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = "Add a new Custom Field"
+ onload = "document.getElementById('new_bugmail').disabled = true;"
+ javascript_urls = [ 'js/util.js' ]
+ doc_section = "custom-fields.html#add-custom-fields"
+ style_urls = ['skins/standard/admin.css']
+%]
+
+[%# set initial editability of fields such as Reverse Relationship Description %]
+<script type="text/javascript">
+YAHOO.util.Event.onDOMReady(function() {onChangeType(document.getElementById('type'))});
+</script>
+
+<p>
+ Adding custom fields can make the interface of [% terms.Bugzilla %] very
+ complicated. Many admins who are new to [% terms.Bugzilla %] start off
+ adding many custom fields, and then their users complain that the interface
+ is "too complex". Please think carefully before adding any custom fields.
+ It may be the case that [% terms.Bugzilla %] already does what you need,
+ and you just haven't enabled the correct feature yet.
+</p>
+
+<ul>
+ <li>Custom field names must begin with "cf_" to distinguish them from
+ standard fields. If you omit "cf_" from the beginning of the name, it
+ will be added for you.</li>
+ <li>Descriptions are a very short string describing the field and will be
+ used as the label for this field in the user interface.</li>
+</ul>
+
+<form id="add_field" action="editfields.cgi" method="GET">
+ <table border="0" cellspacing="0" cellpadding="5" id="edit_custom_field">
+ <tr>
+ <th class="narrow_label"><label for="name">Name:</label></th>
+ <td>
+ <input type="text" id="name" name="name" value="cf_" size="40" maxlength="64">
+ </td>
+
+ <th>
+ <label for="enter_bug">Can be set on [% terms.bug %] creation:</label>
+ </th>
+ <td>
+ <input type="checkbox" id="enter_bug" name="enter_bug" value="1"
+ onchange="toggleCheckbox(this, 'new_bugmail');">
+ </td>
+ </tr>
+ <tr>
+ <th class="narrow_label"><label for="desc">Description:</label></th>
+ <td><input type="text" id="desc" name="desc" value="" size="40"></td>
+
+ <th>
+ <label for="new_bugmail">Displayed in [% terms.bug %]mail for new [% terms.bugs %]:</label>
+ </th>
+ <td><input type="checkbox" id="new_bugmail" name="new_bugmail" value="1"></td>
+ </tr>
+ <tr>
+ <th class="narrow_label"><label for="type">Type:</label></th>
+ <td>
+ <select id="type" name="type" onchange="onChangeType(this)">
+ [% FOREACH type = field_types.keys %]
+ [% NEXT IF type == constants.FIELD_TYPE_UNKNOWN %]
+ <option value="[% type FILTER html %]">[% field_types.$type FILTER html %]</option>
+ [% END %]
+ </select>
+ </td>
+
+ <th><label for="obsolete">Is obsolete:</label></th>
+ <td><input type="checkbox" id="obsolete" name="obsolete" value="1"></td>
+ </tr>
+ <tr>
+ <th class="narrow_label"><label for="sortkey">Sortkey:</label></th>
+ <td>
+ <input type="text" id="sortkey" name="sortkey" size="6" maxlength="6">
+ </td>
+
+ <th align="right"><label for="is_mandatory">Is mandatory:</label></th>
+ <td><input type="checkbox" id="is_mandatory" name="is_mandatory" value="1"></td>
+ </tr>
+
+ <tr>
+ <th class="narrow_label">Long Description:</th>
+ <td>
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'long_desc'
+ id = 'long_desc'
+ minrows = 3
+ maxrows = 5
+ cols = 46
+ defaultcontent = defaultcontent
+ %]
+ </td>
+ <th>
+ <label for="visibility_field_id">Field only appears when:</label>
+ </th>
+ <td>
+ <select name="visibility_field_id" id="visibility_field_id"
+ onchange="onChangeVisibilityField()">
+ <option></option>
+ [% FOREACH sel_field = Bugzilla.fields({ is_select => 1 }) %]
+ <option value="[% sel_field.id FILTER html %]">
+ [% sel_field.description FILTER html %]
+ ([% sel_field.name FILTER html %])
+ </option>
+ [% END %]
+ </select>
+ <label for="visibility_values">
+ <strong>is set to any of:</strong>
+ </label>
+ <select multiple="multiple" size="5" name="visibility_values"
+ id="visibility_values" class="field_value">
+ <option value=""></option>
+ </select>
+ </td>
+ </tr>
+
+ <tr>
+ <th class="narrow_label">
+ <label for="reverse_desc">Reverse Relationship Description:</label>
+ </th>
+ <td>
+ <input type="text" id="reverse_desc" name="reverse_desc" value="" size="40" disabled="disabled">
+ <br/>
+ Use this label for the list of [% terms.bugs %] that link to
+ [%+ terms.abug %] with this
+ [%+ field_types.${constants.FIELD_TYPE_BUG_ID} FILTER html %]
+ field. For example, if the description is "Is a duplicate of",
+ the reverse description would be "Duplicates of this [% terms.bug %]".
+ Leave blank to disable the list for this field.
+ </td>
+ <th>
+ <label for="value_field_id">
+ Field that controls the values<br>
+ that appear in this field:
+ </label>
+ </th>
+
+ <td>
+ <select disabled="disabled" name="value_field_id" id="value_field_id">
+ <option></option>
+ [% FOREACH sel_field = Bugzilla.fields({ is_select => 1 }) %]
+ <option value="[% sel_field.id FILTER html %]">
+ [% sel_field.description FILTER html %]
+ ([% sel_field.name FILTER html %])
+ </option>
+ [% END %]
+ </select>
+ </td>
+ </tr>
+ </table>
+ <p>
+ <input type="hidden" name="action" value="new">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="submit" id="create" value="Create">
+ </p>
+</form>
+
+<p>
+ <a href="editfields.cgi">Back to the list of existing custom fields</a>
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/custom_fields/edit.html.tmpl b/template/en/default/admin/custom_fields/edit.html.tmpl
new file mode 100644
index 0000000..a1d7393
--- /dev/null
+++ b/template/en/default/admin/custom_fields/edit.html.tmpl
@@ -0,0 +1,195 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # field: Bugzila::Field; the current field being edited
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+
+[% title = BLOCK %]
+ Edit the Custom Field '[% field.name FILTER html %]' ([% field.description FILTER html %])
+[% END %]
+
+[% javascript = BLOCK %]
+ [% INCLUDE "admin/custom_fields/cf-js.js.tmpl" %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ onload = "toggleCheckbox(document.getElementById('enter_bug'), 'new_bugmail');"
+ javascript_urls = [ 'js/util.js' ]
+ doc_section = "custom-fields.html#edit-custom-fields"
+ style_urls = ['skins/standard/admin.css']
+%]
+
+<p>
+ Descriptions are a very short string describing the field and will be used as
+ the label for this field in the user interface.
+</p>
+
+<form id="edit_field" action="editfields.cgi" method="GET">
+ <table border="0" cellspacing="0" cellpadding="5" id="edit_custom_field">
+ <tr>
+ <th class="narrow_label">Name:</th>
+ <td>[% field.name FILTER html %]</td>
+
+ <th>
+ <label for="enter_bug">Can be set on [% terms.bug %] creation:</label>
+ </th>
+ <td><input type="checkbox" id="enter_bug" name="enter_bug" value="1"
+ [%- " checked" IF field.enter_bug %]
+ onchange="toggleCheckbox(this, 'new_bugmail');"></td>
+ </tr>
+ <tr>
+ <th class="narrow_label"><label for="desc">Description:</label></th>
+ <td><input type="text" id="desc" name="desc" size="40"
+ value="[% field.description FILTER html %]"></td>
+
+ <th>
+ <label for="new_bugmail">Displayed in [% terms.bug %]mail for new [% terms.bugs %]:</label>
+ </th>
+ <td><input type="checkbox" id="new_bugmail" name="new_bugmail" value="1"
+ [%- " checked" IF field.mailhead %]></td>
+ </tr>
+ <tr>
+ <th class="narrow_label">Type:</th>
+ <td>[% field_types.${field.type} FILTER html %]</td>
+
+ <th><label for="obsolete">Is obsolete:</label></th>
+ <td><input type="checkbox" id="obsolete" name="obsolete" value="1"
+ [%- " checked" IF field.obsolete %]></td>
+ </tr>
+ <tr>
+ <th class="narrow_label"><label for="sortkey">Sortkey:</label></th>
+ <td>
+ <input type="text" id="sortkey" name="sortkey" size="6" maxlength="6"
+ value="[% field.sortkey FILTER html %]">
+ </td>
+ <th align="right"><label for="is_mandatory">Is mandatory:</label></th>
+ <td><input type="checkbox" id="is_mandatory" name="is_mandatory" value="1"
+ [%- ' checked="checked"' IF field.is_mandatory %]></td>
+ </tr>
+ <tr>
+ <th class="narrow_label">Long Description:</th>
+ <td>
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'long_desc'
+ id = 'long_desc'
+ minrows = 3
+ maxrows = 5
+ cols = 46
+ defaultcontent = field.long_desc
+ %]
+ </td>
+ <th>
+ <label for="visibility_field_id">Field only appears when:</label>
+ </th>
+ <td>
+ <select name="visibility_field_id" id="visibility_field_id"
+ onchange="onChangeVisibilityField()">
+ <option></option>
+ [% FOREACH sel_field = Bugzilla.fields({ is_select => 1 }) %]
+ [% NEXT IF sel_field.id == field.id %]
+ <option value="[% sel_field.id FILTER html %]"
+ [% ' selected="selected"'
+ IF sel_field.id == field.visibility_field.id %]>
+ [% sel_field.description FILTER html %]
+ ([% sel_field.name FILTER html %])
+ </option>
+ [% END %]
+ </select>
+ <label for="visibility_values">
+ <strong>is set to any of:</strong>
+ </label>
+ <select multiple="multiple" size="5" name="visibility_values"
+ id="visibility_values" class="field_value">
+ [% FOREACH value = field.visibility_field.legal_values %]
+ <option value="[% value.id FILTER html %]"
+ [% " selected" IF field.visibility_values.contains(value) %]>
+ [% IF field.visibility_field.name == 'component' %]
+ [% display_value('product', value.product.name) FILTER html %]:
+ [% END %]
+ [%+ display_value(field.visibility_field.name, value.name) FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ </td>
+ </tr>
+ [% IF field.type == constants.FIELD_TYPE_BUG_ID %]
+ <tr>
+ <th class="narrow_label">
+ <label for="reverse_desc">Reverse Relationship Description:</label>
+ </th>
+ <td>
+ <input type="text" id="reverse_desc" name="reverse_desc" size="40"
+ value="[% field.reverse_desc FILTER html %]">
+ <br/>
+ Use this label for the list of [% terms.bugs %] that link to
+ [%+ terms.abug %] with this
+ [%+ field_types.${constants.FIELD_TYPE_BUG_ID} FILTER html %] field.
+ For example, if the description is "Is a duplicate of",
+ the reverse description would be "Duplicates of this [% terms.bug %]".
+ Leave blank to disable the list for this field.
+ </td>
+ <td colspan="2">&nbsp;</td>
+ </tr>
+ [% END %]
+ [% IF field.is_select %]
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ <a href="editvalues.cgi?field=[% field.name FILTER uri %]">Edit
+ legal values for this field</a>.
+ </td>
+
+ <th>
+ <label for="value_field_id">
+ Field that controls the values<br>
+ that appear in this field:
+ </label>
+ </th>
+
+ <td>
+ <select name="value_field_id" id="value_field_id">
+ <option></option>
+ [% FOREACH sel_field = Bugzilla.fields({ is_select => 1 }) %]
+ [% NEXT IF sel_field.id == field.id %]
+ <option value="[% sel_field.id FILTER html %]"
+ [% ' selected="selected"'
+ IF sel_field.id == field.value_field.id %]>
+ [% sel_field.description FILTER html %]
+ ([% sel_field.name FILTER html %])
+ </option>
+ [% END %]
+ </select>
+ </td>
+ </tr>
+ [% END %]
+ </table>
+ <br>
+ <input type="hidden" name="action" value="update">
+ <input type="hidden" name="name" value="[% field.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="submit" id="edit" value="Submit">
+</form>
+
+[% IF field.obsolete %]
+<p>
+ <a href="editfields.cgi?action=del&amp;name=[% field.name FILTER html %]">Remove
+ this custom field from the database.</a><br>
+ This action will only be successful if the custom field has never been used
+ in [% terms.abug %].<br>
+</p>
+[% END %]
+
+<p>
+ <a href="editfields.cgi">Back to the list of existing custom fields</a>
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/custom_fields/list.html.tmpl b/template/en/default/admin/custom_fields/list.html.tmpl
new file mode 100644
index 0000000..e6ec0c2
--- /dev/null
+++ b/template/en/default/admin/custom_fields/list.html.tmpl
@@ -0,0 +1,99 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # custom_fields: a list of Bugzilla::Field objects, representing custom fields.
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+
+[% PROCESS global/header.html.tmpl
+ title = "Custom Fields"
+ doc_section = "custom-fields.html"
+%]
+
+[% delete_contentlink = BLOCK %]editfields.cgi?action=del&amp;name=%%name%%[% END %]
+
+[% columns = [
+ {
+ name => "name"
+ heading => "Edit custom field..."
+ contentlink => "editfields.cgi?action=edit&amp;name=%%name%%"
+ },
+ {
+ name => "description"
+ heading => "Description"
+ },
+ {
+ name => "sortkey"
+ heading => "Sortkey"
+ },
+ {
+ name => "type"
+ heading => "Type"
+ },
+ {
+ name => "enter_bug"
+ heading => "Editable on $terms.Bug Creation"
+ },
+ {
+ name => "mailhead"
+ heading => "In ${terms.Bug}mail on $terms.Bug Creation"
+ },
+ {
+ name => "obsolete"
+ heading => "Is Obsolete"
+ },
+ {
+ name => "is_mandatory"
+ heading => "Is Mandatory"
+ },
+ {
+ name => "action"
+ heading => "Action"
+ content => ""
+ }
+ ]
+%]
+
+[% USE Bugzilla %]
+[% custom_fields = Bugzilla.fields({ custom => 1 }) %]
+
+[%# We want to display the type name of fields, not their type ID. %]
+[% overrides.type = {} %]
+
+[% FOREACH field_type = field_types.keys %]
+ [% overrides.type.type.$field_type = {
+ override_content => 1
+ content => field_types.$field_type
+ }
+ %]
+[% END %]
+
+
+[% overrides.action.obsolete = {
+ "1" => {
+ override_content => 1
+ content => "Delete"
+ override_contentlink => 1
+ contentlink => delete_contentlink
+ }
+ }
+%]
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ overrides = overrides
+ data = custom_fields
+%]
+
+<p>
+ <a href="editfields.cgi?action=add">Add a new custom field</a>
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/fieldvalues/confirm-delete.html.tmpl b/template/en/default/admin/fieldvalues/confirm-delete.html.tmpl
new file mode 100644
index 0000000..122df36
--- /dev/null
+++ b/template/en/default/admin/fieldvalues/confirm-delete.html.tmpl
@@ -0,0 +1,154 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # value: Bugzilla::Field::Choice; The field value being deleted.
+ # value_count: number; The number of values available for this field.
+ # field: object; the field the value is being deleted from.
+ #%]
+
+[% title = BLOCK %]
+ Delete Value '[% value.name FILTER html %]' from the
+ '[% field.description FILTER html %]' ([% field.name FILTER html %]) field
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+%]
+
+<table border="1" cellpadding="4" cellspacing="0">
+<tr bgcolor="#6666FF">
+ <th valign="top" align="left">Field</th>
+ <th valign="top" align="left">Value</th>
+</tr>
+<tr>
+ <td valign="top">Field Name:</td>
+ <td valign="top">[% field.description FILTER html %]</td>
+</tr>
+<tr>
+ <td valign="top">Field Value:</td>
+ <td valign="top">[% value.name FILTER html %]</td>
+</tr>
+<tr>
+ <td valign="top">[% terms.Bugs %]:</td>
+ <td valign="top">
+[% IF value.bug_count %]
+ <a title="List of [% terms.bugs %] where '
+ [%- field.description FILTER html %]' is '
+ [%- value.name FILTER html %]'"
+ href="buglist.cgi?[% field.name FILTER uri %]=
+ [%- value.name FILTER uri %]">
+ [%- value.bug_count FILTER html %]</a>
+[% ELSE %]
+ None
+[% END %]
+ </td>
+</tr>
+</table>
+
+<h2>Confirmation</h2>
+
+[% IF value.is_default || value.bug_count || (value_count == 1)
+ || value.controls_visibility_of_fields.size
+ || value.controlled_values_array.size
+%]
+
+ <p>Sorry, but the '[% value.name FILTER html %]' value cannot be deleted
+ from the '[% field.description FILTER html %]' field for the following
+ reason(s):</p>
+
+ <ul class="warningmessages">
+ [% IF value.is_default %]
+ <li>'[% value.name FILTER html %]' is the default value for
+ the '[% field.description FILTER html %]' field.
+ [% IF user.in_group('tweakparams') %]
+ You first have to <a href="editparams.cgi?section=bugfields">change
+ the default value</a> for this field before you can delete
+ this value.
+ [% END %]
+ </li>
+ [% END %]
+
+ [% IF value.bug_count %]
+ <li>
+ [% IF value.bug_count > 1 %]
+ There are [% value.bug_count FILTER html %] [%+ terms.bugs %]
+ with this field value.
+ [% ELSE %]
+ There is 1 [% terms.bug %] with this field value.
+ [% END %]
+ You must change the field value on
+ <a title="List of [% terms.bugs %] where '
+ [%- field.description FILTER html %]' is '
+ [%- value.name FILTER html %]'"
+ href="buglist.cgi?[% field.name FILTER uri %]=
+ [%- value.name FILTER uri %]">
+ [% IF value.bug_count > 1 %]
+ those [% terms.bugs %]
+ [% ELSE %]
+ that [% terms.bug %]
+ [% END %]
+ </a>
+ to another value before you can delete this value.
+ </li>
+ [% END %]
+
+ [% IF value_count == 1 %]
+ <li>'[% value.name FILTER html %]' is the last value for
+ '[%- field.description FILTER html %]', and so it cannot be deleted.
+ </li>
+ [% END %]
+
+ [% IF value.controls_visibility_of_fields.size %]
+ <li>This value controls the visibility of the following fields:<br>
+ [% FOREACH field = value.controls_visibility_of_fields %]
+ <a href="editfields.cgi?action=edit&name=
+ [%- field.name FILTER uri %]">
+ [%- field.description FILTER html %]
+ ([% field.name FILTER html %])</a><br>
+ [% END %]
+ </li>
+ [% END %]
+
+ [% IF value.controlled_values_array.size %]
+ <li>This value controls the visibility of the following values in
+ other fields:<br>
+ [% FOREACH field_name = value.controlled_values.keys %]
+ [% FOREACH controlled = value.controlled_values.${field_name} %]
+ <a href="editvalues.cgi?action=edit&field=
+ [%- controlled.field.name FILTER uri %]&value=
+ [%- controlled.name FILTER uri %]">
+ [% controlled.field.description FILTER html %]
+ ([% controlled.field.name FILTER html %]):
+ [%+ controlled.name FILTER html %]</a><br>
+ [% END %]
+ [% END %]
+ </li>
+ [% END %]
+ </ul>
+
+[% ELSE %]
+
+ <p>Do you really want to delete this value?</p>
+
+ <form method="post" action="editvalues.cgi">
+ <input type="submit" value="Yes, delete" id="delete">
+ <input type="hidden" name="action" value="delete">
+ <input type="hidden" name="field" value="[% field.name FILTER html %]">
+ <input type="hidden" name="value" value="[% value.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ </form>
+
+[% END %]
+
+[% PROCESS admin/fieldvalues/footer.html.tmpl
+ no_edit_link = 1
+ +%]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/fieldvalues/create.html.tmpl b/template/en/default/admin/fieldvalues/create.html.tmpl
new file mode 100644
index 0000000..f9f0f7e
--- /dev/null
+++ b/template/en/default/admin/fieldvalues/create.html.tmpl
@@ -0,0 +1,92 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # field: object; the field the value is being created for
+ #%]
+
+[% title = BLOCK %]
+ Add Value for the '[% field.description FILTER html %]' ([% field.name FILTER html %]) field
+[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+%]
+
+<p>
+ This page allows you to add a new value for the
+ '[% field.description FILTER html %]' field.
+</p>
+
+<form method="post" action="editvalues.cgi">
+ <table border="0" cellpadding="4" cellspacing="0">
+ <tr>
+ <th align="right"><label for="value">Value:</label></th>
+ <td>
+ <input id="value" name="value" size="30"
+ maxlength="[% constants.MAX_FIELD_VALUE_SIZE FILTER none %]">
+ </td>
+ </tr>
+ <tr>
+ <th align="right"><label for="sortkey">Sortkey:</label></th>
+ <td><input id="sortkey" name="sortkey" size="6" maxlength="6"></td>
+ </tr>
+ [% IF field.name == "bug_status" %]
+ <tr>
+ <th align="right"><label for="is_open">Status Type:</label></th>
+ <td>
+ <input type="radio" id="open_status" name="is_open" value="1"
+ checked="checked">
+ <label for="open_status">Open</label><br>
+ <input type="radio" id="closed_status" name="is_open" value="0">
+ <label for="closed_status">Closed (requires a Resolution)</label>
+ </td>
+ </tr>
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ Note: The open/close attribute can only be set now, when you create
+ the status. It cannot be edited later.
+ </td>
+ </tr>
+ [% END %]
+ [% IF field.value_field %]
+ <tr>
+ <th align="right">
+ <label for="visibility_value_id">Only appears when
+ [%+ field.value_field.description FILTER html %] is set to:
+ </label>
+ </th>
+ <td>
+ <select name="visibility_value_id" id="visibility_value_id">
+ <option></option>
+ [% FOREACH field_value = field.value_field.legal_values %]
+ [% NEXT IF field_value.name == '' %]
+ <option value="[% field_value.id FILTER none %]">
+ [% IF field.value_field.name == 'component' %]
+ [% field_value.product.name FILTER html %]:
+ [% END %]
+ [%- field_value.name FILTER html -%]
+ </option>
+ [% END %]
+ </select>
+ <small>(Leave unset to have this value always appear.)</small>
+ </td>
+ </tr>
+ [% END %]
+ </table>
+ <input type="submit" id="create" value="Add">
+ <input type="hidden" name="action" value="new">
+ <input type="hidden" name='field' value="[% field.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+</form>
+
+[% PROCESS admin/fieldvalues/footer.html.tmpl
+ no_add_link = 1
+ %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/fieldvalues/edit.html.tmpl b/template/en/default/admin/fieldvalues/edit.html.tmpl
new file mode 100644
index 0000000..ab64185
--- /dev/null
+++ b/template/en/default/admin/fieldvalues/edit.html.tmpl
@@ -0,0 +1,105 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # value: Bugzilla::Field::Choice; The field value we are editing.
+ # field: Bugzilla::Field; The field this value belongs to.
+ #%]
+
+[% title = BLOCK %]
+ Edit Value '[% value.name FILTER html %]' for the
+ '[% field.description FILTER html %]' ([% field.name FILTER html %]) field
+[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+%]
+
+<form method="post" action="editvalues.cgi">
+ <table border="0" cellpadding="4" cellspacing="0">
+
+ <tr>
+ <th valign="top" align="right">
+ <label for="value_new">Field Value:</label>
+ </th>
+ <td>
+ [% IF value.is_static %]
+ <input type="hidden" name="value_new" id="value_new"
+ value="[% value.name FILTER html %]">
+ [%- value.name FILTER html %]
+ [% ELSE %]
+ <input id="value_new" name="value_new" size="20"
+ maxlength="[% constants.MAX_FIELD_VALUE_SIZE FILTER none %]"
+ value="[% value.name FILTER html %]">
+ [% END %]
+ </td>
+ </tr>
+ <tr>
+ <th align="right"><label for="sortkey">Sortkey:</label></th>
+ <td><input id="sortkey" size="6" maxlength="6" name="sortkey"
+ value="[%- value.sortkey FILTER html %]"></td>
+ </tr>
+ [% IF field.name == "bug_status" %]
+ <tr>
+ <th align="right"><label for="is_open">Status Type:</label></th>
+ <td>[% IF value.is_open %]Open[% ELSE %]Closed[% END %]</td>
+ </tr>
+ [% END %]
+ [% IF field.value_field %]
+ <tr>
+ <th align="right">
+ <label for="visibility_value_id">Only appears when
+ [%+ field.value_field.description FILTER html %] is set to:
+ </label>
+ </th>
+ <td>
+ <select name="visibility_value_id" id="visibility_value_id">
+ <option></option>
+ [% FOREACH field_value = field.value_field.legal_values %]
+ [% NEXT IF field_value.name == '' %]
+ <option value="[% field_value.id FILTER none %]"
+ [% ' selected="selected"'
+ IF field_value.id == value.visibility_value.id %]>
+ [% IF field.value_field.name == 'component' %]
+ [% field_value.product.name FILTER html %]:
+ [% END %]
+ [% field_value.name FILTER html -%]
+ </option>
+ [% END %]
+ </select>
+ <small>(Leave unset to have this value always appear.)</small>
+ </td>
+ </tr>
+ [% END %]
+ <tr>
+ <th align="right"><label for="is_active">Enabled for [% terms.bugs %]:</label></th>
+ <td><input id="is_active" name="is_active" type="checkbox" value="1"
+ [%+ 'checked="checked"' IF value.is_active %]
+ [%+ 'disabled="disabled"' IF value.is_default OR value.is_static %]>
+ [% IF value.is_default %]
+ This value is selected as default in the parameters for this field. It cannot be disabled.
+ [% ELSIF value.is_static %]
+ This value is non-deletable and cannot be disabled.
+ [% END %]
+ [% IF !(value.is_default OR value.is_static) %]
+ <input id="defined_is_active" name="defined_is_active"
+ type="hidden" value="1">
+ [% END %]
+ </td>
+ </tr>
+ </table>
+ <input type="hidden" name="value" value="[% value.name FILTER html %]">
+ <input type="hidden" name="action" value="update">
+ <input type="hidden" name="field" value="[% field.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="submit" id="update" value="Save Changes">
+</form>
+
+[% PROCESS admin/fieldvalues/footer.html.tmpl
+ no_edit_link = 1 %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/fieldvalues/footer.html.tmpl b/template/en/default/admin/fieldvalues/footer.html.tmpl
new file mode 100644
index 0000000..672e11b
--- /dev/null
+++ b/template/en/default/admin/fieldvalues/footer.html.tmpl
@@ -0,0 +1,48 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # value: string; the value being inserted/edited.
+ # field: object; the field which the value belongs/belonged to.
+ #
+ # no_XXX_link: boolean; if defined, then don't show the corresponding
+ # link. Supported parameters are:
+ #
+ # no_edit_link
+ # no_edit_other_link
+ # no_add_link
+ #%]
+
+<hr>
+
+<p>
+
+[% UNLESS no_add_link %]
+ <a title="Add a value for the '[% field.description FILTER html %]' field."
+ href="editvalues.cgi?action=add&amp;field=
+ [%- field.name FILTER uri %]">Add</a> a value.
+[% END %]
+
+[% IF value.defined && !no_edit_link %]
+ Edit value <a
+ title="Edit value '[% value.name FILTER html %]' for the '
+ [%- field.name FILTER html %]' field"
+ href="editvalues.cgi?action=edit&amp;field=
+ [%- field.name FILTER uri %]&amp;value=
+ [%- value.name FILTER uri %]">
+ '[% value.name FILTER html %]'</a>.
+[% END %]
+
+[% UNLESS no_edit_other_link %]
+ Edit other values for the <a
+ href="editvalues.cgi?field=
+ [%- field.name FILTER uri %]">'[% field.description FILTER html %]'</a> field.
+
+[% END %]
+
+</p>
diff --git a/template/en/default/admin/fieldvalues/list.html.tmpl b/template/en/default/admin/fieldvalues/list.html.tmpl
new file mode 100644
index 0000000..01c5717
--- /dev/null
+++ b/template/en/default/admin/fieldvalues/list.html.tmpl
@@ -0,0 +1,90 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # values: array of hashes having the following properties:
+ # - name: string; The value.
+ # - sortkey: number; The sortkey used to order the value when
+ # displayed to the user in a list.
+ #
+ # field: object; the field we are editing values for.
+ # static: array; list of values which cannot be renamed nor deleted.
+ #%]
+
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+[% title = BLOCK %]Select value for the '[% field.description FILTER html %]'
+ ([% field.name FILTER html %]) field[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+%]
+
+[% edit_contentlink = BLOCK %]editvalues.cgi?action=edit&amp;field=
+ [%- field.name FILTER uri %]&amp;value=%%name%%[% END %]
+[% delete_contentlink = BLOCK %]editvalues.cgi?action=del&amp;field=
+ [%- field.name FILTER uri %]&amp;value=%%name%%[% END %]
+
+
+[% columns = [
+ {
+ name => "name"
+ heading => "Edit field value..."
+ contentlink => edit_contentlink
+ },
+ {
+ name => "sortkey"
+ heading => "Sortkey"
+ },
+ {
+ name => "isactive"
+ heading => "Enabled for $terms.bugs"
+ yesno_field => 1
+ },
+ {
+ name => "action"
+ heading => "Action"
+ content => "Delete"
+ contentlink => delete_contentlink
+ } ]
+%]
+
+
+[% SET overrides.action = {} %]
+[% FOREACH check_value = values %]
+ [% IF check_value.is_static %]
+ [% overrides.action.name.${check_value.name} = {
+ override_content => 1
+ content => "(Non-deletable value)"
+ override_contentlink => 1
+ contentlink => undef
+ }
+ %]
+ [% ELSIF check_value.is_default %]
+ [% overrides.action.name.${check_value.name} = {
+ override_content => 1
+ content => "(Default value)"
+ override_contentlink => 1
+ contentlink => undef
+ }
+ %]
+ [% END %]
+
+[% END %]
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ data = values
+ overrides = overrides
+%]
+
+[% PROCESS admin/fieldvalues/footer.html.tmpl
+ no_edit_other_link = 1
+ %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/fieldvalues/select-field.html.tmpl b/template/en/default/admin/fieldvalues/select-field.html.tmpl
new file mode 100644
index 0000000..099eeba
--- /dev/null
+++ b/template/en/default/admin/fieldvalues/select-field.html.tmpl
@@ -0,0 +1,37 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # fields: Array of hashes. Each hash contains only one key, "name."
+ # The names are the same as the keys from field_descs
+ # (see global/field-descs.html.tmpl).
+ #%]
+
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+[% PROCESS global/header.html.tmpl
+ title = "Edit values for which field?"
+%]
+
+[% columns = [
+ {
+ name => "name"
+ heading => "Edit field values for..."
+ content_use_field = 1
+ contentlink => "editvalues.cgi?field=%%name%%"
+ }
+ ]
+%]
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ data = fields
+%]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/flag-type/confirm-delete.html.tmpl b/template/en/default/admin/flag-type/confirm-delete.html.tmpl
new file mode 100644
index 0000000..70f5efb
--- /dev/null
+++ b/template/en/default/admin/flag-type/confirm-delete.html.tmpl
@@ -0,0 +1,49 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% title = BLOCK %]Confirm Deletion of Flag Type '[% flag_type.name FILTER html %]'[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ doc_section = "flags-overview.html#flags-delete"
+%]
+
+<p>
+ [% IF flag_type.flag_count %]
+ There are [% flag_type.flag_count %] flags of type [% flag_type.name FILTER html %].
+ If you delete this type, those flags will also be deleted.
+ [% END %]
+
+ Note that instead of deleting the type you can
+ <a href="editflagtypes.cgi?action=deactivate&amp;id=[% flag_type.id %]&amp;token=
+ [%- token FILTER html %]">deactivate it</a>,
+ in which case the type [% IF flag_type.flag_count %] and its flags [% END %] will remain
+ in the database but will not appear in the [% terms.Bugzilla %] UI.
+</p>
+
+<table>
+ <tr>
+ <td colspan="2">
+ Do you really want to delete this type?
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a href="editflagtypes.cgi?action=delete&amp;id=[% flag_type.id %]&amp;token=
+ [%- token FILTER html %]">Yes, delete
+ </a>
+ </td>
+ <td align="right">
+ <a href="editflagtypes.cgi">
+ No, don't delete
+ </a>
+ </td>
+ </tr>
+</table>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/flag-type/edit.html.tmpl b/template/en/default/admin/flag-type/edit.html.tmpl
new file mode 100644
index 0000000..ab70e23
--- /dev/null
+++ b/template/en/default/admin/flag-type/edit.html.tmpl
@@ -0,0 +1,265 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS "global/js-products.html.tmpl" %]
+
+[% IF action == "insert" %]
+ [% title = BLOCK %]
+ Create Flag Type for [% type.target_type == "bug" ? terms.Bugs : "Attachments" %]
+ [% IF type.id %]
+ Based on [% type.name FILTER html %]
+ [% END %]
+ [% END %]
+ [% doc_section = "flags-overview.html#flags-create" %]
+[% ELSE %]
+ [% title = BLOCK %]Edit Flag Type [% type.name FILTER html %][% END %]
+ [% doc_section = "flags-overview.html#flags-edit" %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ style = "
+ table#form th { text-align: right; vertical-align: baseline; white-space: nowrap; }
+ table#form td { text-align: left; vertical-align: baseline; }
+ "
+ onload="var f = document.forms['flagtype_properties'];
+ selectProduct(f.product, f.component, null, null, '__Any__');"
+ javascript_urls=["js/productform.js"]
+ doc_section = doc_section
+%]
+
+<form id="flagtype_properties" method="post" action="editflagtypes.cgi">
+ <input type="hidden" name="action" value="[% action FILTER html %]">
+ <input type="hidden" name="can_fully_edit" value="[% can_fully_edit FILTER html %]">
+ <input type="hidden" name="id" value="[% type.id FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="hidden" name="target_type" value="[% type.target_type FILTER html %]">
+ <input type="hidden" name="check_clusions" value="[% check_clusions FILTER none %]">
+ [% FOREACH category = inclusions.values %]
+ <input type="hidden" name="inclusions" value="[% category FILTER html %]">
+ [% END %]
+ [% FOREACH category = exclusions.values %]
+ <input type="hidden" name="exclusions" value="[% category FILTER html %]">
+ [% END %]
+
+ [%# Add a hidden button at the top of the form so that the user pressing "return"
+ # really submit the form, as expected. %]
+ <input type="submit" id="commit" value="Submit" style="display: none;">
+
+ <table id="form" cellspacing="0" cellpadding="4" border="0">
+ <tr>
+ <th>Name:</th>
+ <td>
+ a short name identifying this type.<br>
+ <input type="text" name="name" value="[% type.name FILTER html %]" size="50"
+ maxlength="50" [%- ' disabled="disabled"' UNLESS can_fully_edit %]>
+ </td>
+ </tr>
+
+ <tr>
+ <th>Description:</th>
+ <td>
+ a comprehensive description of this type.<br>
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'description'
+ minrows = 4
+ cols = 80
+ defaultcontent = type.description
+ disabled = !can_fully_edit
+ %]
+ </td>
+ </tr>
+
+ <tr>
+ <th>Category:</th>
+
+ <td>
+ the products/components to which [% type.target_type == "bug" ? terms.bugs : "attachments" %]
+ must (inclusions) or must not (exclusions) belong in order for users
+ to be able to set flags of this type for them.
+ [% UNLESS can_fully_edit %]
+ <p class="warning">This flagtype also applies to some products you are not allowed
+ to edit (and so which are not displayed in the lists below). Your limited privileges
+ means you are only allowed to add and remove this flagtype to/from products you can
+ edit, but not to edit other properties of the flagtype.</p>
+ [% END %]
+ <table>
+ <tr>
+ <td style="vertical-align: top;">
+ <b>Product/Component:</b><br>
+ <select name="product" onchange="selectProduct(this, this.form.component, null, null, '__Any__');">
+ <option value="">__Any__</option>
+ [% FOREACH prod = products %]
+ <option value="[% prod.name FILTER html %]">[% prod.name FILTER html %]</option>
+ [% END %]
+ </select><br>
+ <select name="component">
+ <option value="">__Any__</option>
+ [% FOREACH comp = components %]
+ <option value="[% comp FILTER html %]">[% comp FILTER html %]</option>
+ [% END %]
+ </select><br>
+ <input type="submit" id="categoryAction-include"
+ name="categoryAction-include" value="Include">
+ <input type="submit" id="categoryAction-exclude"
+ name="categoryAction-exclude" value="Exclude">
+ </td>
+ <td style="vertical-align: top;">
+ <b>Inclusions:</b><br>
+ [% PROCESS category_select name="inclusion_to_remove" categories = inclusions %]<br>
+ <input type="submit" id="categoryAction-removeInclusion"
+ name="categoryAction-removeInclusion" value="Remove Inclusion">
+ </td>
+ <td style="vertical-align: top;">
+ <b>Exclusions:</b><br>
+ [% PROCESS category_select name="exclusion_to_remove" categories = exclusions %]<br>
+ <input type="submit" id="categoryAction-removeExclusion"
+ name="categoryAction-removeExclusion" value="Remove Exclusion">
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>Sort Key:</th>
+ <td>
+ a number between 1 and [% constants.MAX_SMALLINT FILTER none %] by which
+ this type will be sorted when displayed to users in a list; ignore if you
+ don't care what order the types appear in or if you want them to appear
+ in alphabetical order.<br>
+ <input type="text" name="sortkey" value="[% type.sortkey || 1 FILTER html %]" size="5"
+ maxlength="5" [% ' disabled="disabled"' UNLESS can_fully_edit %]>
+ </td>
+ </tr>
+
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ <input type="checkbox" id="is_active" name="is_active"
+ [%- ' disabled="disabled"' UNLESS can_fully_edit %]
+ [% " checked" IF type.is_active || !type.is_active.defined %]>
+ <label for="is_active">active (flags of this type appear in the UI and can be set)</label>
+ </td>
+ </tr>
+
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ <input type="checkbox" id="is_requestable" name="is_requestable"
+ [%- ' disabled="disabled"' UNLESS can_fully_edit %]
+ [% " checked" IF type.is_requestable || !type.is_requestable.defined %]>
+ <label for="is_requestable">requestable (users can ask for flags of this type to be set)</label>
+ </td>
+ </tr>
+
+ <tr>
+ <th>CC List:</th>
+ <td>
+ if requestable, who should get carbon copied on email notification of requests.
+ This is a comma-separated list of full e-mail addresses which do not
+ need to be [% terms.Bugzilla %] logins.
+ [% IF Param('emailsuffix') %]
+ Note that the configured emailsuffix
+ <kbd>[% Param('emailsuffix') %]</kbd> will <em>not</em> be appended
+ to these addresses, so you should add it explicitly if so desired.
+ [% END %]<br>
+ <input type="text" name="cc_list" value="[% type.cc_list FILTER html %]" size="80"
+ maxlength="200" [%- ' disabled="disabled"' UNLESS can_fully_edit %]>
+ </td>
+ </tr>
+
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ <input type="checkbox" id="is_requesteeble" name="is_requesteeble"
+ [%- ' disabled="disabled"' UNLESS can_fully_edit %]
+ [% " checked" IF type.is_requesteeble || !type.is_requesteeble.defined %]>
+ <label for="is_requesteeble">specifically requestable (users can ask specific other users
+ to set flags of this type as opposed to just asking the wind)</label>
+ </td>
+ </tr>
+
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ <input type="checkbox" id="is_multiplicable" name="is_multiplicable"
+ [%- ' disabled="disabled"' UNLESS can_fully_edit %]
+ [% " checked" IF type.is_multiplicable || !type.is_multiplicable.defined %]>
+ <label for="is_multiplicable">multiplicable (multiple flags of this type can be set on
+ the same [% type.target_type == "bug" ? terms.bug : "attachment" %])</label>
+ </td>
+ </tr>
+
+ <tr>
+ <th>Grant Group:</th>
+ <td>
+ the group allowed to grant/deny flags of this type
+ (to allow all users to grant/deny these flags, select no group).<br>
+ [% PROCESS group_select selname = "grant_group" %]
+ </td>
+ </tr>
+
+ <tr>
+ <th>Request Group:</th>
+ <td>
+ if flags of this type are requestable, the group allowed to request them
+ (to allow all users to request these flags, select no group).<br>
+ Note that the request group alone has no effect if the grant group is not defined!<br>
+ [% PROCESS group_select selname = "request_group" %]
+ </td>
+ </tr>
+
+ <tr>
+ <th>&nbsp;</th>
+ <td>
+ <input type="submit" id="save" value="[% action == "insert" ? "Create" : "Save Changes" %]">
+ </td>
+ </tr>
+
+ </table>
+
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
+
+
+[%############################################################################%]
+[%# Block for SELECT fields #%]
+[%############################################################################%]
+
+[% BLOCK group_select %]
+ <select name="[% selname %]" id="[% selname %]" [%- ' disabled="disabled"' UNLESS can_fully_edit %]>
+ <option value="">(no group)</option>
+ [% group_found = 0 %]
+ [% FOREACH group = groups %]
+ <option value="[% group.name FILTER html %]"
+ [% IF type.${selname} && type.${selname}.name == group.name %]
+ [% ' selected="selected"' %]
+ [% group_found = 1 %]
+ [% END %]>
+ [%- group.name FILTER html ~%]
+ </option>
+ [% END %]
+ [% IF !group_found && type.${selname}.name %]
+ <option value="[% type.${selname}.name FILTER html %]" selected="selected">
+ [%- type.${selname}.name FILTER html ~%]
+ </option>
+ [% END %]
+ </select>
+[% END %]
+
+[% BLOCK category_select %]
+ <select name="[% name FILTER html %]" multiple="multiple" size="7">
+ [% FOREACH option = categories.keys.sort %]
+ <option value="[% categories.$option FILTER html %]">
+ [% option FILTER html %]
+ </option>
+ [% END %]
+ </select>
+[% END %]
diff --git a/template/en/default/admin/flag-type/list.html.tmpl b/template/en/default/admin/flag-type/list.html.tmpl
new file mode 100644
index 0000000..7a02938
--- /dev/null
+++ b/template/en/default/admin/flag-type/list.html.tmpl
@@ -0,0 +1,159 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS "global/js-products.html.tmpl" %]
+
+[% PROCESS global/header.html.tmpl
+ title = 'Administer Flag Types'
+ style = "
+ table#flag_types_bugs tr th,
+ table#flag_types_attachments tr th { text-align: left; }
+ .inactive { color: #787878; }
+ .multiplicable { display: block; }
+ "
+ onload="var f = document.flagtype_form; selectProduct(f.product, f.component, null, null, '__All__');"
+ javascript_urls=["js/productform.js"]
+ doc_section = "flags-overview.html#flag-types"
+%]
+
+<p>
+ Flags are markers that identify whether [% terms.abug %] or attachment has been granted
+ or denied some status. Flags appear in the UI as a name and a status symbol
+ ("+" for granted, "-" for denied, and "?" for statuses requested by users).
+</p>
+
+<p>
+ For example, you might define a "review" status for users to request review
+ for their patches. When a patch writer requests review, the string "review?"
+ will appear in the attachment. When a patch reviewer reviews the patch,
+ either the string "review+" or the string "review-" will appear in the patch,
+ depending on whether the patch passed or failed review.
+</p>
+
+<p>
+ You can restrict the list of flag types to those available for a given product
+ and component. If a product is selected with no component, only flag types
+ which are available to at least one component of the product are shown.
+</p>
+
+<form id="flagtype_form" name="flagtype_form" action="editflagtypes.cgi" method="get">
+ <table>
+ <tr>
+ <th><label for="product">Product:</label></th>
+ <td>
+ <select name="product" onchange="selectProduct(this, this.form.component, null, null, '__Any__');">
+ <option value="">__Any__</option>
+ [% FOREACH prod = products %]
+ <option value="[% prod.name FILTER html %]"
+ [% " selected" IF selected_product == prod.name %]>
+ [% prod.name FILTER html %]</option>
+ [% END %]
+ </select>
+ </td>
+ <th><label for="component">Component:</label></th>
+ <td>
+ <select name="component">
+ <option value="">__Any__</option>
+ [% FOREACH comp = components %]
+ <option value="[% comp FILTER html %]"
+ [% " selected" IF selected_component == comp %]>
+ [% comp FILTER html %]</option>
+ [% END %]
+ </select>
+ </td>
+ <td>
+ <input type="checkbox" id="show_flag_counts" name="show_flag_counts" value="1"
+ [%+ 'checked="checked"' IF show_flag_counts %]>
+ <label for="show_flag_counts">Show flag counts</label>
+ </td>
+ <td><input type="submit" id="submit" value="Filter"></td>
+ </tr>
+ </table>
+</form>
+
+<h3>Flag Types for [% terms.Bugs %]</h3>
+
+[% PROCESS display_flag_types types=bug_types types_id='bugs' %]
+
+<p>
+ <a href="editflagtypes.cgi?action=enter&amp;target_type=bug">Create Flag Type for [% terms.Bugs %]</a>
+</p>
+
+<h3>Flag Types for Attachments</h3>
+
+[% PROCESS display_flag_types types=attachment_types types_id='attachments' %]
+
+<p>
+ <a href="editflagtypes.cgi?action=enter&amp;target_type=attachment">Create Flag Type For Attachments</a>
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
+
+
+[% BLOCK display_flag_types %]
+ <table id="flag_types_[% types_id FILTER html %]" cellspacing="0" cellpadding="4" border="1">
+
+ <tr>
+ <th>Edit name ...</th>
+ <th>Description</th>
+ <th>Sortkey</th>
+ <th>Properties</th>
+ <th>Grant group</th>
+ <th>Request group</th>
+ [% IF show_flag_counts %]
+ <th>Flags</th>
+ [%# Note to translators: translate the strings in quotes only. %]
+ [% state_desc = {granted = 'granted' denied = 'denied' pending = 'pending'} %]
+ [% END %]
+ <th>Actions</th>
+ </tr>
+
+ [% FOREACH type = types %]
+
+ <tr class="[% IF type.is_active %]active[% ELSE %]inactive[% END %]">
+ <td><a href="editflagtypes.cgi?action=edit&amp;id=[% type.id %]">[% type.name FILTER html FILTER no_break %]</a></td>
+ <td>[% type.description FILTER html %]</td>
+ <td align="right">[% type.sortkey FILTER html %]</td>
+ <td>
+ [% IF type.is_requestable %]
+ <span class="requestable">requestable</span>
+ [% END %]
+ [% IF type.is_requestable && type.is_requesteeble %]
+ <span class="requesteeble">(specifically)</span>
+ [% END %]
+ [% IF type.is_multiplicable %]
+ <span class="multiplicable">multiplicable</span>
+ [% END %]
+ </td>
+ <td>[% IF type.grant_group %][% type.grant_group.name FILTER html %][% END %]</td>
+ <td>[% IF type.request_group %][% type.request_group.name FILTER html %][% END %]</td>
+ [% IF show_flag_counts %]
+ <td>
+ [% FOREACH state = ['granted', 'pending', 'denied'] %]
+ [% bug_list = bug_lists.${type.id}.$state || [] %]
+ [% IF bug_list.size %]
+ <a href="buglist.cgi?bug_id=[% bug_list.unique.nsort.join(",") FILTER html %]">
+ [% bug_list.size FILTER html %] [%+ state_desc.$state FILTER html %]
+ </a>
+ <br>
+ [% ELSE %]
+ 0 [% state_desc.$state FILTER html %]<br>
+ [% END %]
+ [% END %]
+ </td>
+ [% END %]
+ <td>
+ <a href="editflagtypes.cgi?action=copy&amp;id=[% type.id %]">Copy</a>
+ | <a href="editflagtypes.cgi?action=confirmdelete&amp;id=[% type.id %]">Delete</a>
+ </td>
+ </tr>
+
+ [% END %]
+
+ </table>
+[% END %]
diff --git a/template/en/default/admin/groups/confirm-remove.html.tmpl b/template/en/default/admin/groups/confirm-remove.html.tmpl
new file mode 100644
index 0000000..a9aa7e1
--- /dev/null
+++ b/template/en/default/admin/groups/confirm-remove.html.tmpl
@@ -0,0 +1,50 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # group: The Bugzilla::Group being changed.
+ # regexp: the regexp according to which the update is performed.
+ #%]
+
+[% IF regexp %]
+ [% title = "Confirm: Remove Explicit Members in the Regular Expression?" %]
+[% ELSE %]
+ [% title = "Confirm: Remove All Explicit Members?" %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ doc_section = "groups.html"
+%]
+
+[% IF regexp %]
+ <p>This option will remove all users from '[% group.name FILTER html %]'
+ whose login names match the regular expression:
+ '[% regexp FILTER html %]'</p>
+[% ELSE %]
+ <p>This option will remove all explicitly defined users
+ from '[% group.name FILTER html %].'</p>
+[% END %]
+
+<p>Generally, you will only need to do this when upgrading groups
+ created with [% terms.Bugzilla %] versions 2.16 and earlier. Use
+ this option with <b>extreme care</b> and consult the documentation
+ for further information.
+</p>
+
+<form method="post" action="editgroups.cgi">
+ <input type="hidden" name="group_id" value="[% group.id FILTER html %]">
+ <input type="hidden" name="regexp" value="[% regexp FILTER html %]">
+ <input type="hidden" name="action" value="remove_regexp">
+
+ <input name="token" type="hidden" value="[% token FILTER html %]">
+ <input id="confirm" name="confirm" type="submit" value="Confirm">
+ <p>Or <a href="editgroups.cgi">return to the Edit Groups page</a>.</p>
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/groups/create.html.tmpl b/template/en/default/admin/groups/create.html.tmpl
new file mode 100644
index 0000000..db65629
--- /dev/null
+++ b/template/en/default/admin/groups/create.html.tmpl
@@ -0,0 +1,94 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # none
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Add group"
+ subheader = "This page allows you to define a new user group."
+ doc_section = "groups.html#create-groups"
+%]
+
+<form method="post" action="editgroups.cgi">
+ <table border="1" cellpadding="4" cellspacing="0"><tr>
+ <th>New Name</th>
+ <th>New Description</th>
+ <th>New User RegExp</th>
+ <th>Use For [% terms.Bugs %]</th>
+ </tr><tr>
+ <td><input size="20" name="name"></td>
+ <td><input size="40" name="desc"></td>
+ <td><input size="30" name="regexp"></td>
+ <td><input type="checkbox" name="isactive" value="1" checked></td>
+ </tr>
+ <tr>
+ <th>Icon URL:</th>
+ <td colspan="3"><input type="text" size="70" maxlength="255" id="icon_url" name="icon_url"></td>
+ </tr>
+ [% Hook.process('field') %]
+ </table>
+
+ <hr>
+
+ <input type="checkbox" id="insertnew" name="insertnew" value="1"
+ [% IF Param("makeproductgroups") %] checked[% END %]>
+ <label for="insertnew">Insert new group into all existing products.</label>
+ <p>
+ <input type="submit" id="create" value="Add">
+ <input type="hidden" name="action" value="new">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+</form>
+
+<p><b>Name</b> is what is used with the B<!-- blah -->ugzilla->user->in_group()
+function in any customized cgi files you write that use a given group.
+It can also be used by people submitting [% terms.bugs %] by email to
+limit [% terms.abug %] to a certain set of groups.</p>
+
+<p><b>Description</b> is what will be shown in the [% terms.bug %] reports
+to members of the group where they can choose whether
+the [% terms.bug %] will be restricted to others in the same group.</p>
+
+<p>The <b>Use For [% terms.Bugs %]</b> flag determines whether or not the
+group is eligible to be used for [% terms.bugs %]. If you clear this, it will
+no longer be possible for users to add [% terms.bugs %] to this group,
+although [% terms.bugs %] already in the group will remain in the group.
+Doing so is a much less drastic way to stop a group from growing
+than deleting the group would be. <b>Note: If you are creating
+a group, you probably want it to be usable for [% terms.bugs %], in which
+case you should leave this checked.</b></p>
+
+<p><b>User RegExp</b> is optional, and if filled in, will
+automatically grant membership to this group to anyone with an
+email address that matches this regular expression.</p>
+
+<p>
+ <b>Icon URL</b> is optional, and is the URL pointing to the icon
+ used to identify the group. It may be either a relative URL to the base URL
+ of this installation or an absolute URL. This icon will be displayed
+ in comments in [% terms.bugs %] besides the name of the author of comments.
+</p>
+
+[% IF Param("makeproductgroups") %]
+ <p>By default, the new group will be associated with existing products.
+ Unchecking the "Insert new group into all existing products" option will
+ prevent this and make the group become visible only when its controls have
+ been added to a product.</p>
+[% ELSE %]
+ <p>Checking the "Insert new group into all existing products" option will
+ make the new group be associated with existing products. Leaving it unchecked
+ will make the group become visible only when its controls have been added to
+ a product.</p>
+[% END %]
+
+<p>Back to the <a href="./">main [% terms.bugs %] page</a>
+
+or to the <a href="editgroups.cgi">group list</a>.
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/groups/delete.html.tmpl b/template/en/default/admin/groups/delete.html.tmpl
new file mode 100644
index 0000000..5ae0ce9
--- /dev/null
+++ b/template/en/default/admin/groups/delete.html.tmpl
@@ -0,0 +1,172 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # group: A Bugzilla::Group object representing the group that is
+ # about to be deleted.
+ # shared_queries: int; The number of queries being shared with this
+ # group.
+ #%]
+
+
+[% PROCESS global/header.html.tmpl
+ title = "Delete group"
+ doc_section = "groups.html"
+%]
+
+<table border="1">
+ <tr>
+ <th>Id</th>
+ <th>Name</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>[% group.id FILTER html %]</td>
+ <td>[% group.name FILTER html %]</td>
+ <td>[% group.description FILTER html_light %]</td>
+ </tr>
+</table>
+
+<form method="post" action="editgroups.cgi">
+ [% IF group.members_non_inherited.size %]
+ <p><b>[% group.members_non_inherited.size FILTER html %] users belong
+ directly to this group. You cannot delete this group while there are
+ users in it.</b>
+
+ <br><a href="editusers.cgi?action=list&amp;groupid=
+ [%- group.id FILTER uri %]&amp;grouprestrict=1">Show
+ me which users</a> - <label><input type="checkbox" name="removeusers">Remove
+ all users from this group for me.</label></p>
+ [% END %]
+
+ [% IF group.granted_by_direct(constants.GROUP_MEMBERSHIP).size %]
+ <p><b>Members of this group inherit membership in the following groups:</b></p>
+ <ul>
+ [% FOREACH grantor = group.granted_by_direct(constants.GROUP_MEMBERSHIP) %]
+ <li>[% grantor.name FILTER html %]</li>
+ [% END %]
+ </ul>
+ [% END %]
+
+ [% IF group.bugs.size %]
+ <p><b>[% group.bugs.size FILTER html %] [%+ terms.bug %] reports are
+ visible only to this group. You cannot delete this group while any
+ [%+ terms.bugs %] are using it.</b>
+
+ <br><a href="buglist.cgi?field0-0-0=bug_group&amp;type0-0-0=equals&amp;value0-0-0=
+ [%- group.name FILTER uri %]">Show me
+ which [% terms.bugs %]</a> -
+ <label><input type="checkbox" name="removebugs">Remove
+ all [% terms.bugs %] from this group restriction for me.</label></p>
+
+ <p><b>NOTE:</b> It's quite possible to make confidential [% terms.bugs %]
+ public by checking this box. It is <B>strongly</B> suggested
+ that you review the [% terms.bugs %] in this group before checking
+ the box.</p>
+ [% END %]
+
+ [% IF group.products.size %]
+ <p><b>This group is tied to the following products:</b></p>
+ [% SET any_hidden = 0 %]
+ <ul>
+ [% FOREACH data = group.products %]
+
+ [% SET active = [] %]
+ [% FOREACH control = data.controls.keys.sort %]
+ [% NEXT IF !data.controls.$control %]
+ [% IF control == 'othercontrol' OR control == 'membercontrol' %]
+ [% SWITCH data.controls.$control %]
+ [% CASE constants.CONTROLMAPMANDATORY %]
+ [% SET type = "Mandatory" %]
+ [% CASE constants.CONTROLMAPSHOWN %]
+ [% SET type = "Shown" %]
+ [% CASE constants.CONTROLMAPDEFAULT %]
+ [% SET type = "Default" %]
+ [% END %]
+ [% active.push("$control: $type") %]
+ [% ELSE %]
+ [% active.push(control) %]
+ [% END %]
+ [% END %]
+
+ [% SET hidden = 0 %]
+ [% IF data.controls.othercontrol == constants.CONTROLMAPMANDATORY
+ AND data.controls.membercontrol == constants.CONTROLMAPMANDATORY
+ AND data.controls.entry
+ %]
+ [% SET hidden = 1 %]
+ [% END %]
+
+ <li><a href="editproducts.cgi?action=editgroupcontrols&amp;product=
+ [%- data.product.name FILTER uri %]">
+ [%- data.product.name FILTER html %]</a>
+ ([% active.join(', ') FILTER html %])
+ [% IF hidden %]
+ <strong>WARNING: This product is currently hidden.
+ Deleting this group could make this product publicly visible
+ if no other group applies.
+ </strong>
+ [% END %]</li>
+ [% END %]
+ </ul>
+
+ <p><label><input type="checkbox" name="unbind">Delete this group anyway,
+ and remove these controls.</label></p>
+ [% END %]
+
+ [% IF group.flag_types.size %]
+ <p><b>This group restricts who can make changes to flags of certain types.
+ You cannot delete this group while there are flag types using it.</b>
+
+ <br><a href="editflagtypes.cgi?action=list&amp;group=
+ [%- group.id FILTER uri %]">Show
+ me which types</a> -
+ <label><input type="checkbox" name="removeflags">Remove all
+ flag types from this group for me.</label></p>
+ [% END %]
+
+ [% IF shared_queries %]
+ <p>
+ <b>There
+ [% IF shared_queries > 1 %]
+ are [% shared_queries %] saved searches
+ [% ELSE %]
+ is a saved search
+ [% END %]
+ being shared with this group.</b>
+ If you delete this group,
+ [% IF shared_queries > 1 %]
+ these saved searches
+ [% ELSE %]
+ this saved search
+ [% END %]
+ will fall back to being private again.
+ </p>
+ [% END %]
+
+ <h2>Confirmation</h2>
+
+ <p>Do you really want to delete this group?</p>
+ [% IF group.users.size || group.bugs.size || group.products.size
+ || group.flags.size
+ %]
+ <p><b>You must check all of the above boxes or correct the
+ indicated problems first before you can proceed.</b></p>
+ [% END %]
+
+ <p>
+ <input type="submit" id="delete" value="Yes, delete">
+ <input type="hidden" name="action" value="delete">
+ <input type="hidden" name="group" value="[% group.id FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ </p>
+</form>
+
+Go back to the <a href="editgroups.cgi">group list</a>.
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/groups/edit.html.tmpl b/template/en/default/admin/groups/edit.html.tmpl
new file mode 100644
index 0000000..2f4101a
--- /dev/null
+++ b/template/en/default/admin/groups/edit.html.tmpl
@@ -0,0 +1,233 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # group - A Bugzilla::Group representing the group being edited.
+ # *_current - Arrays of Bugzilla::Group objects that show the current
+ # values for this group, as far as grants.
+ # *_available - Arrays of Bugzilla::Group objects that show the current
+ # available values for each grant.
+ #%]
+
+[% title = BLOCK %]Change Group: [% group.name FILTER html %][% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ doc_section = "groups.html#edit-groups"
+ style = "
+ .grant_table { border-collapse: collapse; }
+ .grant_table td, .grant_table th {
+ padding-left: .5em;
+ }
+ .grant_table td.one, .grant_table th.one {
+ border-right: 1px solid black;
+ padding-right: .5em;
+ }
+ "
+%]
+
+<form method="post" action="editgroups.cgi">
+ <input type="hidden" name="action" value="postchanges">
+ <input type="hidden" name="group_id" value="[% group.id FILTER html %]">
+
+ <table border="1" cellpadding="4">
+ <tr>
+ <th>Group:</th>
+ <td>
+ [% IF group.is_bug_group %]
+ <input type="text" name="name" size="60"
+ value="[% group.name FILTER html %]">
+ [% ELSE %]
+ [% group.name FILTER html %]
+ [% END %]
+ </td>
+ </tr>
+
+ <tr>
+ <th>Description:</th>
+ <td>
+ [% IF group.is_bug_group %]
+ <input type="text" name="desc" size="70"
+ value="[% group.description FILTER html %]">
+ [% ELSE %]
+ [% group.description FILTER html %]
+ [% END %]
+ </td>
+ </tr>
+
+ <tr>
+ <th>User Regexp:</th>
+ <td>
+ <input type="text" name="regexp" size="40"
+ value="[% group.user_regexp FILTER html %]">
+ </td>
+ </tr>
+
+ <tr>
+ <th>
+ Icon URL:
+ [% IF group.icon_url %]
+ <img src="[% group.icon_url FILTER html %]" alt="[% group.name FILTER html %]">
+ [% END %]
+ </th>
+ <td>
+ <input type="text" name="icon_url" size="70" maxlength="255"
+ value="[% group.icon_url FILTER html %]">
+ </td>
+ </tr>
+
+ [% IF group.is_bug_group %]
+ <tr>
+ <th>Use For [% terms.Bugs %]:</th>
+ <td>
+ <input type="checkbox" name="isactive"
+ value="1" [% 'checked="checked"' IF group.is_active %]>
+ </td>
+ </tr>
+ [% END %]
+ [% Hook.process('field') %]
+ </table>
+
+ <h4>Group Permissions</h4>
+
+ <table class="grant_table">
+ <tr>
+ <th class="one">Groups That Are a Member of This Group<br>
+ (&quot;Users in <var>X</var> are automatically in
+ [%+ group.name FILTER html %]&quot;)</th>
+ <th>Groups That This Group Is a Member Of<br>
+ (&quot;If you are in [% group.name FILTER html %], you are
+ automatically also in...&quot;)</th>
+ </tr>
+ <tr>
+ <td class="one">
+ [% PROCESS select_pair name = "members" size = 10
+ items_available = members_available
+ items_current = members_current %]
+ </td>
+
+ <td>[% PROCESS select_pair name = "member_of" size = 10
+ items_available = member_of_available
+ items_current = member_of_current %]</td>
+ </tr>
+ </table>
+
+ <table class="grant_table">
+ <tr>
+ <th class="one">
+ Groups That Can Grant Membership in This Group<br>
+ (&quot;Users in <var>X</var> can add other users to
+ [%+ group.name FILTER html %]&quot;)
+
+ </th>
+ <th>Groups That This Group Can Grant Membership In<br>
+ (&quot;Users in [% group.name FILTER html %] can add users to...&quot;)
+ </th>
+ </tr>
+ <tr>
+ <td class="one">
+ [% PROCESS select_pair name = "bless_from" size = 10
+ items_available = bless_from_available
+ items_current = bless_from_current %]
+ </td>
+ <td>[% PROCESS select_pair name = "bless_to" size = 10
+ items_available = bless_to_available
+ items_current = bless_to_current %]
+ </td>
+ </tr>
+ </table>
+
+ [% IF Param('usevisibilitygroups') %]
+ <table class="grant_table">
+ <tr>
+ <th class="one">
+ Groups That Can See This Group<br>
+ (&quot;Users in <var>X</var> can see users in
+ [%+ group.name FILTER html %]&quot;)
+ </th>
+ <th>Groups That This Group Can See<br>
+ (&quot;Users in [% group.name FILTER html %] can see users in...&quot;)
+ </th>
+ </tr>
+ <tr>
+ <td class="one">
+ [% PROCESS select_pair name = "visible_from" size = 10
+ items_available = visible_from_available
+ items_current = visible_from_current %]
+ </td>
+ <td>[% PROCESS select_pair name = "visible_to_me" size = 10
+ items_available = visible_to_me_available
+ items_current = visible_to_me_current %]
+ </td>
+ </tr>
+ </table>
+ [% END %]
+
+ <input type="submit" id="update-group" value="Update Group">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+</form>
+
+<h4>Mass Remove</h4>
+
+<p>You can use this form to do mass-removal of users from groups.
+ This is often very useful if you upgraded from [% terms.Bugzilla %]
+ 2.16.</p>
+
+<table><tr><td>
+<form method="post" action="editgroups.cgi">
+ <fieldset>
+ <legend>Remove all explicit memberships from users whose login names
+ match the following regular expression:</legend>
+ <input type="text" size="20" name="regexp">
+ <input type="submit" id="remove-membership" value="Remove Memberships">
+
+ <p>If you leave the field blank, all explicit memberships in
+ this group will be removed.</p>
+
+ <input type="hidden" name="action" value="confirm_remove">
+ <input type="hidden" name="group_id" value="[% group.id FILTER html %]">
+ </fieldset>
+</form>
+</td></tr></table>
+
+<p>Back to the <a href="editgroups.cgi">group list</a>.</p>
+
+[% PROCESS global/footer.html.tmpl %]
+
+[% BLOCK select_pair %]
+ <table class="select_pair">
+ <tr>
+ <th><label for="[% "${name}_add" FILTER html %]">Add<br>
+ (select to add)</label></th>
+ <th><label for="[% "${name}_remove" FILTER html %]">Current<br>
+ (select to remove)</label></th>
+ </tr>
+ <tr>
+ <td>
+ <select multiple="multiple" size="[% size FILTER html %]"
+ name="[% "${name}_add" FILTER html %]"
+ id="[% "${name}_add" FILTER html %]">
+ [% FOREACH item = items_available %]
+ <option value="[% item.id FILTER html %]">
+ [% item.name FILTER html %]</option>
+ [% END %]
+ </select>
+ </td>
+ <td>
+ <select multiple="multiple" size="[% size FILTER html %]"
+ name="[% "${name}_remove" FILTER html %]"
+ id="[% "${name}_remove" FILTER html %]">
+ [% FOREACH item = items_current %]
+ <option value="[% item.id FILTER html %]">
+ [% item.name FILTER html %]</option>
+ [% END %]
+ </select>
+ </td>
+ </tr>
+ </table>
+[% END %]
diff --git a/template/en/default/admin/groups/list.html.tmpl b/template/en/default/admin/groups/list.html.tmpl
new file mode 100644
index 0000000..af7da33
--- /dev/null
+++ b/template/en/default/admin/groups/list.html.tmpl
@@ -0,0 +1,153 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # groups: array with group objects having the properties:
+ # - id: number. The ID of the group.
+ # - name: string. The name of the group.
+ # - description: string. The description of the group.
+ # - userregexp: string. The user regexp for the given group.
+ # - isactive: boolean int. Specifies if the group is active or not.
+ # - isbuggroup: boolean int. Specifies if it can be used for bugs.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Edit Groups"
+ subheader = "This lets you edit the groups available to put users in."
+ doc_section = "groups.html"
+%]
+
+[% edit_contentlink = "editgroups.cgi?action=changeform&amp;group=%%id%%" %]
+[% del_contentlink = "editgroups.cgi?action=del&amp;group=%%id%%" %]
+
+[% columns =
+ [{name => 'name'
+ heading => 'Name'
+ contentlink => edit_contentlink
+ }
+ {name => 'description'
+ heading => 'Description'
+ allow_html_content => 1
+ }
+ {name => 'userregexp'
+ heading => 'User RegExp'
+ }
+ {name => 'is_active_bug_group'
+ heading => "Use For $terms.Bugs"
+ align => 'center'
+ }
+ {name => 'type'
+ heading => 'Type'
+ align => 'center'
+ }
+ {name => 'action'
+ heading => 'Action'
+ }
+ ]
+%]
+
+[% overrides.is_active_bug_group = {
+ 'is_active_bug_group' => {
+ "0" => {
+ override_content => 1
+ content => "&nbsp;"
+ }
+ "1" => {
+ override_content => 1
+ content => "X"
+ }
+ }
+ }
+
+ overrides.userregexp = {
+ 'userregexp' => {
+ "" => {
+ override_content => 1
+ content => "&nbsp;"
+ }
+ }
+ }
+%]
+
+[% FOREACH group IN ["chartgroup", "insidergroup", "timetrackinggroup", "querysharegroup"] %]
+ [% special_group = Param(group) %]
+
+ [% IF special_group %]
+ [% overrides.action.name.$special_group = {
+ override_content => 1
+ content => "(used as the '$group')"
+ }
+ %]
+ [% END %]
+[% END %]
+
+[% overrides.action.isbuggroup = {
+ "1" => {
+ override_content => 1
+ content => "Delete"
+ override_contentlink => 1
+ contentlink => del_contentlink
+ }
+ }
+
+ overrides.type.isbuggroup = {
+ "0" => {
+ override_content => 1
+ content => "system"
+ }
+ "1" => {
+ override_content => 1
+ content => "user"
+ }
+ }
+%]
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ data = groups
+ overrides = overrides
+%]
+
+<p><a href="editgroups.cgi?action=add">Add Group</a></p>
+
+<p>
+ <b>Name</b> is what is used with the B<!-- blah -->ugzilla->user->in_group()
+function in any customized cgi files you write that use a given group.
+It can also be used by people submitting [% terms.bugs %] by email to
+limit [% terms.abug %] to a certain set of groups.
+</p>
+
+<p>
+ <b>Description</b> is what will be shown in the [% terms.bug %] reports
+to members of the group where they can choose whether the [% terms.bug %]
+will be restricted to others in the same group.
+</p>
+
+<p>
+ <b>User RegExp</b> is optional, and if filled in, will automatically
+grant membership to this group to anyone with an email address
+that matches this perl regular expression. Do not forget
+the trailing '$'. Example '@mycompany\.com$'
+</p>
+
+<p>
+ The <b>Use For [% terms.Bugs %]</b> flag determines whether or not
+the group is eligible to be used for [% terms.bugs %]. If you remove
+this flag, it will no longer be possible for users to add [% terms.bugs %]
+to this group, although [% terms.bugs %] already in the group will remain
+in the group. Doing so is a much less drastic way to stop a group
+from growing than deleting the group as well as a way to maintain
+lists of users without cluttering the lists of groups used
+for [% terms.bug %] restrictions.
+</p>
+
+<p>
+ The <b>Type</b> field identifies system groups.
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/keywords/confirm-delete.html.tmpl b/template/en/default/admin/keywords/confirm-delete.html.tmpl
new file mode 100644
index 0000000..718a32e
--- /dev/null
+++ b/template/en/default/admin/keywords/confirm-delete.html.tmpl
@@ -0,0 +1,39 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # keyword: A Bugzilla::Keyword object.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Delete Keyword"
+%]
+
+<p>
+ [% IF keyword.bug_count == 1 %]
+ There is one [% terms.bug %] with this keyword set.
+ [% ELSIF keyword.bug_count > 1 %]
+ There are [% keyword.bug_count FILTER html %] [%+ terms.bugs %] with
+ this keyword set.
+ [% END %]
+
+ Are you <b>sure</b> you want to delete
+ the <code>[% keyword.name FILTER html %]</code> keyword?
+</p>
+
+<form method="post" action="editkeywords.cgi">
+ <input type="hidden" name="id" value="[% keyword.id FILTER html %]">
+ <input type="hidden" name="action" value="delete">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="submit" id="delete"
+ value="Yes, really delete the keyword">
+</form>
+
+<p><a href="editkeywords.cgi">Edit other keywords</a>.</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/keywords/create.html.tmpl b/template/en/default/admin/keywords/create.html.tmpl
new file mode 100644
index 0000000..e29db40
--- /dev/null
+++ b/template/en/default/admin/keywords/create.html.tmpl
@@ -0,0 +1,45 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # none
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Add keyword"
+ subheader = "This page allows you to add a new keyword."
+%]
+
+<form method="post" action="editkeywords.cgi">
+ <table border="0" cellpadding="4" cellspacing="0">
+ <tr>
+ <th align="right">Name:</th>
+ <td><input size="64" maxlength="64" name="name" value=""></td>
+ </tr>
+ <tr>
+ <th align="right">Description:</th>
+ <td>
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'description'
+ minrows = 4
+ cols = 64
+ wrap = 'virtual'
+ %]
+ </td>
+ </tr>
+ </table>
+ <hr>
+ <input type="hidden" name="id" value="-1">
+ <input type="submit" id="create" value="Add">
+ <input type="hidden" name="action" value="new">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+</form>
+
+<p><a href="editkeywords.cgi">Edit other keywords</a>.</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/keywords/edit.html.tmpl b/template/en/default/admin/keywords/edit.html.tmpl
new file mode 100644
index 0000000..07603e1
--- /dev/null
+++ b/template/en/default/admin/keywords/edit.html.tmpl
@@ -0,0 +1,57 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # keyword: A Bugzilla::Keyword object.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Edit keyword"
+%]
+
+<form method="post" action="editkeywords.cgi">
+ <table border="0" cellpadding="4" cellspacing="0">
+ <tr>
+ <th align="right">Name:</th>
+ <td><input size="64" maxlength="64" name="name"
+ value="[% keyword.name FILTER html %]"></td>
+ </tr>
+ <tr>
+ <th align="right">Description:</th>
+ <td>
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'description'
+ minrows = 4
+ cols = 64
+ wrap = 'virtual'
+ defaultcontent = keyword.description
+ %]
+ </td>
+ </tr>
+ <tr>
+ <th align="right">[% terms.Bugs %]:</th>
+ <td>
+ [% IF keyword.bug_count > 0 %]
+ <a href="buglist.cgi?keywords=[% keyword.name FILTER uri %]">
+ [% keyword.bug_count FILTER html %]</a>
+ [% ELSE %]
+ none
+ [% END %]
+ </td>
+ </tr>
+ </table>
+
+ <input type="submit" id="update" value="Save Changes">
+ <input type="hidden" name="action" value="update">
+ <input type="hidden" name="id" value="[% keyword.id FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+</form>
+
+<p><a href="editkeywords.cgi">Edit other keywords</a>.</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/keywords/list.html.tmpl b/template/en/default/admin/keywords/list.html.tmpl
new file mode 100644
index 0000000..ea98ca7
--- /dev/null
+++ b/template/en/default/admin/keywords/list.html.tmpl
@@ -0,0 +1,54 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # keywords: array keyword objects having the properties:
+ # - id: number. The ID of the keyword.
+ # - name: string. The name of the keyword.
+ # - description: string. The description of the keyword.
+ # - bug_count: number. The number of bugs with the keyword.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Select keyword"
+%]
+
+[% columns = [
+ {
+ name => "name"
+ heading => "Edit keyword..."
+ contentlink => "editkeywords.cgi?action=edit&amp;id=%%id%%"
+ },
+ {
+ name => "description"
+ heading => "Description"
+ allow_html_content => 1
+ },
+ {
+ name => "bug_count"
+ heading => "$terms.Bugs"
+ align => "right"
+ contentlink => "buglist.cgi?keywords=%%name%%"
+ },
+ {
+ heading => "Action"
+ content => "Delete"
+ contentlink => "editkeywords.cgi?action=del&amp;id=%%id%%"
+ }
+ ]
+%]
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ data = keywords
+ footer = footer_row
+%]
+
+<p><a href="editkeywords.cgi?action=add">Add a new keyword</a></p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/milestones/confirm-delete.html.tmpl b/template/en/default/admin/milestones/confirm-delete.html.tmpl
new file mode 100644
index 0000000..cc30f16
--- /dev/null
+++ b/template/en/default/admin/milestones/confirm-delete.html.tmpl
@@ -0,0 +1,83 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: object; Bugzilla::Product object representing the product to
+ # which the milestone belongs.
+ # milestone: object; Bugzilla::Milestone object representing the
+ # milestone the user wants to delete.
+ #%]
+
+[% title = BLOCK %]Delete Milestone of Product '[% product.name FILTER html %]'
+ [% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+%]
+
+<table border="1" cellpadding="4" cellspacing="0">
+<tr bgcolor="#6666FF">
+ <th valign="top" align="left">Field</th>
+ <th valign="top" align="left">Value</th>
+</tr>
+<tr>
+ <td valign="top">Milestone:</td>
+ <td valign="top">[% milestone.name FILTER html %]</td>
+</tr>
+<tr>
+ <td valign="top">Milestone of Product:</td>
+ <td valign="top">[% product.name FILTER html %]</td>
+</tr>
+<tr>
+ <td valign="top">[% terms.Bugs %]:</td>
+ <td valign="top">
+[% IF milestone.bug_count %]
+ <a title="List of [% terms.bugs %] targetted at milestone '
+ [% milestone.name FILTER html %]'"
+ href="buglist.cgi?target_milestone=[% milestone.name FILTER uri %]&amp;product=
+ [%- product.name FILTER uri %]">
+ [% milestone.bug_count FILTER none %]</a>
+[% ELSE %]
+ None
+[% END %]
+ </td>
+</tr>
+</table>
+
+<h2>Confirmation</h2>
+
+[% IF milestone.bug_count %]
+
+ <p class="confirmation">
+ There
+ [% IF milestone.bug_count > 1 %]
+ are [% milestone.bug_count FILTER none %] [%+ terms.bugs %]
+ [% ELSE %]
+ is 1 [% terms.bug %]
+ [% END %]
+ entered for this milestone! When you delete this milestone,
+ <b>ALL</b> of these [% terms.bugs %] will be retargeted
+ to [% product.default_milestone FILTER html %], the default milestone for
+ the [% product.name FILTER html %] product.
+ </p>
+[% END %]
+
+<p>Do you really want to delete this milestone?<p>
+
+<form method="post" action="editmilestones.cgi">
+ <input type="submit" id="delete" value="Yes, delete">
+ <input type="hidden" name="action" value="delete">
+ <input type="hidden" name="product" value="[% product.name FILTER html %]">
+ <input type="hidden" name="milestone" value="[% milestone.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+</form>
+
+[% PROCESS admin/milestones/footer.html.tmpl %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/milestones/create.html.tmpl b/template/en/default/admin/milestones/create.html.tmpl
new file mode 100644
index 0000000..8006c0c
--- /dev/null
+++ b/template/en/default/admin/milestones/create.html.tmpl
@@ -0,0 +1,46 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: object; Bugzilla::Product object representing the product to
+ # which the milestone belongs.
+ #%]
+
+[% title = BLOCK %]Add Milestone to Product '[% product.name FILTER html %]'[% END %]
+[% subheader = BLOCK %]This page allows you to add a new milestone to product
+ '[% product.name FILTER html %]'.[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+ subheader = subheader
+ onload = "document.forms['f'].milestone.focus()"
+%]
+
+<form name="f" method="post" action="editmilestones.cgi">
+ <table border="0" cellpadding="4" cellspacing="0">
+ <tr>
+ <th align="right"><label for="milestone">Milestone:</label></th>
+ <td><input id="milestone" size="64" maxlength="64" name="milestone"
+ value=""></td>
+ </tr>
+ <tr>
+ <th align="right"><label for="sortkey">Sortkey:</label></th>
+ <td><input id="sortkey" size="20" maxlength="20" name="sortkey"
+ value=""></td>
+ </tr>
+ </table>
+ <input type="submit" id="create" value="Add">
+ <input type="hidden" name="action" value="new">
+ <input type="hidden" name='product' value="[% product.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+</form>
+
+[% PROCESS admin/milestones/footer.html.tmpl
+ no_add_milestone_link = 1
+ %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/milestones/edit.html.tmpl b/template/en/default/admin/milestones/edit.html.tmpl
new file mode 100644
index 0000000..759bd70
--- /dev/null
+++ b/template/en/default/admin/milestones/edit.html.tmpl
@@ -0,0 +1,53 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: object; Bugzilla::Product object representing the product to
+ # which the milestone belongs.
+ # milestone: object; Bugzilla::Milestone object representing the
+ # milestone the user wants to edit.
+ #%]
+
+[% title = BLOCK %]Edit Milestone '[% milestone.name FILTER html %]' of product '
+ [%- product.name FILTER html %]'[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+ onload = "document.forms['f'].milestone.select()"
+%]
+
+<form name="f" method="post" action="editmilestones.cgi">
+ <table border="0" cellpadding="4" cellspacing="0">
+
+ <tr>
+ <th class="field_label"><label for="milestone">Milestone:</label></th>
+ <td><input id="milestone" size="64" maxlength="64" name="milestone" value="
+ [%- milestone.name FILTER html %]"></td>
+ </tr>
+ <tr>
+ <th class="field_label"><label for="sortkey">Sortkey:</label></th>
+ <td><input id="sortkey" size="20" maxlength="20" name="sortkey" value="
+ [%- milestone.sortkey FILTER html %]"></td>
+ </tr>
+ <tr>
+ <th class="field_label"><label for="isactive">Enabled For [% terms.Bugs %]:</label></th>
+ <td><input id="isactive" name="isactive" type="checkbox" value="1"
+ [% 'checked="checked"' IF milestone.isactive %]></td>
+ </tr>
+ </table>
+
+ <input type="hidden" name="milestoneold" value="[% milestone.name FILTER html %]">
+ <input type="hidden" name="action" value="update">
+ <input type="hidden" name="product" value="[% product.name FILTER html %]">
+ <input type="submit" id="update" value="Save Changes">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+</form>
+
+[% PROCESS admin/milestones/footer.html.tmpl
+ no_edit_milestone_link = 1 %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/milestones/footer.html.tmpl b/template/en/default/admin/milestones/footer.html.tmpl
new file mode 100644
index 0000000..10c6f90
--- /dev/null
+++ b/template/en/default/admin/milestones/footer.html.tmpl
@@ -0,0 +1,55 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: object; Bugzilla::Product object representing the product to
+ # which the milestone belongs.
+ #
+ # milestone: object; Bugzilla::Milestone object representing the
+ # milestone.
+ #
+ # no_XXX_link: boolean; if defined, then don't show the corresponding
+ # link. Supported parameters are:
+ #
+ # no_edit_milestone_link
+ # no_edit_other_milestones_link
+ # no_add_milestone_link
+ #%]
+
+<hr>
+
+<p>
+
+[% UNLESS no_add_milestone_link %]
+ <a title="Add a milestone to product '[% product.name FILTER html %]'"
+ href="editmilestones.cgi?action=add&amp;product=
+ [%- product.name FILTER uri %]">Add</a> a milestone.
+[% END %]
+
+[% IF milestone.name && !no_edit_milestone_link %]
+ Edit milestone <a
+ title="Edit Milestone '[% milestone.name FILTER html %]' of product '
+ [%- product.name FILTER html %]'"
+ href="editmilestones.cgi?action=edit&amp;product=
+ [%- product.name FILTER uri %]&amp;milestone=
+ [%- milestone.name FILTER uri %]">
+ '[% milestone.name FILTER html %]'</a>.
+[% END %]
+
+[% UNLESS no_edit_other_milestones_link %]
+ Edit other milestones of product <a
+ href="editmilestones.cgi?product=
+ [%- product.name FILTER uri %]">'[% product.name FILTER html %]'</a>.
+
+[% END %]
+
+ Edit product <a
+ href="editproducts.cgi?action=edit&amp;product=
+ [%- product.name FILTER uri %]">'[% product.name FILTER html %]'</a>.
+
+</p>
diff --git a/template/en/default/admin/milestones/list.html.tmpl b/template/en/default/admin/milestones/list.html.tmpl
new file mode 100644
index 0000000..1638279
--- /dev/null
+++ b/template/en/default/admin/milestones/list.html.tmpl
@@ -0,0 +1,98 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: object; Bugzilla::Product object representing the product to
+ # which the milestones belongs.
+ # showbugcounts: if defined, then bug counts should be included in the table
+ #%]
+
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+[% title = BLOCK %]Select milestone of product
+ '[% product.name FILTER html %]'[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+%]
+
+[% edit_contentlink = BLOCK %]editmilestones.cgi?action=edit&amp;product=
+ [%- product.name FILTER uri %]&amp;milestone=%%name%%[% END %]
+[% delete_contentlink = BLOCK %]editmilestones.cgi?action=del&amp;product=
+ [%- product.name FILTER uri %]&amp;milestone=%%name%%[% END %]
+[% bug_count_contentlink = BLOCK %]buglist.cgi?target_milestone=%%name%%&amp;product=
+ [%- product.name FILTER uri %][% END %]
+
+
+[% columns = [
+ {
+ name => "name"
+ heading => "Edit milestone..."
+ contentlink => edit_contentlink
+ },
+ {
+ name => "sortkey"
+ heading => "Sortkey"
+ },
+ {
+ name => "isactive"
+ heading => "Active"
+ yesno_field => 1
+ }
+ ]
+%]
+
+[% IF showbugcounts %]
+
+ [% columns.push({
+ name => "bug_count"
+ heading => "$terms.Bugs"
+ align => "right"
+ contentlink => bug_count_contentlink
+ })
+ %]
+
+[% END %]
+
+[% columns.push({
+ name => "action"
+ heading => "Action"
+ content => "Delete"
+ contentlink => delete_contentlink
+ })
+%]
+
+[%# We want to override the usual 'Delete' link for the default milestone %]
+[% overrides.action.name.${product.default_milestone} = {
+ override_content => 1
+ content => "(Default milestone)"
+ override_contentlink => 1
+ contentlink => undef
+ }
+%]
+
+[% Hook.process('before_table') %]
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ data = product.milestones
+ overrides = overrides
+%]
+
+[% IF ! showbugcounts %]
+
+ <p><a href="editmilestones.cgi?product=[% product.name FILTER uri %]&amp;showbugcounts=1">
+ Redisplay table with [% terms.bug %] counts (slower)</a></p>
+
+[% END %]
+
+[% PROCESS admin/milestones/footer.html.tmpl
+ no_edit_other_milestones_link = 1
+%]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/milestones/select-product.html.tmpl b/template/en/default/admin/milestones/select-product.html.tmpl
new file mode 100644
index 0000000..18bb88c
--- /dev/null
+++ b/template/en/default/admin/milestones/select-product.html.tmpl
@@ -0,0 +1,54 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # products: array of product objects
+ # showbugcounts: if defined, then bug counts should be included in the table
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Edit milestones for which product?"
+%]
+
+[% columns = [
+ {
+ name => "name"
+ heading => "Edit milestones of..."
+ contentlink => "editmilestones.cgi?product=%%name%%"
+ },
+ {
+ name => "description"
+ heading => "Description"
+ allow_html_content => 1
+ }
+ ]
+%]
+
+[% IF showbugcounts %]
+
+ [% columns.push({
+ name => 'bug_count'
+ heading => "$terms.Bugs"
+ align => "right"
+ contentlink => "buglist.cgi?product=%%name%%"
+ })
+ %]
+
+[% END %]
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ data = products
+%]
+
+[% IF !showbugcounts %]
+ <p><a href="editmilestones.cgi?showbugcounts=1">
+ Redisplay table with [% terms.bug %] counts (slower)</a></p>
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/params/admin.html.tmpl b/template/en/default/admin/params/admin.html.tmpl
new file mode 100644
index 0000000..c63329c
--- /dev/null
+++ b/template/en/default/admin/params/admin.html.tmpl
@@ -0,0 +1,28 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[%
+ title = "Administrative Policies"
+ desc = "Set up account policies"
+%]
+
+[% param_descs = {
+ allowbugdeletion => "The pages to edit products and components can delete all " _
+ "associated $terms.bugs when you delete a product (or component). " _
+ "Since that is a pretty scary idea, you have to turn on " _
+ "this option before any such deletions will ever happen.",
+
+ allowemailchange => "Users can change their own email address through the preferences. " _
+ "Note that the change is validated by emailing both addresses, so " _
+ "switching this option on will not let users use an invalid address.",
+
+ allowuserdeletion => "The user editing pages are capable of letting you delete user accounts. " _
+ "$terms.Bugzilla will issue a warning in case you'd run into inconsistencies " _
+ "when you're about to do so, but such deletions remain kinda scary. " _
+ "So, you have to turn on this option before any such deletions " _
+ "will ever happen." }
+%]
diff --git a/template/en/default/admin/params/advanced.html.tmpl b/template/en/default/admin/params/advanced.html.tmpl
new file mode 100644
index 0000000..076d2dc
--- /dev/null
+++ b/template/en/default/admin/params/advanced.html.tmpl
@@ -0,0 +1,68 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%
+ title = "Advanced"
+ desc = "Settings for advanced configurations."
+%]
+
+[% sts_desc = BLOCK %]
+ Enables the sending of the
+ <a href="http://en.wikipedia.org/wiki/Strict_Transport_Security">Strict-Transport-Security</a>
+ header along with HTTP responses on SSL connections. This adds greater
+ security to your SSL connections by forcing the browser to always
+ access your domain over SSL and never accept an invalid certificate.
+ However, it should only be used if you have the <code>ssl_redirect</code>
+ parameter turned on, [% terms.Bugzilla %] is the only thing running
+ on its domain (i.e., your <code>urlbase</code> is something like
+ <code>http://bugzilla.example.com/</code>), and you never plan to disable
+ the <code>ssl_redirect</code> parameter.
+ <ul>
+ <li>
+ off - Don't send the Strict-Transport-Security header with requests.
+ </li>
+ <li>
+ this_domain_only - Send the Strict-Transport-Security header with all
+ requests, but only support it for the current domain.
+ </li>
+ <li>
+ include_subdomains - Send the Strict-Transport-Security header along
+ with the <code>includeSubDomains</code> flag, which will apply the
+ security change to all subdomains. This is especially useful when
+ combined with an <code>attachment_base</code> that exists as (a)
+ subdomain(s) under the main [% terms.Bugzilla %] domain.
+ </li>
+ </ul>
+[% END %]
+
+[% param_descs = {
+ cookiedomain =>
+ "If your website is at 'www.foo.com', setting this to"
+ _ " '.foo.com' will also allow 'bar.foo.com' to access"
+ _ " $terms.Bugzilla cookies. This is useful if you have more than"
+ _ " one hostname pointing at the same web server, and you"
+ _ " want them to share the $terms.Bugzilla cookie.",
+
+ inbound_proxies =>
+ "When inbound traffic to $terms.Bugzilla goes through a proxy,"
+ _ " $terms.Bugzilla thinks that the IP address of every single"
+ _ " user is the IP address of the proxy. If you enter a comma-separated"
+ _ " list of IPs in this parameter, then $terms.Bugzilla will trust any"
+ _ " <code>X-Forwarded-For</code> header sent from those IPs,"
+ _ " and use the value of that header as the end user's IP address.",
+
+ proxy_url =>
+ "$terms.Bugzilla may have to access the web to get notifications about"
+ _ " new releases (see the <tt>upgrade_notification</tt> parameter)."
+ _ " If your $terms.Bugzilla server is behind a proxy, it may be"
+ _ " necessary to enter its URL if the web server cannot access the"
+ _ " HTTP_PROXY environment variable. If you have to authenticate,"
+ _ " use the <code>http://user:pass@proxy_url/</code> syntax.",
+
+ strict_transport_security => sts_desc,
+} %]
diff --git a/template/en/default/admin/params/attachment.html.tmpl b/template/en/default/admin/params/attachment.html.tmpl
new file mode 100644
index 0000000..c0c32a4
--- /dev/null
+++ b/template/en/default/admin/params/attachment.html.tmpl
@@ -0,0 +1,62 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[%
+ title = "Attachments"
+ desc = "Set up attachment options"
+%]
+
+[% param_descs = {
+ allow_attachment_display =>
+ "If this option is on, users will be able to view attachments from"
+ _ " their browser, if their browser supports the attachment's MIME type."
+ _ " If this option is off, users are forced to download attachments,"
+ _ " even if the browser is able to display them."
+ _ "<p>This is a security restriction for installations where untrusted"
+ _ " users may upload attachments that could be potentially damaging if"
+ _ " viewed directly in the browser.</p>"
+ _ "<p>It is highly recommended that you set the <tt>attachment_base</tt>"
+ _ " parameter if you turn this parameter on.",
+
+ attachment_base =>
+ "When the <tt>allow_attachment_display</tt> parameter is on, it is "
+ _ " possible for a malicious attachment to steal your cookies or"
+ _ " perform an attack on $terms.Bugzilla using your credentials."
+ _ "<p>If you would like additional security on attachments to avoid"
+ _ " this, set this parameter to an alternate URL for your $terms.Bugzilla"
+ _ " that is not the same as <tt>urlbase</tt> or <tt>sslbase</tt>."
+ _ " That is, a different domain name that resolves to this exact"
+ _ " same $terms.Bugzilla installation.</p>"
+ _ "<p>Note that if you have set the"
+ _ " <a href=\"editparams.cgi?section=advanced#cookiedomain_desc\"><tt>cookiedomain</tt>"
+ _" parameter</a>, you should set <tt>attachment_base</tt> to use a"
+ _ " domain that would <em>not</em> be matched by"
+ _ " <tt>cookiedomain</tt>.</p>"
+ _ "<p>For added security, you can insert <tt>%bugid%</tt> into the URL,"
+ _ " which will be replaced with the ID of the current $terms.bug that"
+ _ " the attachment is on, when you access an attachment. This will limit"
+ _ " attachments to accessing only other attachments on the same"
+ _ " ${terms.bug}. Remember, though, that all those possible domain names "
+ _ " (such as <tt>1234.your.domain.com</tt>) must point to this same"
+ _ " $terms.Bugzilla instance.",
+
+ allow_attachment_deletion => "If this option is on, administrators will be able to delete " _
+ "the content of attachments.",
+
+ maxattachmentsize => "The maximum size (in kilobytes) of attachments to be stored " _
+ "in the database. If a file larger than this size is attached " _
+ "to ${terms.abug}, $terms.Bugzilla will look at the " _
+ "<a href=\"#maxlocalattachment\"><tt>maxlocalattachment</tt> parameter</a> " _
+ "to determine if the file can be stored locally on the web server. " _
+ "If the file size exceeds both limits, then the attachment is rejected. " _
+ "Settings both parameters to 0 will prevent attaching files to ${terms.bugs}.",
+
+ maxlocalattachment => "The maximum size (in megabytes) of attachments to be stored " _
+ "locally on the web server. If set to a value lower than the " _
+ "<a href=\"#maxattachmentsize\"><tt>maxattachmentsize</tt> parameter</a>, " _
+ "attachments will never be kept on the local filesystem." }
+%]
diff --git a/template/en/default/admin/params/auth.html.tmpl b/template/en/default/admin/params/auth.html.tmpl
new file mode 100644
index 0000000..0a72938
--- /dev/null
+++ b/template/en/default/admin/params/auth.html.tmpl
@@ -0,0 +1,130 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[%
+ title = "User Authentication"
+ desc = "Set up your authentication policies"
+%]
+
+[% param_descs = {
+ auth_env_id => "Environment variable used by external authentication system " _
+ "to store a unique identifier for each user. Leave it blank " _
+ "if there isn't one or if this method of authentication " _
+ "is not being used.",
+
+ auth_env_email => "Environment variable used by external authentication system " _
+ "to store each user's email address. This is a required " _
+ "field for environmental authentication. Leave it blank " _
+ "if you are not going to use this feature.",
+
+ auth_env_realname => "Environment variable used by external authentication system " _
+ "to store the user's real name. Leave it blank if there " _
+ "isn't one or if this method of authentication is not being " _
+ "used.",
+
+ user_info_class => "Mechanism(s) to be used for gathering a user's login information.
+ More than one may be selected. If the first one returns nothing,
+ the second is tried, and so on.<br>
+ The types are:
+ <dl>
+ <dt>CGI</dt>
+ <dd>
+ Asks for username and password via CGI form interface.
+ </dd>
+ <dt>Env</dt>
+ <dd>
+ Info for a pre-authenticated user is passed in system
+ environment variables.
+ </dd>
+ </dl>",
+
+ user_verify_class => "Mechanism(s) to be used for verifying (authenticating) information
+ gathered by user_info_class.
+ More than one may be selected. If the first one cannot find the
+ user, the second is tried, and so on.<br>
+ The types are:
+ <dl>
+ <dt>DB</dt>
+ <dd>
+ ${terms.Bugzilla}'s built-in authentication. This is the most common
+ choice.
+ </dd>
+ <dt>RADIUS</dt>
+ <dd>
+ RADIUS authentication using a RADIUS server.
+ Please see the $terms.Bugzilla documentation for
+ more information.
+ Using this method requires
+ <a href=\"?section=radius\">additional
+ parameters</a> to be set.
+ </dd>
+ <dt>LDAP</dt>
+ <dd>
+ LDAP authentication using an LDAP server.
+ Please see the $terms.Bugzilla documentation
+ for more information. Using this method requires
+ <a href=\"?section=ldap\">additional
+ parameters</a> to be set.
+ </dd>
+ </dl>",
+
+ rememberlogin => "Controls management of session cookies
+ <ul>
+ <li>
+ on - Session cookies never expire (the user has to login only
+ once per browser).
+ </li>
+ <li>
+ off - Session cookies last until the users session ends (the user
+ will have to login in each new browser session).
+ </li>
+ <li>
+ defaulton/defaultoff - Default behavior as described
+ above, but user can choose whether $terms.Bugzilla will remember his
+ login or not.
+ </li>
+ </ul>",
+
+ requirelogin => "If this option is set, all access to the system beyond the " _
+ "front page will require a login. No anonymous users will " _
+ "be permitted.",
+
+ emailregexp =>
+ "This defines the regular expression to use for legal email addresses. " _
+ "The default tries to match fully qualified email addresses. " _
+ "Use <tt>.*</tt> to accept any email address following the " _
+ "<a href=\"http://tools.ietf.org/html/rfc2822#section-3.4.1\">RFC 2822</a> " _
+ "specification. Another popular value to put here is <tt>^[^@]+$</tt>, " _
+ "which means 'local usernames, no @ allowed.'",
+
+ emailregexpdesc => "This describes in English words what kinds of legal addresses " _
+ "are allowed by the <tt>emailregexp</tt> param.",
+
+ emailsuffix => "This is a string to append to any email addresses when actually " _
+ "sending mail to that address. It is useful if you have changed " _
+ "the <tt>emailregexp</tt> param to only allow local usernames, " _
+ "but you want the mail to be delivered to username@my.local.hostname.",
+
+ createemailregexp => "This defines the (case-insensitive) regexp to use for email addresses that are " _
+ "permitted to self-register using a 'New Account' feature. The " _
+ "default (.*) permits any account matching the emailregexp " _
+ "to be created. If this parameter is left blank, no users " _
+ "will be permitted to create their own accounts and all accounts " _
+ "will have to be created by an administrator.",
+
+ password_complexity =>
+ "Set the complexity required for passwords. In all cases must the passwords " _
+ "be at least ${constants.USER_PASSWORD_MIN_LENGTH} characters long." _
+ "<ul><li>no_constraints - No complexity required.</li>" _
+ "<li>mixed_letters - Passwords must contain at least one UPPER and one lower " _
+ "case letter.</li>" _
+ "<li>letters_numbers - Passwords must contain at least one UPPER and one " _
+ "lower case letter and a number.</li>" _
+ "<li>letters_numbers_specialchars - Passwords must contain at least one " _
+ "letter, a number and a special character.</li></ul>"
+ }
+%]
diff --git a/template/en/default/admin/params/bugchange.html.tmpl b/template/en/default/admin/params/bugchange.html.tmpl
new file mode 100644
index 0000000..f442c59
--- /dev/null
+++ b/template/en/default/admin/params/bugchange.html.tmpl
@@ -0,0 +1,42 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[%
+ title = "$terms.Bug Change Policies"
+ desc = "Set up $terms.bug change policies"
+%]
+
+[% accept_status = display_value('bug_status', 'IN_PROGRESS') FILTER html %]
+
+[% param_descs = {
+ duplicate_or_move_bug_status => "When $terms.abug is marked as a duplicate of another one " _
+ "or is moved to another installation, use this $terms.bug status."
+
+ letsubmitterchoosepriority => "If this is on, then people submitting $terms.bugs can " _
+ "choose an initial priority for that ${terms.bug}. " _
+ "If off, then all $terms.bugs initially have the default " _
+ "priority selected below.",
+
+ letsubmitterchoosemilestone => "If this is on, then people submitting $terms.bugs can " _
+ "choose the Target Milestone for that ${terms.bug}. " _
+ "If off, then all $terms.bugs initially have the default " _
+ "milestone for the product being filed in.",
+
+ musthavemilestoneonaccept =>
+ "If you are using ${field_descs.target_milestone}, do you want to require"
+ _ " that the milestone be set in order for a user to set"
+ _ " ${terms.abug}'s status to ${accept_status}?",
+
+ commentonchange_resolution => "If this option is on, the user needs to enter a short " _
+ "comment if the resolution of the $terms.bug changes.",
+
+ commentonduplicate => "If this option is on, the user needs to enter a short comment " _
+ "if the $terms.bug is marked as duplicate.",
+
+ noresolveonopenblockers => "Don\'t allow $terms.bugs to be resolved as fixed " _
+ "if they have unresolved dependencies." }
+%]
diff --git a/template/en/default/admin/params/bugfields.html.tmpl b/template/en/default/admin/params/bugfields.html.tmpl
new file mode 100644
index 0000000..07b2008
--- /dev/null
+++ b/template/en/default/admin/params/bugfields.html.tmpl
@@ -0,0 +1,45 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[%
+ title = "$terms.Bug Fields"
+ desc = "Choose fields you want to display"
+%]
+
+[% param_descs = {
+ useclassification => "If this is on, $terms.Bugzilla will associate each product with a " _
+ "specific classification. But you must have 'editclassification' " _
+ "permissions enabled in order to edit classifications.",
+
+ usetargetmilestone => "Do you wish to use the Target Milestone field?",
+
+ useqacontact => "Do you wish to use the QA Contact field?",
+
+ usestatuswhiteboard => "Do you wish to use the Status Whiteboard field?",
+
+ use_see_also =>
+ "Do you wish to use the See Also field? It allows you refer to"
+ _ " $terms.bugs in other installations. Even if you disable this field,"
+ _ " $terms.bug relationships (URLs) already set on $terms.bugs will"
+ _ " still appear and can be removed.",
+
+ defaultpriority => "This is the priority that newly entered $terms.bugs are set to.",
+
+ defaultseverity => "This is the severity that newly entered $terms.bugs are set to.",
+
+ defaultplatform => "This is the platform that is preselected on the $terms.bug " _
+ "entry form.<br> " _
+ "You can leave this empty: " _
+ "$terms.Bugzilla will then use the platform that the browser " _
+ "reports to be running on as the default.",
+
+ defaultopsys => "This is the operating system that is preselected on the $terms.bug " _
+ "entry form.<br> " _
+ "You can leave this empty: " _
+ "$terms.Bugzilla will then use the operating system that the browser " _
+ "reports to be running on as the default." }
+%]
diff --git a/template/en/default/admin/params/common.html.tmpl b/template/en/default/admin/params/common.html.tmpl
new file mode 100644
index 0000000..bf2675b
--- /dev/null
+++ b/template/en/default/admin/params/common.html.tmpl
@@ -0,0 +1,125 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% sortlist_separator = '---' %]
+
+<dl>
+ [% FOREACH param = panel.param_list %]
+ <dt id="[% param.name FILTER html %]_desc">[% param.name FILTER html %]</dt>
+ <dd>[% panel.param_descs.${param.name} FILTER none %]
+ <p>
+ [% IF param.type == "t" %]
+ <input type="text" size="80" name="[% param.name FILTER html %]"
+ id="[% param.name FILTER html %]" value="[% Param(param.name) FILTER html %]">
+ [% ELSIF param.type == "p" %]
+ <input type="password" size="80" name="[% param.name FILTER html %]"
+ id="[% param.name FILTER html %]" value="[% Param(param.name) FILTER html %]"
+ autocomplete="off">
+ [% ELSIF param.type == "l" %]
+ <textarea name="[% param.name FILTER html %]" id="[% param.name FILTER html %]"
+ rows="10" cols="80">[% Param(param.name) FILTER html %]</textarea>
+ [% ELSIF param.type == "b" %]
+ <input type="radio" name="[% param.name FILTER html %]" id="[% param.name FILTER html %]-on"
+ value=1 [% "checked=\"checked\"" IF Param(param.name) %]>
+ <label for="[% param.name FILTER html %]-on">On</label>
+ <input type="radio" name="[% param.name FILTER html %]" id="[% param.name FILTER html %]-off"
+ value=0 [% "checked=\"checked\"" IF !Param(param.name) %]>
+ <label for="[% param.name FILTER html %]-off">Off</label>
+ [% ELSIF param.type == "m" %]
+ [% boxSize = 5 %]
+ [% boxSize = param.choices.size IF param.choices.size < 5 %]
+
+ <select multiple="multiple" size="[% boxSize FILTER html %]"
+ name="[% param.name FILTER html %]" id="[% param.name FILTER html %]">
+ [% FOREACH item = param.choices %]
+ <option value="[% item FILTER html %]"
+ [% " selected=\"selected\"" IF lsearch(Param(param.name), item) != -1 %]>
+ [% item FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ [% ELSIF param.type == "o" %]
+ <input id="input_[% param.name FILTER html %]" size="80"
+ name="[% param.name FILTER html %]"
+ value="[% Param(param.name) FILTER html %]"><br>
+ [% boxSize = 7 %]
+ [% boxSize = 3 + param.choices.size IF param.choices.size < 7 %]
+ [% plist = Param(param.name).split(',') %]
+
+ <table id="table_[% param.name FILTER html %]" class="bz_default_hidden">
+ <tr>
+ <td rowspan="2">
+ <select id="select_[% param.name FILTER html %]"
+ name="select_[% param.name FILTER html %]"
+ size="[% boxSize FILTER html %]">
+ [% FOREACH item = plist %]
+ <option value="[% item FILTER html %]">[% item FILTER html %]</option>
+ [% END %]
+ <option class="sortlist_separator" disabled="disabled"
+ value="[% sortlist_separator %]">active&uarr;&nbsp;&darr;inactive</option>
+ [% FOREACH item = param.choices %]
+ [% IF lsearch(plist, item) == -1 %]
+ <option value="[% item FILTER html %]">[% item FILTER html %]</option>
+ [% END %]
+ [% END %]
+ </select>
+ </td>
+ <td style="vertical-align: bottom">
+ <button type="button"
+ onClick="sortedList_moveItem('[% param.name FILTER html %]', -1, '[% sortlist_separator %]');">&uarr;</button>
+ </td>
+ </tr>
+
+ <tr>
+ <td style="vertical-align: top">
+ <button type="button"
+ onClick="sortedList_moveItem('[% param.name FILTER html %]', +1, '[% sortlist_separator %]');">&darr;</button>
+ </td>
+ </tr>
+ </table>
+
+ <script type="text/javascript">
+ bz_toggleClass("input_[% param.name FILTER html %]", "bz_default_hidden");
+ bz_toggleClass("table_[% param.name FILTER html %]", "bz_default_hidden");
+ </script>
+ [% ELSIF param.type == "s" %]
+ <select name="[% param.name FILTER html %]" id="[% param.name FILTER html %]">
+ [% FOREACH item = param.choices %]
+ <option value="[% item FILTER html %]"
+ [% " selected=\"selected\"" IF item == Param(param.name) %]>
+ [% IF param.name == "defaultseverity" %]
+ [% display_value("bug_severity", item) FILTER html %]
+ [% ELSIF param.name == "defaultplatform" %]
+ [% display_value("rep_platform", item) FILTER html %]
+ [% ELSIF param.name == "defaultopsys" %]
+ [% display_value("op_sys", item) FILTER html %]
+ [% ELSIF param.name == "duplicate_or_move_bug_status" %]
+ [% display_value("bug_status", item) FILTER html %]
+ [% ELSE %]
+ [% item FILTER html %]
+ [% END %]
+ </option>
+ [% END %]
+ </select>
+ [% ELSE %]
+ <font color="red">
+ Unknown param type [% param.type FILTER html %]!!!
+ </font>
+ [% END %]
+ </p>
+ [% UNLESS param.no_reset %]
+ <p>
+ <input type="checkbox" name="reset-[% param.name FILTER html %]"
+ id="reset-[% param.name FILTER html %]">
+ <label for="reset-[% param.name FILTER html %]">Reset</label>
+ </p>
+ [% END %]
+ <hr>
+ </dd>
+ [% END %]
+</dl>
diff --git a/template/en/default/admin/params/core.html.tmpl b/template/en/default/admin/params/core.html.tmpl
new file mode 100644
index 0000000..fd839ed
--- /dev/null
+++ b/template/en/default/admin/params/core.html.tmpl
@@ -0,0 +1,35 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%
+ title = "Required Settings"
+ desc = "Settings that are required for proper operation of $terms.Bugzilla"
+%]
+
+[% param_descs = {
+ urlbase => "The URL that is the common initial leading part of all $terms.Bugzilla " _
+ "URLs.",
+
+ sslbase => "The URL that is the common initial leading part of all HTTPS " _
+ "(SSL) $terms.Bugzilla URLs.",
+
+ ssl_redirect =>
+ "When this is enabled, $terms.Bugzilla will ensure that every page is"
+ _ " accessed over SSL, by redirecting any plain HTTP requests to HTTPS"
+ _ " using the <tt>sslbase</tt> parameter. Also, when this is enabled,"
+ _ " $terms.Bugzilla will send out links using <tt>sslbase</tt> in emails"
+ _ " instead of <tt>urlbase</tt>.",
+
+ cookiepath => "Path, relative to your web document root, to which to restrict " _
+ "$terms.Bugzilla cookies. Normally this is the URI portion of your URL " _
+ "base. Begin with a / (single slash mark). For instance, if " _
+ "$terms.Bugzilla serves from 'http://www.somedomain.com/bugzilla/', set " _
+ "this parameter to /bugzilla/. Setting it to / will allow " _
+ "all sites served by this web server or virtual host to read " _
+ "$terms.Bugzilla cookies.",
+} %]
diff --git a/template/en/default/admin/params/dependencygraph.html.tmpl b/template/en/default/admin/params/dependencygraph.html.tmpl
new file mode 100644
index 0000000..e8baf45
--- /dev/null
+++ b/template/en/default/admin/params/dependencygraph.html.tmpl
@@ -0,0 +1,36 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[%
+ title = "Dependency Graphs"
+ desc = "Optional setup for dependency graphing"
+%]
+
+[% param_descs = {
+ webdotbase => "It is possible to show graphs of dependent ${terms.bugs}. You may set
+ this parameter to any of the following:
+ <ul>
+ <li>
+ A complete file path to 'dot' (part of
+ <a href=\"http://www.graphviz.org\">GraphViz</a>) will
+ generate the graphs locally.
+ </li>
+ <li>
+ A URL prefix pointing to an installation of the
+ <a href=\"http://www.research.att.com/~north/cgi-bin/webdot.cgi\">webdot
+ package</a> will generate the graphs remotely.
+ </li>
+ <li>
+ A blank value will disable dependency graphing.
+ </li>
+ </ul>
+ The default value is a publicly-accessible webdot server. If you change
+ this value, make certain that the webdot server can read files from your
+ webdot directory. On Apache you do this by editing the .htaccess file,
+ for other systems the needed measures may vary. You can run <kbd>checksetup.pl</kbd>
+ to recreate the .htaccess file if it has been lost."}
+%]
diff --git a/template/en/default/admin/params/editparams.html.tmpl b/template/en/default/admin/params/editparams.html.tmpl
new file mode 100644
index 0000000..3febbab
--- /dev/null
+++ b/template/en/default/admin/params/editparams.html.tmpl
@@ -0,0 +1,103 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% curpanel = -1 %]
+[% panels = panels.nsort('sortkey') %]
+
+[% FOREACH panel = panels %]
+ [% PROCESS "admin/params/${panel.name}.html.tmpl"
+ params = panel.param_list %]
+ [% panel.title = title %]
+ [% panel.desc = desc %]
+ [% panel.param_descs = param_descs %]
+ [% IF panel.current %][% curpanel = loop.index %][% END %]
+[% END %]
+
+[% current_panel = panels.$curpanel %]
+
+[%# We cannot call header.html.tmpl earlier as we have to know
+ which panel is active first, in order to get its title %]
+
+[% title = BLOCK %]
+ [% IF curpanel == -1 %]
+ Parameters: Index
+ [% ELSE %]
+ Configuration:
+ [%+ current_panel.title FILTER html %]
+ [% END %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ message = message
+ style_urls = ['skins/standard/params.css']
+ javascript_urls = ['js/params.js', 'js/util.js']
+ doc_section = "parameters.html"
+%]
+
+<table border="0" width="100%">
+ <tr>
+ <td>
+ [%# NAVIGATION BAR %]
+ <table id="menu">
+ <tr>
+ <td class="index">
+ <a href="editparams.cgi?section=index" title="Show all parameters">Index</a>
+ </td>
+ </tr>
+ [% FOREACH panel = panels %]
+ <tr>
+ [% IF panel.current %]
+ [% Hook.process("current_panel") %]
+ <td class="selected_section">
+ <span title="[% panel.desc FILTER html %]">[% panel.title FILTER html %]</span>
+ </td>
+ [% ELSE %]
+ <td>
+ <a href="editparams.cgi?section=[% panel.name FILTER uri %]"
+ title="[% panel.desc FILTER html %]">[% panel.title FILTER html %]</a>
+ </td>
+ [% END %]
+ </tr>
+ [% END %]
+ </table>
+ </td>
+ <td>
+ [% IF curpanel == -1 %]
+ [% PROCESS admin/params/index.html.tmpl panels = panels %]
+ [% ELSE %]
+
+ <div class="contribute"><strong>Note:</strong>
+ B[% %]ugzilla is developed entirely by volunteers.
+ The best way to give back to the B[% %]ugzilla project is to
+ <a href="http://www.bugzilla.org/contribute/">contribute</a>
+ yourself!
+ You don't have to be a programmer to contribute, there are lots of
+ things that we need.
+ </div>
+
+ <p>
+ This lets you edit the basic operating parameters of [% terms.Bugzilla %].
+ Be careful!<br>
+ Any item you check "Reset" on will get reset to its default value.
+ </p>
+
+ [%# CONTENT PANEL %]
+ <form method="post" action="editparams.cgi">
+ [% PROCESS admin/params/common.html.tmpl panel = current_panel %]
+ <input type="hidden" name="section" value="[% current_panel.name FILTER html %]">
+ <input type="hidden" name="action" value="save">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="submit" id="save-params" value="Save Changes">
+ </form>
+ [% END %]
+ </td>
+ </tr>
+</table>
+
+[% INCLUDE global/footer.html.tmpl %]
diff --git a/template/en/default/admin/params/general.html.tmpl b/template/en/default/admin/params/general.html.tmpl
new file mode 100644
index 0000000..daa1f35
--- /dev/null
+++ b/template/en/default/admin/params/general.html.tmpl
@@ -0,0 +1,73 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%
+ title = "General"
+ desc = "Miscellaneous general settings that are not required."
+%]
+
+[% param_descs = {
+ maintainer =>
+ "The email address of the person who maintains this installation "
+ _ " of ${terms.Bugzilla}.",
+
+ docs_urlbase =>
+ "The URL that is the common initial leading part of all"
+ _ " $terms.Bugzilla documentation URLs. It may be an absolute URL,"
+ _ " or a URL relative to the <tt>urlbase</tt> parameter. Leave this"
+ _ " empty to suppress links to the documentation."
+ _ "'%lang%' will be replaced by user's preferred language (if"
+ _ " documentation is available in that language).",
+
+ utf8 =>
+ "Use UTF-8 (Unicode) encoding for all text in ${terms.Bugzilla}. New"
+ _ " installations should set this to true to avoid character encoding"
+ _ " problems. <strong>Existing databases should set this to true"
+ _ " only after the data has been converted from existing legacy"
+ _ " character encodings to UTF-8, using the <kbd>contrib/recode.pl</kbd>"
+ _ " script</strong>."
+ _ " <p>Note that if you turn this parameter from &quot;off&quot; to"
+ _ " &quot;on&quot;, you must re-run <kbd>checksetup.pl</kbd> immediately"
+ _ " afterward.</p>",
+
+ shutdownhtml =>
+ "If this field is non-empty, then $terms.Bugzilla will be completely"
+ _ " disabled and this text will be displayed instead of all the"
+ _ " $terms.Bugzilla pages.",
+
+ announcehtml =>
+ "If this field is non-empty, then $terms.Bugzilla will"
+ _ " display whatever is in this field at the top of every"
+ _ " HTML page. The HTML you put in this field is not wrapped or"
+ _ " enclosed in anything. You might want to wrap it inside a"
+ _ "<tt>&lt;div&gt;</tt>. Give the div <em>id=\"message\"</em> to get"
+ _ " green text inside a red box, or <em>class=\"bz_private\"</em> for"
+ _ " dark red on a red background. Anything defined in "
+ _ " <tt>skins/standard/global.css</tt> or <tt>skins/custom/global.css</tt>"
+ _ " will work. To get centered text, use <em>style=\"text-align: "
+ _ " center;\"</em>.",
+
+ upgrade_notification =>
+ "$terms.Bugzilla can inform you when a new release is available."
+ _ " The notification will appear on the $terms.Bugzilla homepage,"
+ _ " for administrators only."
+ _ " <ul><li>'development_snapshot' notifies you about the development "
+ _ " snapshot that has been released.</li>"
+ _ " <li>'latest_stable_release' notifies you about the most recent"
+ _ " release available on the most recent stable branch. This branch"
+ _ " may be different from the branch your installation is based on.</li>"
+ _ " <li>'stable_branch_release' notifies you only about new releases"
+ _ " corresponding to the branch your installation is based on."
+ _ " If you are running a release candidate, you will get a notification"
+ _ " for newer release candidates too.</li>"
+ _ " <li>'disabled' will never notify you about new releases and no"
+ _ " connection will be established to a remote server.</li></ul>"
+ _ " <p>Note that if your $terms.Bugzilla server requires a proxy to"
+ _ " access the Internet, you may also need to set the <tt>proxy_url</tt>"
+ _ " parameter in the Advanced section.</p>",
+} %]
diff --git a/template/en/default/admin/params/groupsecurity.html.tmpl b/template/en/default/admin/params/groupsecurity.html.tmpl
new file mode 100644
index 0000000..7e30f07
--- /dev/null
+++ b/template/en/default/admin/params/groupsecurity.html.tmpl
@@ -0,0 +1,46 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[%
+ title = "Group Security"
+ desc = "Decide how you will use Security Groups"
+%]
+
+[% param_descs = {
+ makeproductgroups => "If this is on, $terms.Bugzilla will associate $terms.abug group " _
+ "with each product in the database, and use it for querying ${terms.bugs}.",
+
+ chartgroup => "The name of the group of users who can use the 'New Charts' " _
+ "feature. Administrators should ensure that the public categories " _
+ "and series definitions do not divulge confidential information " _
+ "before enabling this for an untrusted population. If left blank, " _
+ "no users will be able to use New Charts.",
+
+ insidergroup => "The name of the group of users who can see/change private " _
+ "comments and attachments.",
+
+ timetrackinggroup => "The name of the group of users who can see/change time tracking " _
+ "information.",
+
+ querysharegroup => "The name of the group of users who can share their " _
+ "saved searches with others.",
+
+ debug_group => "The name of the group of users who can view the actual " _
+ "SQL query generated when viewing $terms.bug lists and reports.",
+
+ usevisibilitygroups => "Do you wish to restrict visibility of users to members of " _
+ "specific groups?",
+
+ strict_isolation => "Don't allow users to be assigned to, " _
+ "be qa-contacts on, " _
+ "be added to CC list, " _
+ "or make or remove dependencies " _
+ "involving any bug that is in a product on which that " _
+ "user is forbidden to edit.",
+
+ }
+%]
diff --git a/template/en/default/admin/params/index.html.tmpl b/template/en/default/admin/params/index.html.tmpl
new file mode 100644
index 0000000..65aa398
--- /dev/null
+++ b/template/en/default/admin/params/index.html.tmpl
@@ -0,0 +1,38 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+<p>
+ All parameters are displayed below, per section.
+ If you cannot find one from here, then the parameter does not exist.
+</p>
+
+<div align="center">
+ <table>
+ <tr>
+ <th>Parameter</th>
+ <th>Section</th>
+ </tr>
+ [% FOREACH panel = panels %]
+ [% FOREACH param = panel.param_list.sort('name') %]
+ <tr>
+ <td>
+ <a href="editparams.cgi?section=
+ [%- panel.name FILTER uri %]#[% param.name FILTER uri %]_desc">
+ [% param.name FILTER html %]</a>
+ </td>
+ <td>
+ [% panel.title FILTER html %]
+ </td>
+ </tr>
+ [% END %]
+ <tr>
+ <td>&nbsp;</td><td>&nbsp;</td>
+ </tr>
+ [% END %]
+ </table>
+</div>
diff --git a/template/en/default/admin/params/ldap.html.tmpl b/template/en/default/admin/params/ldap.html.tmpl
new file mode 100644
index 0000000..64b3dbd
--- /dev/null
+++ b/template/en/default/admin/params/ldap.html.tmpl
@@ -0,0 +1,45 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[%
+ title = "LDAP"
+ desc = "Configure this first before choosing LDAP as an authentication method"
+%]
+
+[% param_descs = {
+ LDAPserver => "The name (and optionally port) of your LDAP server " _
+ "(e.g. ldap.company.com, or ldap.company.com:portnum). " _
+ "URI syntax can also be used, such as "_
+ "ldaps://ldap.company.com (for a secure connection) or " _
+ "ldapi://%2fvar%2flib%2fldap_sock (for a socket-based " _
+ "local connection. Multiple hostnames or URIs can be comma " _
+ "separated; each will be tried in turn until a connection is " _
+ "established.",
+
+ LDAPstarttls => "Whether to require encrypted communication once a normal " _
+ "LDAP connection is achieved with the server.",
+
+ LDAPbinddn => "If your LDAP server requires that you use a binddn and password " _
+ "instead of binding anonymously, enter it here " _
+ "(e.g. cn=default,cn=user:password). " _
+ "Leave this empty for the normal case of an anonymous bind.",
+
+ LDAPBaseDN => "The BaseDN for authenticating users against " _
+ "(e.g. ou=People,o=Company).",
+
+ LDAPuidattribute => "The name of the attribute containing the user's login name.",
+
+ LDAPmailattribute => "The name of the attribute of a user in your " _
+ "directory that contains the email address, to be " _
+ "used as $terms.Bugzilla username. If this parameter " _
+ "is empty, $terms.Bugzilla will use the LDAP username"_
+ " as the $terms.Bugzilla username. You may also want" _
+ " to set the \"emailsuffix\" parameter, in this case.",
+
+ LDAPfilter => "LDAP filter to AND with the <tt>LDAPuidattribute</tt> for " _
+ "filtering the list of valid users." }
+%]
diff --git a/template/en/default/admin/params/mta.html.tmpl b/template/en/default/admin/params/mta.html.tmpl
new file mode 100644
index 0000000..f491a30
--- /dev/null
+++ b/template/en/default/admin/params/mta.html.tmpl
@@ -0,0 +1,67 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[%
+ title = "Email"
+ desc = "How will outgoing mail be delivered?"
+%]
+
+[% param_descs = {
+ mail_delivery_method => "Defines how email is sent, or if it is sent at all.<br>
+ <ul>
+ <li>
+ 'Sendmail', 'SMTP' and 'Qmail' are all MTAs.
+ You need to install a third-party sendmail replacement if
+ you want to use sendmail on Windows.
+ </li>
+ <li>
+ 'Test' is useful for debugging: all email is stored
+ in 'data/mailer.testfile' instead of being sent.
+ </li>
+ <li>
+ 'none' will completely disable email. $terms.Bugzilla continues
+ to act as though it is sending mail, but nothing is sent or
+ stored.
+ </li>
+ </ul>",
+
+ mailfrom => "The email address of the $terms.Bugzilla mail daemon. Some email systems " _
+ "require this to be a valid email address.",
+
+ use_mailer_queue => "In a large $terms.Bugzilla installation, updating"
+ _ " $terms.bugs can be very slow, because $terms.Bugzilla sends all"
+ _ " email at once. If you enable this parameter, $terms.Bugzilla will"
+ _ " queue all mail and then send it in the background. This requires"
+ _ " that you have installed certain Perl modules (as listed by"
+ _ " <kbd>checksetup.pl</kbd> for this feature), and that you are"
+ _ " running the <code>jobqueue.pl</code> daemon (otherwise your mail"
+ _ " won't get sent). This affects all mail sent by $terms.Bugzilla,"
+ _ " not just $terms.bug updates.",
+
+ smtpserver => "The SMTP server address (if using SMTP for mail delivery).",
+
+ smtp_username => "The username to pass to the SMTP server for SMTP authentication. " _
+ "Leave this field empty if your SMTP server doesn't require authentication.",
+
+ smtp_password => "The password to pass to the SMTP server for SMTP authentication. " _
+ "This field has no effect if the smtp_username parameter is left empty.",
+
+ smtp_ssl => "Enable SSL support for SMTP.",
+
+ smtp_debug => "If enabled, this will print detailed information to your" _
+ " web server's error log about the communication between" _
+ " $terms.Bugzilla and your SMTP server. You can use this to" _
+ " troubleshoot email problems.",
+
+ whinedays => "The number of days that we'll let a $terms.bug sit untouched in a CONFIRMED " _
+ "state before our cronjob will whine at the owner.<br> " _
+ "Set to 0 to disable whining.",
+
+ globalwatchers => "A comma-separated list of users who should receive a " _
+ "copy of every notification mail the system sends." }
+
+%]
diff --git a/template/en/default/admin/params/patchviewer.html.tmpl b/template/en/default/admin/params/patchviewer.html.tmpl
new file mode 100644
index 0000000..61d32a0
--- /dev/null
+++ b/template/en/default/admin/params/patchviewer.html.tmpl
@@ -0,0 +1,51 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[%
+ title = "Patch Viewer"
+ desc = "Set up third-party applications to run with PatchViewer"
+%]
+
+[% param_descs = {
+ cvsroot => "The <a href=\"http://www.cvshome.org\">CVS</a> root that most " _
+ "users of your system will be using for 'cvs diff'. Used in " _
+ "Patch Viewer ('Diff' option on patches) to figure out where " _
+ "patches are rooted even if users did the 'cvs diff' from " _
+ "different places in the directory structure. (NOTE: if your " _
+ "CVS repository is remote and requires a password, you must " _
+ "either ensure the $terms.Bugzilla user has done a 'cvs login' or " _
+ "specify the password " _
+ "<a href=\"http://www.cvshome.org/docs/manual/cvs_2.html#SEC26\">as " _
+ "part of the CVS root</a>.) Leave this blank if you have no " _
+ "CVS repository.",
+
+ cvsroot_get => "The CVS root $terms.Bugzilla will be using to get patches from. " _
+ "Some installations may want to mirror their CVS repository on " _
+ "the $terms.Bugzilla server or even have it on that same server, and " _
+ "thus the repository can be the local file system (and much " _
+ "faster). Make this the same as cvsroot if you don't " _
+ "understand what this is (if cvsroot is blank, make this blank too).",
+
+ bonsai_url => "The URL to a <a href=\"http://www.mozilla.org/bonsai.html\">Bonsai</a> " _
+ "server containing information about your CVS repository. " _
+ "Patch Viewer will use this information to create links to " _
+ "bonsai's blame for each section of a patch (it will append " _
+ "'/cvsblame.cgi?...' to this url). Leave this blank if you " _
+ "don't understand what this is.",
+
+ lxr_url => "The URL to an <a href=\"http://sourceforge.net/projects/lxr\">LXR</a> server " _
+ "that indexes your CVS repository. Patch Viewer will use this " _
+ "information to create links to LXR for each file in a patch. " _
+ "Leave this blank if you don't understand what this is.",
+
+ lxr_root => "Some LXR installations do not index the CVS repository from the root -- " _
+ "<a href=\"http://lxr.mozilla.org/mozilla\">Mozilla's</a>, for " _
+ "example, starts indexing under <code>mozilla/</code>. This " _
+ "means URLs are relative to that extra path under the root. " _
+ "Enter this if you have a similar situation. Leave it blank " _
+ "if you don't know what this is." }
+%]
diff --git a/template/en/default/admin/params/query.html.tmpl b/template/en/default/admin/params/query.html.tmpl
new file mode 100644
index 0000000..52a960b
--- /dev/null
+++ b/template/en/default/admin/params/query.html.tmpl
@@ -0,0 +1,64 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[%
+ title = "Query Defaults"
+ desc = "Default options for query and $terms.bug lists"
+%]
+
+[% param_descs = {
+ quip_list_entry_control => "Controls how easily users can add entries to the quip list.
+ <ul>
+ <li>
+ open - Users may freely add to the quip list, and
+ their entries will immediately be available for viewing.
+ </li>
+ <li>
+ moderated - quips can be entered, but need to be approved
+ by a moderator before they will be shown.
+ </li>
+ <li>
+ closed - no new additions to the quips list are allowed.
+ </li>
+ </ul>",
+
+ mostfreqthreshold => "The minimum number of duplicates $terms.abug needs to show up on the " _
+ "<a href=\"duplicates.cgi\">most frequently reported $terms.bugs page</a>. " _
+ "If you have a large database and this page takes a long time to " _
+ "load, try increasing this number.",
+
+ mybugstemplate => "This is the URL to use to bring up a simple 'all of my $terms.bugs' " _
+ "list for a user. %userid% will get replaced with the login name of a user.",
+
+ defaultquery => "This is the default query that initially comes up when you " _
+ "access the advanced query page. It's in URL parameter " _
+ "format, which makes it hard to read. Sorry!",
+
+ search_allow_no_criteria =>
+ "Unless the code explicitly allows all $terms.bugs to be returned, this " _
+ "parameter permits to block the execution of queries with no criteria. " _
+ "When turned off, a query must have some criteria specified to limit " _
+ "the number of $terms.bugs returned to the user. When turned on, a user " _
+ "is allowed to run a query with no criteria and get all $terms.bugs he can " _
+ "see in his list. Turning this parameter on is not recommended on large " _
+ "installations.",
+
+ default_search_limit =>
+ "By default, $terms.Bugzilla limits searches done in the web"
+ _ " interface to returning only this many results, for performance"
+ _ " reasons. (This only affects the HTML format of search results--CSV,"
+ _ " XML, and other formats are exempted.) Users can click a link on the"
+ _ " search result page to see all the results."
+ _ "<p>Usually you should not have to change this--the default value"
+ _ " should be acceptable for most installations.</p>",
+
+ max_search_results =>
+ "The maximum number of $terms.bugs that a search can"
+ _ " <strong>ever</strong> return. Tabular and graphical reports"
+ _ " are exempted from this limit, however.",
+
+} %]
diff --git a/template/en/default/admin/params/radius.html.tmpl b/template/en/default/admin/params/radius.html.tmpl
new file mode 100644
index 0000000..5ac291a
--- /dev/null
+++ b/template/en/default/admin/params/radius.html.tmpl
@@ -0,0 +1,43 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[%
+ title = "RADIUS"
+ desc = "Configure this first before choosing RADIUS as an authentication method"
+%]
+
+[% param_descs = {
+ RADIUS_server => "The name (and optionally port) of your RADIUS server " _
+ "(e.g. <code>radius.company.com</code>, or " _
+ "<code>radius.company.com:portnum</code>).<br>" _
+ "Required only if " _
+ "<a href=\"?section=auth#user_verify_class_desc\">the " _
+ "<code>user_verify_class</code> parameter</a> contains " _
+ "<code>RADIUS</code>.",
+
+ RADIUS_secret => "Your RADIUS server's secret.<br>" _
+ "Required only if " _
+ "<a href=\"?section=auth#user_verify_class_desc\">the " _
+ "<code>user_verify_class</code> parameter</a> contains " _
+ "<code>RADIUS</code>.",
+
+ RADIUS_NAS_IP => "The NAS-IP-Address attribute to be used when exchanging " _
+ "data with your RADIUS server. " _
+ "If unspecified, <code>127.0.0.1</code> will be used.<br>" _
+ "Useful only if " _
+ "<a href=\"?section=auth#user_verify_class_desc\">the " _
+ "<code>user_verify_class</code> parameter</a> " _
+ "contains <code>RADIUS</code>.",
+
+ RADIUS_email_suffix => "Suffix to append to a RADIUS user name to form an " _
+ "e-mail address.<br>" _
+ "Useful only if " _
+ "<a href=\"?section=auth#user_verify_class_desc\">the " _
+ "<code>user_verify_class</code> parameter</a> " _
+ "contains <code>RADIUS</code>.",
+ }
+%]
diff --git a/template/en/default/admin/params/shadowdb.html.tmpl b/template/en/default/admin/params/shadowdb.html.tmpl
new file mode 100644
index 0000000..9f9f314
--- /dev/null
+++ b/template/en/default/admin/params/shadowdb.html.tmpl
@@ -0,0 +1,36 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[%
+ title = "Shadow Database"
+ desc = "An optional hack to increase database performance"
+%]
+
+[% param_descs = {
+ shadowdbhost => "The host the shadow database is on.",
+
+ shadowdbport => "The port the shadow database is on. Ignored if " _
+ "<tt>shadowdbhost</tt> is blank. Note: if the host is the local " _
+ "machine, then MySQL will ignore this setting, and you must " _
+ "specify a socket below.",
+
+ shadowdbsock => "The socket used to connect to the shadow database, if the host " _
+ "is the local machine. This setting is required because MySQL " _
+ "ignores the port specified by the client and connects using " _
+ "its compiled-in socket path (on unix machines) when connecting " _
+ "from a client to a local server. If you leave this blank, and " _
+ "have the database on localhost, then the <tt>shadowdbport</tt> " _
+ "will be ignored.",
+
+ shadowdb => "If non-empty, then this is the name of another database in " _
+ "which $terms.Bugzilla will use as a read-only copy of everything. " _
+ "This is done so that long slow read-only operations can be used " _
+ "against this db, and not lock up things for everyone else. This " _
+ "database is on the <tt>shadowdbhost</tt>, and must exist. " _
+ "$terms.Bugzilla does not update it, if you use this parameter, then " _
+ "you need to set up replication for your database." }
+%]
diff --git a/template/en/default/admin/params/usermatch.html.tmpl b/template/en/default/admin/params/usermatch.html.tmpl
new file mode 100644
index 0000000..ebbc363
--- /dev/null
+++ b/template/en/default/admin/params/usermatch.html.tmpl
@@ -0,0 +1,29 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[%
+ title = "User Matching"
+ desc = "Set up your user matching policies"
+%]
+
+[% param_descs = {
+ usemenuforusers => "If this option is set, $terms.Bugzilla will offer you a list " _
+ "to select from (instead of a text entry field) where a user " _
+ "needs to be selected. This option should not be enabled on " _
+ "sites where there are a large number of users.",
+
+ ajax_user_autocompletion => "If this option is set, typing characters in a certain user " _
+ "fields will display a list of matches that can be selected from.",
+
+ maxusermatches => "Search for no more than this many matches.<br> " _
+ "If set to '1', no users will be displayed on ambiguous matches. " _
+ "This is useful for user privacy purposes.<br> " _
+ "A value of zero means no limit.",
+
+ confirmuniqueusermatch => "Whether a confirmation screen should be displayed when only " _
+ "one user matches a search entry." }
+%]
diff --git a/template/en/default/admin/products/confirm-delete.html.tmpl b/template/en/default/admin/products/confirm-delete.html.tmpl
new file mode 100644
index 0000000..eb1094f
--- /dev/null
+++ b/template/en/default/admin/products/confirm-delete.html.tmpl
@@ -0,0 +1,259 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: Bugzilla::Product object; The product
+ #
+ # (classification fields available if Param('useclassification') is enabled:)
+ #
+ # classification: Bugzilla::Classification object; The classification
+ # the product is in
+ #
+ #%]
+
+[% title = BLOCK %]Delete Product '[% product.name FILTER html %]'
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+%]
+
+<table border="1" cellpadding="4" cellspacing="0">
+ <tr bgcolor="#6666FF">
+ <th valign="top" align="left">Field</th>
+ <th valign="top" align="left">Value</th>
+ </tr>
+
+ [% IF Param('useclassification') %]
+ <tr>
+ <td>Classification:</td>
+ <td>[% classification.name FILTER html %]</td>
+ </tr>
+ <tr>
+ <td>Classification Description:</td>
+ [%# descriptions are intentionally not filtered to allow html content %]
+ <td>
+ [% IF classification.description %]
+ [% classification.description FILTER html_light %]
+ [% ELSE %]
+ <span style="color: red">missing</span>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <td valign="top">Product:</td>
+ <td valign="top">
+ <a href="editproducts.cgi?product=[% product.name FILTER uri %]">
+ [% product.name FILTER html %]
+ </a>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">Description:</td>
+ [%# descriptions are intentionally not filtered to allow html content %]
+ <td valign="top">
+ [% IF product.description %]
+ [% product.description FILTER html_light %]
+ [% ELSE %]
+ <span style="color: red">missing</span>
+ [% END %]
+ </td>
+ </tr>
+
+ [% IF Param('usetargetmilestone') %]
+ <tr>
+ <td>Milestone URL:</td>
+ <td>
+ [% IF product.milestone_url %]
+ <a href="[% product.milestone_url FILTER html %]">
+ [%- product.milestone_url FILTER html %]
+ </a>
+ [% ELSE %]
+ none
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <td>Closed for [% terms.bugs %]:</td>
+ <td>
+ [% IF product.is_active %]
+ open
+ [% ELSE %]
+ closed
+ [% END %]
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ [% IF product.components.size > 0 %]
+ <a href="editcomponents.cgi?product=[% product.name FILTER uri %]"
+ title="Edit components for product '[% product.name FILTER html %]'">
+ Components:
+ </a>
+ [% ELSE %]
+ Components:
+ [% END %]
+ </td>
+ <td>
+ [% IF product.components.size > 0 %]
+ <table>
+ [% FOREACH c = product.components %]
+ <tr>
+ <th align="right">[% c.name FILTER html %]:</th>
+ [%# descriptions are intentionally not filtered to allow html content %]
+ <td>
+ [% IF c.description %]
+ [% c.description FILTER html_light %]
+ [% ELSE %]
+ <span style="color: red">missing</span>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+ </table>
+ [% ELSE %]
+ none
+ [% END %]
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ [% IF product.versions.size > 0 %]
+ <a href="editversions.cgi?product=[%- product.name FILTER uri %]">
+ Versions:
+ </a>
+ [% ELSE %]
+ Versions:
+ [% END %]
+ </td>
+ <td>
+ [% IF product.versions.size > 0 %]
+ [% FOREACH v = product.versions %]
+ [% v.name FILTER html %]<br>
+ [% END %]
+ [% ELSE %]
+ none
+ [% END %]
+ </td>
+ </tr>
+
+
+ [% IF Param('usetargetmilestone') %]
+ <tr>
+ <td valign="top">
+ [% IF product.milestones.size > 0 %]
+ <a href="editmilestones.cgi?product=[%- product.name FILTER uri %]">
+ Milestones:
+ </a>
+ [% ELSE %]
+ Milestones:
+ [% END %]
+ </td>
+ <td>
+ [% IF product.milestones.size > 0 %]
+ [% FOREACH m = product.milestones %]
+ [% m.name FILTER html %]<br>
+ [% END %]
+ [% ELSE %]
+ none
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <td>[% terms.Bugs %]:</td>
+ <td>
+ [% IF product.bug_count %]
+ <a href="buglist.cgi?product=[% product.name FILTER uri %]"
+ title="List of [% terms.bugs %] for product '[% product.name FILTER html %]'">
+ [% product.bug_count FILTER html %]
+ </a>
+ [% ELSE %]
+ none
+ [% END %]
+ </td>
+ </tr>
+</table>
+
+<h2>Confirmation</h2>
+
+[% IF product.bug_count %]
+
+ [% IF !Param("allowbugdeletion") %]
+
+ <p class="confirmation">Sorry, there
+
+ [% IF product.bug_count > 1 %]
+ are [% product.bug_count FILTER html %] [%+ terms.bugs %]
+ [% ELSE %]
+ is 1 [% terms.bug %]
+ [% END %]
+
+ outstanding for this product. You must reassign
+
+ [% IF product.bug_count > 1 %]
+ those [% terms.bugs %]
+ [% ELSE %]
+ that [% terms.bug %]
+ [% END %]
+
+ to another product before you can delete this one.</p>
+
+ [% ELSE %]
+
+ <table border="0" cellpadding="20" width="70%" bgcolor="red">
+ <tr>
+ <td>
+ There
+ [% IF product.bug_count > 1 %]
+ are [% product.bug_count FILTER html %] [%+ terms.bugs %]
+ [% ELSE %]
+ is 1 [% terms.bug %]
+ [% END %]
+ entered for this product! When you delete this
+ product, <b>ALL</b> stored [% terms.bugs %] and
+ their history will be deleted, too.
+ </td>
+ </tr>
+ </table>
+
+ [% END %]
+
+[% END %]
+
+[% Hook.process("confirmation") %]
+
+[% IF product.bug_count == 0 || Param('allowbugdeletion') %]
+
+ <p>Do you really want to delete this product?</p>
+
+ <form method="post" action="editproducts.cgi">
+ <input type="checkbox" id="delete_series" name="delete_series" value=1>
+ <label for="delete_series">
+ Delete all related series (you can also delete them later, by visiting
+ the <a href="chart.cgi?category=[% product.name FILTER html %]">New Charts page</a>.)
+ </label><p>
+ <input type="submit" id="delete" value="Yes, delete">
+ <input type="hidden" name="action" value="delete">
+ <input type="hidden" name="product" value="[% product.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ </form>
+
+[% END %]
+
+[% PROCESS admin/products/footer.html.tmpl %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/products/create.html.tmpl b/template/en/default/admin/products/create.html.tmpl
new file mode 100644
index 0000000..6d40095
--- /dev/null
+++ b/template/en/default/admin/products/create.html.tmpl
@@ -0,0 +1,74 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # classification: Bugzilla::Classification object; If classifications
+ # are enabled, then this is
+ # the currently selected classification
+ #
+ #%]
+
+[% title = BLOCK %]Add Product[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+ javascript_urls = ['js/util.js', 'js/field.js']
+ yui = [ 'autocomplete' ]
+%]
+
+[% DEFAULT
+ product.is_active = 1,
+ version = "unspecified",
+ product.defaultmilestone = constants.DEFAULT_MILESTONE
+ product.allows_unconfirmed = 1
+%]
+
+<form method="post" action="editproducts.cgi">
+ <table border="0" cellpadding="4" cellspacing="0">
+
+ [% PROCESS "admin/products/edit-common.html.tmpl" %]
+
+ <tr>
+ <th align="right">Version:</th>
+ <td><input size="20" maxlength="64" name="version"
+ value="[% version FILTER html %]">
+ </td>
+ </tr>
+ <tr>
+ <th align="right">Create chart datasets for this product:</th>
+ <td>
+ <input type="checkbox" name="createseries" value="1" checked="checked">
+ </td>
+ </tr>
+
+ <tr>
+ <td colspan="2">&nbsp;</td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ This product must have at least one component.
+ You will be able to create additional components later:
+ </td>
+ </tr>
+
+ [% PROCESS "admin/components/edit-common.html.tmpl" desc_name = "comp_desc" %]
+ </table>
+
+ <input type="submit" id="add-product" value="Add">
+ <input type="hidden" name="action" value="new">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="hidden" name="classification"
+ value="[% classification.name FILTER html %]">
+</form>
+
+[% PROCESS "admin/products/footer.html.tmpl"
+ no_add_product_link = 1
+ no_edit_product_link = 1 %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/products/edit-common.html.tmpl b/template/en/default/admin/products/edit-common.html.tmpl
new file mode 100644
index 0000000..2b76c44
--- /dev/null
+++ b/template/en/default/admin/products/edit-common.html.tmpl
@@ -0,0 +1,72 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: Bugzilla::Product object; The product
+ #
+ # classification: Bugzilla::Classifiation object; classification product is in.
+ #%]
+
+[% IF Param('useclassification') %]
+ <tr>
+ <th align="right">Classification:</th>
+ <td><b>[% classification.name FILTER html %]</b></td>
+ </tr>
+[% END %]
+
+<tr>
+ <th align="right">Product:</th>
+ <td><input size="64" maxlength="64" name="product"
+ value="[% product.name FILTER html %]">
+ </td>
+</tr>
+<tr>
+ <th align="right">Description:</th>
+ <td><textarea rows="4" cols="64" wrap="virtual" name="description">
+ [% product.description FILTER html %]</textarea>
+ </td>
+</tr>
+
+<tr>
+ <th align="right">Open for [% terms.bug %] entry:</th>
+ <td><input type="checkbox" name="is_active" value="1"
+ [% ' checked="checked"' IF product.is_active %]>
+ </td>
+</tr>
+<tr>
+ <th align="right">
+ <label for="allows_unconfirmed">Enable the
+ [%+ display_value('bug_status', 'UNCONFIRMED') FILTER html %] status
+ in this product:</label>
+ </th>
+ <td><input type="checkbox" id="allows_unconfirmed" name="allows_unconfirmed"
+ [% ' checked="checked"' IF product.allows_unconfirmed %]>
+ </td>
+</tr>
+
+[% IF Param('usetargetmilestone') -%]
+ <tr>
+ <th align="right">Default milestone:</th>
+ <td>
+ [% IF product.milestones.size %]
+ <select name="defaultmilestone">
+ [% FOREACH m = product.milestones %]
+ <option value="[% m.name FILTER html %]"
+ [% " selected=\"selected\"" IF m.name == product.defaultmilestone %]>
+ [%- m.name FILTER html -%]</option>
+ [% END %]
+ </select>
+ [% ELSE %]
+ <input type="text" size="64" maxlength="64" name="defaultmilestone"
+ value="[% product.defaultmilestone FILTER html %]">
+ [% END %]
+ </td>
+ </tr>
+[% END %]
+
+[% Hook.process('rows') %]
diff --git a/template/en/default/admin/products/edit.html.tmpl b/template/en/default/admin/products/edit.html.tmpl
new file mode 100644
index 0000000..c385301
--- /dev/null
+++ b/template/en/default/admin/products/edit.html.tmpl
@@ -0,0 +1,142 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: Bugzilla::Product object; The product
+ #
+ # (classification fields available if Param('useclassification') is enabled:)
+ #
+ # classification: Bugzilla::Classification object; The classification
+ # the product is in
+ #%]
+
+[% title = BLOCK %]Edit Product '[% product.name FILTER html %]'[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+ javascript_urls = ['js/util.js']
+%]
+
+[% group_control = {${constants.CONTROLMAPNA} => 'NA',
+ ${constants.CONTROLMAPSHOWN} => 'Shown',
+ ${constants.CONTROLMAPDEFAULT} => 'Default',
+ ${constants.CONTROLMAPMANDATORY} => 'Mandatory'}
+ %]
+
+<form method="post" action="editproducts.cgi">
+ <table border="0" cellpadding="4" cellspacing="0">
+
+ [% PROCESS "admin/products/edit-common.html.tmpl" %]
+
+ <tr>
+ <th align="right" valign="top">
+ <a href="editcomponents.cgi?product=[% product.name FILTER uri %]">
+ Edit components:
+ </a>
+ </th>
+ <td>
+ [% IF product.components.size -%]
+ [% FOREACH component = product.components %]
+ <a href="editcomponents.cgi?action=edit&product=
+ [%- product.name FILTER uri %]&component=
+ [%- component.name FILTER uri %]">[% component.name FILTER html %]</a>:&nbsp;
+ [% IF component.description %]
+ [% component.description FILTER html_light %]
+ [% ELSE %]
+ <font color="red">description missing</font>
+ [% END %]
+ <br>
+ [% END %]
+ [% ELSE %]
+ <font color="red">missing</font>
+ [% END %]
+ </td>
+ </tr>
+ <tr>
+ <th align="right" valign="top">
+ <a href="editversions.cgi?product=[% product.name FILTER uri %]">Edit
+versions:</a>
+ </th>
+ <td>
+ [%- IF product.versions.size -%]
+ [% FOREACH v = product.versions %]
+ [% v.name FILTER html %]
+ <br>
+ [% END %]
+ [% ELSE %]
+ <font color="red">missing</font>
+ [% END %]
+ </td>
+ </tr>
+ [% IF Param('usetargetmilestone') %]
+ <tr>
+ <th align="right" valign="top">
+ <a href="editmilestones.cgi?product=[% product.name FILTER uri %]">
+ Edit milestones:</a>
+ </th>
+ <td>
+ [%- IF product.milestones.size -%]
+ [%- FOREACH m = product.milestones -%]
+ [% m.name FILTER html %]
+ <br>
+ [% END %]
+ [% ELSE %]
+ <font color="red">missing</font>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+ <tr>
+ <th align="right" valign="top">
+ <a href="editproducts.cgi?action=editgroupcontrols&product=
+ [%- product.name FILTER uri %]">
+ Edit Group Access Controls:
+ </a>
+ </th>
+ <td>
+ [% IF product.group_controls.size %]
+ [% FOREACH g = product.group_controls.values.sort("name") %]
+ <b>[% g.group.name FILTER html %]:</b>&nbsp;
+ [% IF g.group.isactive %]
+ [% group_control.${g.membercontrol} FILTER html %]/
+ [% group_control.${g.othercontrol} FILTER html %]
+ [% IF g.entry %], ENTRY[% END %]
+ [% IF g.canedit %], CANEDIT[% END %]
+ [% IF g.editcomponents %], editcomponents[% END %]
+ [% IF g.canconfirm %], canconfirm[% END %]
+ [% IF g.editbugs %], editbugs[% END %]
+ [% ELSE %]
+ DISABLED
+ [% END %]
+ <br>
+ [% END %]
+ [% ELSE %]
+ no groups
+ [% END %]
+ </td>
+ </tr>
+ <tr>
+ <th align="right">[% terms.Bugs %]:</th>
+ <td><a href="buglist.cgi?product=[% product.name FILTER uri %]">
+ [% product.bug_count FILTER html %]</a></td>
+ </tr>
+ </table>
+
+ <input type="hidden" name="product_old_name"
+ value="[% product.name FILTER html %]">
+ <input type="hidden" name="action" value="update">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="submit" id="update-product" value="Save Changes">
+</form>
+
+[% PROCESS "admin/products/footer.html.tmpl"
+ no_add_product_link = 1
+ no_edit_product_link = 1 %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/products/footer.html.tmpl b/template/en/default/admin/products/footer.html.tmpl
new file mode 100644
index 0000000..689c5c9
--- /dev/null
+++ b/template/en/default/admin/products/footer.html.tmpl
@@ -0,0 +1,79 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: Bugzilla::Product Object; the product
+ #
+ # classification: Bugzilla::Classification object ; If classifications
+ # are enabled, then this is the currently
+ # selected classification
+ #
+ # no_XXX_link: boolean; if defined, then don't show the corresponding
+ # link. Supported parameters are:
+ #
+ # no_edit_product_link
+ # no_edit_other_products_link
+ # no_add_product_link
+ #%]
+
+[% IF Param('useclassification') && classification %]
+ [% classification_url_part = BLOCK %]&amp;classification=
+ [%- classification.name FILTER uri %]
+ [% END %]
+ [% classification_url_part_start = BLOCK %]classification=
+ [%- classification.name FILTER uri %]
+ [% END %]
+ [% classification_text = BLOCK %]
+ of classification '[% classification.name FILTER html %]'
+ [% END %]
+[% END %]
+
+<hr>
+
+<p>
+[% UNLESS no_add_product_link || !user.in_group("editcomponents") %]
+ <a title="Add a product"
+ href="editproducts.cgi?action=add">Add</a> a product[% -%]
+[%# Strictly speaking, we should not have to check for a
+ classification if they are enabled, but I'm just being paranoid %]
+ [% IF Param('useclassification') && classification %]
+ (<a title="Add a product to classification '
+ [%- classification.name FILTER html %]'"
+ href="editproducts.cgi?action=add
+ [%- classification_url_part %]">to
+ classification '[% classification.name FILTER html %]'</a>)
+ [% END %].
+[% END %]
+
+[% IF product && !no_edit_product_link %]
+ Edit product <a
+ title="Edit Product '[% product.name FILTER html %]'
+ [%- classification_text %]"
+ href="editproducts.cgi?action=edit&amp;product=[% product.name FILTER uri %]">
+ '[% product.name FILTER html %]'</a>.
+[% END %]
+
+
+[%# Edit other products (in a classification if specified): %]
+[% UNLESS no_edit_other_products_link %]
+ Edit <a
+ href="editproducts.cgi?
+ [%- classification_url_part_start FILTER none %]">other products
+ [% classification_text %]</a>.
+
+[% END %]
+
+[% IF Param('useclassification') && classification
+ && user.in_group('editclassifications') %]
+ Edit classification <a href="editclassifications.cgi?action=edit
+ [%- classification_url_part %]">'
+ [%- classification.name FILTER html %]'</a>.
+
+[% END %]
+
+</p>
diff --git a/template/en/default/admin/products/groupcontrol/confirm-edit.html.tmpl b/template/en/default/admin/products/groupcontrol/confirm-edit.html.tmpl
new file mode 100644
index 0000000..fc3ad9b
--- /dev/null
+++ b/template/en/default/admin/products/groupcontrol/confirm-edit.html.tmpl
@@ -0,0 +1,42 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% title = BLOCK %]
+ Confirm Group Control Change for product '[%- product.name FILTER html %]'
+[% END %]
+
+[% PROCESS global/header.html.tmpl title = title %]
+[% FOREACH group = mandatory_groups %]
+<P>
+group '[% group.name FILTER html %]' impacts [% group.count %]
+[%+ terms.bugs %] for
+which the group is newly mandatory and will be added.
+[% END %]
+
+[% FOREACH group = na_groups %]
+<P>
+group '[% group.name FILTER html %]' impacts [% group.count %]&nbsp;
+[% terms.bugs %] for which the group is no longer applicable and will
+be removed.[% END %]
+<form action="editproducts.cgi" method="post" >
+
+ [% PROCESS "global/hidden-fields.html.tmpl" exclude="^Bugzilla_(login|password)$" %]
+
+ <br>
+ Click "Continue" to proceed with the change including the changes
+ indicated above. If you do not want these changes, use "back" to
+ return to the previous page.
+ <p>
+ <input type="hidden" name="confirmed" value="confirmed">
+ <input type="submit" id="update" value="Continue">
+ </p>
+
+</form>
+
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/products/groupcontrol/edit.html.tmpl b/template/en/default/admin/products/groupcontrol/edit.html.tmpl
new file mode 100644
index 0000000..889647e
--- /dev/null
+++ b/template/en/default/admin/products/groupcontrol/edit.html.tmpl
@@ -0,0 +1,303 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% title = BLOCK %]
+ Edit Group Controls for [% product.name FILTER html %]
+[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+%]
+
+[% display_headers = 1 %]
+[% FOREACH group = product.group_controls(1).values.sort("name") %]
+ [% NEXT UNLESS group.group.isactive OR group.bug_count %]
+ [% IF display_headers %]
+ [% display_headers = 0 %]
+ <form method="post" action="editproducts.cgi">
+ <input type="hidden" name="action" value="updategroupcontrols">
+ <input type="hidden" name="product" value="[% product.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+
+ <table id="form" cellspacing="0" cellpadding="4" border="1">
+ <tr bgcolor="#6666ff">
+ <th>Group</th>
+ <th>Entry</th>
+ <th>MemberControl</th>
+ <th>OtherControl</th>
+ <th>Canedit</th>
+ <th>editcomponents</th>
+ <th>canconfirm</th>
+ <th>editbugs</th>
+ <th>[% terms.Bugs %]</th>
+ </tr>
+ [% END %]
+ [% IF !group.group.isactive %]
+ <tr bgcolor="#bbbbbb">
+ <td>[% group.group.name FILTER html %]</td>
+ <td align="center" colspan="7">Disabled</td>
+ <td>[% group.bug_count FILTER html %]</td>
+ </tr>
+ [% ELSE %]
+ <tr>
+ <td>[% group.group.name FILTER html %]</td>
+ <td>
+ <input type=checkbox value=1 name=entry_[% group.id %]
+ [% " checked='checked'" IF group.entry %]>
+ </td>
+ <td>
+ <select name="membercontrol_[% group.id %]">
+ <option value=[% constants.CONTROLMAPNA %]
+ [% " selected='selected'" IF group.membercontrol == constants.CONTROLMAPNA %]
+ >NA
+ </option>
+ <option value=[% constants.CONTROLMAPSHOWN %]
+ [% " selected='selected'" IF group.membercontrol == constants.CONTROLMAPSHOWN %]
+ >Shown
+ </option>
+ <option value=[% constants.CONTROLMAPDEFAULT %]
+ [% " selected='selected'" IF group.membercontrol == constants.CONTROLMAPDEFAULT %]
+ >Default
+ </option>
+ <option value=[% constants.CONTROLMAPMANDATORY %]
+ [% " selected='selected'" IF group.membercontrol == constants.CONTROLMAPMANDATORY %]
+ >Mandatory
+ </option>
+ </select>
+ </td>
+ <td>
+ <select name="othercontrol_[% group.id %]">
+ <option value=[% constants.CONTROLMAPNA %]
+ [% " selected='selected'" IF group.othercontrol == constants.CONTROLMAPNA %]
+ >NA
+ </option>
+ <option value=[% constants.CONTROLMAPSHOWN %]
+ [% " selected='selected'" IF group.othercontrol == constants.CONTROLMAPSHOWN %]
+ >Shown
+ </option>
+ <option value=[% constants.CONTROLMAPDEFAULT %]
+ [% " selected='selected'" IF group.othercontrol == constants.CONTROLMAPDEFAULT %]
+ >Default
+ </option>
+ <option value=[% constants.CONTROLMAPMANDATORY %]
+ [% " selected='selected'" IF group.othercontrol == constants.CONTROLMAPMANDATORY %]
+ >Mandatory
+ </option>
+ </select>
+ </td>
+ <td>
+ <input type=checkbox value=1 name=canedit_[% group.id %]
+ [% " checked='checked'" IF group.canedit %]>
+ </td>
+ <td>
+ <input type=checkbox value=1 name=editcomponents_[% group.id %]
+ [% " checked='checked'" IF group.editcomponents %]>
+ </td>
+ <td>
+ <input type=checkbox value=1 name=canconfirm_[% group.id %]
+ [% " checked='checked'" IF group.canconfirm %]>
+ </td>
+ <td>
+ <input type=checkbox value=1 name=editbugs_[% group.id %]
+ [% " checked='checked'" IF group.editbugs %]>
+ </td>
+ <td>[% group.bug_count || 0 FILTER html %]</td>
+ </tr>
+ [% END %]
+[% END %]
+
+[% IF display_headers %]
+ <p>No groups are available for products.
+ [% IF user.in_group('creategroups') %]
+ <a href="editgroups.cgi?action=add">Create a new group</a>
+ [% END %]
+ </p>
+[% ELSE %]
+ </table>
+ <br>
+ <input type=submit name="submit" value="submit">
+ </form>
+[% END %]
+
+<p>
+These settings control the relationship of the groups to this
+product.
+</p>
+<p>
+If any group has <b>Entry</b> selected, then this product will
+restrict [% terms.bug %] entry to only those users who are members of all the
+groups with entry selected.
+</p>
+<p>
+If any group has <b>Canedit</b> selected, then this product
+will be read-only for any users who are not members of all of
+the groups with Canedit selected. ONLY users who are members of
+all the canedit groups will be able to edit. This is an additional
+restriction that further restricts what can be edited by a user.
+</p>
+<p>
+The following settings control let you choose privileges on a <b>per-product basis</b>.
+This is a convenient way to give privileges to some users for some products
+only, without having to give them global privileges which would affect all
+products:
+</p>
+<p>
+Any group having <b>editcomponents</b> selected allows users who are
+in this group to edit all aspects of this product, including components,
+milestones and versions.
+</p>
+<p>
+Any group having <b>canconfirm</b> selected allows users who are
+in this group to confirm [% terms.bugs %] in this product.
+</p>
+<p>
+Any group having <b>editbugs</b> selected allows users who are
+in this group to edit all fields of [% terms.bugs %] in this product.
+</p>
+<p>
+The <b>MemberControl</b> and <b>OtherControl</b> fields
+indicate which [% terms.bugs %] will be placed in
+this group according to the following definitions.
+</p>
+
+<table border=1>
+ <tr>
+ <th>
+ MemberControl
+ </th>
+ <th>
+ OtherControl
+ </th>
+ <th>
+ Interpretation
+ </th>
+ </tr>
+ <tr>
+ <td>
+ NA
+ </td>
+ <td>
+ NA
+ </td>
+ <td>
+ [% terms.Bugs %] in this product are never associated with this group.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Shown
+ </td>
+ <td>
+ NA
+ </td>
+ <td>
+ [% terms.Bugs %] in this product are permitted to be restricted to this
+ group. Users who are members of this group will be able to place [% terms.bugs %] in
+ this group.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Shown
+ </td>
+ <td>
+ Shown
+ </td>
+ <td>
+ [% terms.Bugs %] in this product can be placed in this group by anyone
+ with permission to edit the [% terms.bug %] even if they are not a member
+ of this group.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Shown
+ </td>
+ <td>
+ Default
+ </td>
+ <td>
+ [% terms.Bugs %] in this product can be placed in this group by anyone
+ with permission to edit the [% terms.bug %] even if they are not a member
+ of this group. Non-members place [% terms.bugs %] in this group by default.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Shown
+ </td>
+ <td>
+ Mandatory
+ </td>
+ <td>
+ [% terms.Bugs %] in this product are permitted to be restricted to this
+ group. Users who are members of this group will be able to place [% terms.bugs %]
+ in this group. Non-members will be forced to restrict [% terms.bugs %] to
+ this group when they initially enter [% terms.abug %] in this product.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Default
+ </td>
+ <td>
+ NA
+ </td>
+ <td>
+ [% terms.Bugs %] in this product are permitted to be restricted to this
+ group and are placed in this group by default. Users who are members of this
+ group will be able to place [% terms.bugs %] in this group.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Default
+ </td>
+ <td>
+ Default
+ </td>
+ <td>
+ [% terms.Bugs %] in this product are permitted to be restricted to this
+ group and are placed in this group by default. Users who are members of this group
+ will be able to place [% terms.bugs %] in this group. Non-members will be
+ able to restrict [% terms.bugs %] to this group on entry and will do so by default.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Default
+ </td>
+ <td>
+ Mandatory
+ </td>
+ <td>
+ [% terms.Bugs %] in this product are permitted to be restricted to this
+ group and are placed in this group by default. Users who are members of this group
+ will be able to place [% terms.bugs %] in this group. Non-members will be forced
+ to place [% terms.bugs %] in this group on entry.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Mandatory
+ </td>
+ <td>
+ Mandatory
+ </td>
+ <td>
+ [% terms.Bugs %] in this product are required to be restricted to this
+ group. Users are not given any option.
+ </td>
+ </tr>
+</table>
+<p>
+Please note that the above table delineates the only allowable combinations
+for the <b>MemberControl</b> and <b>OtherControl</b> field settings.
+Attempting to submit a combination not listed there (e.g. Mandatory/NA,
+Default/Shown, etc.) will produce an error message.
+</p>
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/products/groupcontrol/updated.html.tmpl b/template/en/default/admin/products/groupcontrol/updated.html.tmpl
new file mode 100644
index 0000000..5ee066c
--- /dev/null
+++ b/template/en/default/admin/products/groupcontrol/updated.html.tmpl
@@ -0,0 +1,42 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: Bugzilla::Product object; the product.
+ # changes: Hashref with changes made to the product group controls.
+ #%]
+
+[% title = BLOCK %]
+ Update group access controls for [% product.name FILTER html %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+%]
+<p>
+[% IF changes._group_controls.now_na.size %]
+ [% FOREACH g = changes._group_controls.now_na %]
+ Removing [% terms.bugs %] from group '[% g.name FILTER html %]' which
+ no longer applies to this product<p>
+ [% g.bug_count FILTER html %] [%+ terms.bugs %] removed<p>
+ [% END %]
+[% END %]
+
+[% IF changes._group_controls.now_mandatory.size %]
+ [% FOREACH g = changes._group_controls.now_mandatory %]
+ Adding [% terms.bugs %] to group '[% g.name FILTER html %]' which is
+ mandatory for this product<p>
+ [% g.bug_count FILTER html %] [%+ terms.bugs %] added<p>
+ [% END %]
+[% END %]
+
+Group control updates done<p>
+
+[% PROCESS admin/products/footer.html.tmpl %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/products/list-classifications.html.tmpl b/template/en/default/admin/products/list-classifications.html.tmpl
new file mode 100644
index 0000000..ea32a00
--- /dev/null
+++ b/template/en/default/admin/products/list-classifications.html.tmpl
@@ -0,0 +1,58 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # classifications: array of hashes having the following properties:
+ # - name: string; The name of the classification
+ # - description: string; The classification description (html allowed)
+ # - product_count: number; The number of products in this classification
+ #
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Select Classification"
+%]
+
+[% columns = [
+ {
+ name => "name"
+ heading => "Edit products of..."
+ contentlink => 'editproducts.cgi?classification=%%name%%'
+ },
+ {
+ name => "description"
+ heading => "Description"
+ allow_html_content => 1
+ },
+ {
+ name => "product_count"
+ align => "right"
+ heading => "Product Count"
+ }
+ ]
+%]
+
+[% IF user.in_group('editcomponents') %]
+ [% columns.push({
+ heading => "Action..."
+ content => "Add product"
+ contentlink => 'editproducts.cgi?action=add&amp;classification=%%name%%' })
+ %]
+[% END %]
+
+[% Hook.process('before_table') %]
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ data = classifications
+%]
+
+[%# No need for the standard edit products footer, as we have an 'add'
+ link in the table %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/products/list.html.tmpl b/template/en/default/admin/products/list.html.tmpl
new file mode 100644
index 0000000..a5126af
--- /dev/null
+++ b/template/en/default/admin/products/list.html.tmpl
@@ -0,0 +1,86 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # products: array of Bugzilla::Product objects
+ #
+ # classification: Bugzilla::Classification object; If classifications
+ # are enabled, then this is
+ # the currently selected classification
+ # showbugcounts: boolean; true if bug counts should be included in the table
+ #%]
+
+[% IF classification %]
+ [% classification_url_part = BLOCK %]&amp;classification=
+ [%- classification.name FILTER uri %]
+ [%- END %]
+ [% classification_title = BLOCK %]
+ in classification '[% classification.name FILTER html %]'
+ [% END %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = "Select product $classification_title"
+%]
+
+[% columns = [
+ {
+ name => "name"
+ heading => "Edit product..."
+ contentlink => 'editproducts.cgi?action=edit&amp;product=%%name%%'
+ },
+ {
+ name => "description"
+ heading => "Description"
+ allow_html_content => 1
+ },
+ {
+ name => "is_active"
+ heading => "Open For New $terms.Bugs"
+ yesno_field => 1
+ },
+] %]
+
+[% IF showbugcounts %]
+
+ [% columns.push({
+ name => "bug_count"
+ heading => "$terms.Bug Count"
+ align => 'right'
+ contentlink => 'buglist.cgi?product=%%name%%'
+ })
+ %]
+
+[% END %]
+
+[% columns.push({
+ heading => "Action"
+ content => "Delete"
+ contentlink => 'editproducts.cgi?action=del&amp;product=%%name%%'
+ })
+%]
+
+[% Hook.process('before_table') %]
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ data = products
+%]
+
+[% IF !showbugcounts %]
+
+ <p><a href="editproducts.cgi?showbugcounts=1[% classification_url_part %]">
+ Redisplay table with [% terms.bug %] counts (slower)</a></p>
+
+[% END %]
+
+[% PROCESS admin/products/footer.html.tmpl
+ no_edit_other_products_link = 1
+ %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/products/updated.html.tmpl b/template/en/default/admin/products/updated.html.tmpl
new file mode 100644
index 0000000..4d22801
--- /dev/null
+++ b/template/en/default/admin/products/updated.html.tmpl
@@ -0,0 +1,90 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product : Bugzilla::Product Object; new product.
+ # classification: Bugzilla::Classification Object; The product classification (may be empty or missing)
+ # changes: hashref with all changes made to the product. Each key is an edited field,
+ # and its value is an arrayref of the form [old values, new values].
+ #%]
+
+[% IF classification %]
+ [% classification_text = BLOCK %]
+ of classification '[% classification.name FILTER html %]'
+ [% END %]
+[% END %]
+
+[% title = BLOCK %]Updating Product '[% product.name FILTER html %]'
+ [% classification_text FILTER none %][% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+%]
+
+[% IF changes.name.defined %]
+ <p>
+ Updated product name from '[% changes.name.0 FILTER html %]' to
+ '<a href="editproducts.cgi?action=edit&amp;product=
+ [%- product.name FILTER uri %]">[% product.name FILTER html %]</a>'.
+ </p>
+[% END %]
+
+
+[% IF changes.description.defined %]
+ <p>
+ Updated description to:
+ </p>
+ <p style="margin: 1em 3em 1em 3em">[% product.description FILTER html_light %]</p>
+[% END %]
+
+[% IF changes.isactive.defined %]
+ <p>
+ Product is now
+ [% IF product.is_active %]
+ open for
+ [% ELSE %]
+ closed to
+ [% END %]
+ new [% terms.bugs %].
+ </p>
+[% END %]
+
+[% IF changes.defaultmilestone.defined %]
+ <p>
+ Updated default milestone from '[% changes.defaultmilestone.0 FILTER html %]' to
+ '[% product.default_milestone FILTER html %]'.
+ </p>
+[% END %]
+
+[% IF changes.allows_unconfirmed.defined %]
+ <p>
+ [% IF product.allows_unconfirmed %]
+ The product now allows the
+ [%+ display_value('bug_status', 'UNCONFIRMED') FILTER html %] status.
+ [% ELSE %]
+ The product no longer allows the
+ [%+ display_value('bug_status', 'UNCONFIRMED') FILTER html %] status.
+ Note that any
+ <a href="buglist.cgi?product=
+ [%- product.name FILTER uri %]&amp;bug_status=UNCONFIRMED">
+ [%- terms.bugs %] that currently have the
+ [%+ display_value('bug_status', 'UNCONFIRMED') FILTER html %] status</a>
+ will remain in that status until they are edited.
+ [% END %]
+ </p>
+[% END %]
+
+[% Hook.process('changes') %]
+
+[% IF !changes.keys.size %]
+ <p>Nothing changed for product '[% product.name FILTER html %]'.</p>
+[% END %]
+
+[% PROCESS admin/products/footer.html.tmpl %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/sanitycheck/list.html.tmpl b/template/en/default/admin/sanitycheck/list.html.tmpl
new file mode 100644
index 0000000..6814662
--- /dev/null
+++ b/template/en/default/admin/sanitycheck/list.html.tmpl
@@ -0,0 +1,26 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS global/header.html.tmpl title = "Sanity Check"
+ style_urls = ['skins/standard/admin.css'] %]
+
+<div>
+ <p>
+ [% terms.Bugzilla %] is checking the referential integrity of your database.
+ This may take several minutes to complete.
+ </p>
+
+ <p>
+ Errors, if any, will be <span class="alert">emphasized like this</span>.
+ Depending on the errors found, some links will be displayed allowing you
+ to easily fix them. Fixing these errors will automatically run this script
+ again (so be aware that it may take an even longer time than the first run).
+ </p>
+</div>
+
+<hr>
diff --git a/template/en/default/admin/sanitycheck/messages.html.tmpl b/template/en/default/admin/sanitycheck/messages.html.tmpl
new file mode 100644
index 0000000..bb5ca06
--- /dev/null
+++ b/template/en/default/admin/sanitycheck/messages.html.tmpl
@@ -0,0 +1,312 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% san_message = BLOCK %]
+ [% IF san_tag == "checks_start" %]
+ OK, now running sanity checks.
+
+ [% ELSIF san_tag == "checks_completed" %]
+ Sanity check completed.
+
+ [% ELSIF san_tag == "attachment_reference_deletion_start" %]
+ OK, now removing all references to deleted attachments.
+
+ [% ELSIF san_tag == "attachment_reference_deletion_end" %]
+ All references to deleted attachments have been removed.
+
+ [% ELSIF san_tag == "bug_check_alert" %]
+ [% errortext FILTER html %]: [% INCLUDE bug_list badbugs = badbugs %]
+
+ [% ELSIF san_tag == "bug_check_repair" %]
+ <a href="sanitycheck.cgi?[% param FILTER uri %]=1&amp;token=
+ [%- issue_hash_token(['sanitycheck']) FILTER uri %]">[% text FILTER html %]</a>.
+
+ [% ELSIF san_tag == "bug_check_creation_date" %]
+ Checking for [% terms.bugs %] with no creation date (which makes them invisible).
+
+ [% ELSIF san_tag == "bug_check_creation_date_error_text" %]
+ [% terms.Bugs %] with no creation date
+
+ [% ELSIF san_tag == "bug_check_creation_date_repair_text" %]
+ Repair missing creation date for these [% terms.bugs %]
+
+ [% ELSIF san_tag == "bug_check_bugs_fulltext" %]
+ Checking for [% terms.bugs %] with no entry for full text searching.
+
+ [% ELSIF san_tag == "bug_check_bugs_fulltext_error_text" %]
+ [% terms.Bugs %] with no entry for full text searching
+
+ [% ELSIF san_tag == "bug_check_bugs_fulltext_repair_text" %]
+ Repair missing full text search entries for these [% terms.bugs %]
+
+ [% ELSIF san_tag == "bug_check_res_dupl" %]
+ Checking resolution/duplicates
+
+ [% ELSIF san_tag == "bug_check_res_dupl_error_text" %]
+ [% terms.Bugs %] found on duplicates table that are not marked duplicate
+
+ [% ELSIF san_tag == "bug_check_res_dupl_error_text2" %]
+ [% terms.Bugs %] found marked resolved duplicate and not on duplicates table
+
+ [% ELSIF san_tag == "bug_check_status_res" %]
+ Checking statuses/resolutions
+
+ [% ELSIF san_tag == "bug_check_status_res_error_text" %]
+ [% terms.Bugs %] with open status and a resolution
+
+ [% ELSIF san_tag == "bug_check_status_res_error_text2" %]
+ [% terms.Bugs %] with non-open status and no resolution
+
+ [% ELSIF san_tag == "bug_check_status_everconfirmed" %]
+ Checking statuses/everconfirmed
+
+ [% ELSIF san_tag == "bug_check_status_everconfirmed_error_text" %]
+ [% terms.Bugs %] that are UNCONFIRMED but have everconfirmed set
+
+ [% ELSIF san_tag == "bug_check_status_everconfirmed_error_text2" %]
+ [% terms.Bugs %] with confirmed status but don't have everconfirmed set
+
+ [% ELSIF san_tag == "bug_check_control_values" %]
+ Checking for bad values in group_control_map
+
+ [% ELSIF san_tag == "bug_check_control_values_alert" %]
+ Found [% entries FILTER html %] bad group_control_map entries
+
+ [% ELSIF san_tag == "bug_check_control_values_violation" %]
+ Checking for [% terms.bugs %] with groups violating their product's group controls
+
+ [% ELSIF san_tag == "bug_check_control_values_error_text" %]
+ Have groups not permitted for their products
+
+ [% ELSIF san_tag == "bug_check_control_values_repair_text" %]
+ Permit the missing groups for the affected products
+ (set member control to <code>SHOWN</code>)
+
+ [% ELSIF san_tag == "bug_check_control_values_error_text2" %]
+ Are missing groups required for their products
+
+ [% ELSIF san_tag == "bug_creation_date_start" %]
+ OK, now fixing missing [% terms.bug %] creation dates.
+
+ [% ELSIF san_tag == "bug_creation_date_fixed" %]
+ [% bug_count FILTER html %] [%+ terms.bugs %] have been fixed.
+
+ [% ELSIF san_tag == "bugs_fulltext_start" %]
+ OK, now fixing [% terms.bug %] entries for full text searching.
+
+ [% ELSIF san_tag == "bugs_fulltext_fixed" %]
+ [% bug_count FILTER html %] [%+ terms.bugs %] have been fixed.
+
+ [% ELSIF san_tag == "bug_reference_deletion_start" %]
+ OK, now removing all references to deleted [% terms.bugs %].
+
+ [% ELSIF san_tag == "bug_reference_deletion_end" %]
+ All references to deleted [% terms.bugs %] have been removed.
+
+ [% ELSIF san_tag == "cross_check_to" %]
+ Checking references to [% table FILTER html %].[% field FILTER html %]...
+
+ [% ELSIF san_tag == "cross_check_from" %]
+ ... from [% table FILTER html %].[% field FILTER html %].
+
+ [% ELSIF san_tag == "cross_check_alert" %]
+ Bad value '[% value FILTER html %]' found in
+ [%+ table FILTER html %].[% field FILTER html %]
+ [% IF keyname %]
+ [% IF keyname == "bug_id" %]
+ ([% PROCESS bug_link bug_id = key %])
+ [% ELSE %]
+ ([% keyname FILTER html %] == '[% key FILTER html %]')
+ [% END %]
+ [% END %]
+
+ [% ELSIF san_tag == "cross_check_attachment_has_references" %]
+ <a href="sanitycheck.cgi?remove_invalid_attach_references=1&amp;token=
+ [%- issue_hash_token(['sanitycheck']) FILTER uri %]">Remove
+ invalid references to non existent attachments.</a>
+
+ [% ELSIF san_tag == "cross_check_bug_has_references" %]
+ <a href="sanitycheck.cgi?remove_invalid_bug_references=1&amp;token=
+ [%- issue_hash_token(['sanitycheck']) FILTER uri %]">Remove
+ invalid references to non existent [% terms.bugs %].</a>
+
+ [% ELSIF san_tag == "double_cross_check_to" %]
+ Checking references to [% table FILTER html %].[% field1 FILTER html %] /
+ [%+ table FILTER html %].[% field2 FILTER html %]...
+
+ [% ELSIF san_tag == "double_cross_check_from" %]
+ ... from [% table FILTER html %].[% field1 FILTER html %] /
+ [%+ table FILTER html %].[% field2 FILTER html %].
+
+ [% ELSIF san_tag == "double_cross_check_alert" %]
+ Bad values '[% value1 FILTER html %]', '[% value2 FILTER html %]' found
+ in [% table FILTER html %].[% field1 FILTER html %] /
+ [%+ table FILTER html %].[% field2 FILTER html %].
+ [% IF keyname %]
+ [% IF keyname == "bug_id" %]
+ ([% PROCESS bug_link bug_id = key %])
+ [% ELSE %]
+ ([% keyname FILTER html %] == '[% key FILTER html %]')
+ [% END %]
+ [% END %]
+
+ [% ELSIF san_tag == "everconfirmed_start" %]
+ OK, now fixing everconfirmed.
+
+ [% ELSIF san_tag == "everconfirmed_end" %]
+ everconfirmed fixed.
+
+ [% ELSIF san_tag == "flag_check_start" %]
+ Checking for flags being in the wrong product/component.
+
+ [% ELSIF san_tag == "flag_deletion_start" %]
+ OK, now deleting invalid flags.
+
+ [% ELSIF san_tag == "flag_deletion_end" %]
+ Invalid flags deleted.
+
+ [% ELSIF san_tag == "flag_alert" %]
+ Invalid flag [% flag_id FILTER html %] for
+ [% IF attach_id %]
+ attachment [% attach_id FILTER html %] in
+ [% END %]
+ [%+ PROCESS bug_link bug_id = bug_id %].
+
+ [% ELSIF san_tag == "flag_fix" %]
+ <a href="sanitycheck.cgi?remove_invalid_flags=1&amp;token=
+ [%- issue_hash_token(['sanitycheck']) FILTER uri %]">Click
+ here to delete invalid flags</a>
+
+ [% ELSIF san_tag == "group_control_map_entries_creation" %]
+ OK, now creating <code>SHOWN</code> member control entries
+ for product/group combinations lacking one.
+
+ [% ELSIF san_tag == "group_control_map_entries_update" %]
+ Updating <code>NA/<em>xxx</em></code> group control setting
+ for group <em>[% group_name FILTER html %]</em> to
+ <code>SHOWN/<em>xxx</em></code> in product
+ <em>[% product_name FILTER html %]</em>.
+
+ [% ELSIF san_tag == "group_control_map_entries_generation" %]
+ Generating <code>SHOWN/NA</code> group control setting
+ for group <em>[% group_name FILTER html %]</em> in product
+ <em>[% product_name FILTER html %]</em>.
+
+ [% ELSIF san_tag == "group_control_map_entries_repaired" %]
+ Repaired [% counter FILTER html %] defective group control settings.
+
+ [% ELSIF san_tag == "keyword_check_start" %]
+ Checking keywords table.
+
+ [% ELSIF san_tag == "keyword_check_alert" %]
+ Duplicate entry in keyworddefs for id [% id FILTER html %].
+
+ [% ELSIF san_tag == "keyword_check_invalid_name" %]
+ Bogus name in keyworddefs for id [% id FILTER html %].
+
+ [% ELSIF san_tag == "keyword_check_invalid_id" %]
+ Bogus keywordids [% id FILTER html %] found in keywords table.
+
+ [% ELSIF san_tag == "keyword_check_duplicated_ids" %]
+ Duplicate keyword IDs found in [% PROCESS bug_link bug_id = id %].
+
+ [% ELSIF san_tag == "profile_login_start" %]
+ Checking profile logins.
+
+ [% ELSIF san_tag == "product_alert" %]
+ Product <a href="editproducts.cgi?product=[% name FILTER html%]">
+ [%- name FILTER html %]</a> has no components or no versions.
+
+ [% ELSIF san_tag == "product_check_start" %]
+ Checking products with no components or versions.
+
+ [% ELSIF san_tag == "profile_login_alert" %]
+ Bad profile email address, id=[% id FILTER html %],
+ &lt;[% email FILTER html %]&gt;.
+
+ [% ELSIF san_tag == "repair_bugs" %]
+ Repair these [% terms.bugs %].
+
+ [% ELSIF san_tag == "send_bugmail_start" %]
+ OK, now attempting to send unsent mail.
+
+ [% ELSIF san_tag == "send_bugmail_status" %]
+ [% bug_count FILTER html %] [%+ terms.bugs %] found with
+ possibly unsent mail.
+
+ [% ELSIF san_tag == "send_bugmail_end" %]
+ Unsent mail has been sent.
+
+ [% ELSIF san_tag == "unsent_bugmail_check" %]
+ Checking for unsent mail
+
+ [% ELSIF san_tag == "unsent_bugmail_alert" %]
+ [% terms.Bugs %] that have changes but no mail sent for at least
+ half an hour: [% INCLUDE bug_list badbugs = badbugs %]
+
+ [% ELSIF san_tag == "unsent_bugmail_fix" %]
+ <a href="sanitycheck.cgi?rescanallBugMail=1&amp;token=
+ [%- issue_hash_token(['sanitycheck']) FILTER uri %]">Send these mails</a>.
+
+ [% ELSIF san_tag == "whines_obsolete_target_deletion_start" %]
+ OK, now removing non-existent users/groups from whines.
+
+ [% ELSIF san_tag == "whines_obsolete_target_deletion_end" %]
+ Non-existent users/groups have been removed from whines.
+
+ [% ELSIF san_tag == "whines_obsolete_target_start" %]
+ Checking for whines with non-existent users/groups.
+
+ [% ELSIF san_tag == "whines_obsolete_target_alert" %]
+ [% FOREACH schedule = schedules %]
+ Non-existent [% (type == constants.MAILTO_USER) ? "user" : "group" FILTER html %]
+ [%+ schedule.1 FILTER html %] for whine schedule [% schedule.0 FILTER html %]<br>
+ [% END %]
+
+ [% ELSIF san_tag == "whines_obsolete_target_fix" %]
+ <a href="sanitycheck.cgi?remove_old_whine_targets=1&amp;token=
+ [%- issue_hash_token(['sanitycheck']) FILTER uri %]">Click here to
+ remove old users/groups</a>
+
+ [% ELSE %]
+ [% message = Hook.process("statuses") %]
+
+ [% IF message %]
+ [% message FILTER none %]
+ [% ELSE %]
+ The status message string <code>[% san_tag FILTER html %]</code>
+ was not found. Please send email to [% Param("maintainer") %] describing
+ the steps taken to obtain this message.
+ [% END %]
+
+ [% END %]
+[% END %]
+
+[% USE Bugzilla %]
+[% IF Bugzilla.usage_mode == constants.USAGE_MODE_CMDLINE %]
+ [% san_message FILTER none %]
+[% ELSE %]
+ [%# Avoid the txt filter in message.txt.tmpl. %]
+ [% san_message FILTER html %]
+[% END %]
+
+[% BLOCK bug_list %]
+ [% FOREACH bug_id = badbugs %]
+ [%# Do not use FILTER bug_link() here, because bug_link() calls get_text()
+ # which itself calls this template again, generating a recursion error.
+ # I doubt having a tooltip with the bug status and summary is so
+ # important here anyway, as you can click the "(as buglist)" link. %]
+ <a href="show_bug.cgi?id=[% bug_id FILTER uri %]">[% bug_id FILTER html %]</a>
+ [% ", " IF !loop.last %]
+ [% END %]
+ (<a href="buglist.cgi?bug_id=[% badbugs.join(",") FILTER uri %]">as [% terms.bug %] list</a>).
+[% END %]
+
+[% BLOCK bug_link %]
+ <a href="show_bug.cgi?id=[% bug_id FILTER uri %]">[% terms.bug %] [%+ bug_id FILTER html %]</a>
+[% END %]
diff --git a/template/en/default/admin/settings/edit.html.tmpl b/template/en/default/admin/settings/edit.html.tmpl
new file mode 100644
index 0000000..411c527
--- /dev/null
+++ b/template/en/default/admin/settings/edit.html.tmpl
@@ -0,0 +1,93 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # settings: a hash of hashes, keyed by setting name.
+ # Each hash contains:
+ # is_enabled - boolean
+ # default_value - string (global default for this setting)
+ # value - string (user-defined preference)
+ # is_default - boolean (true if user has no preference)
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Default Preferences"
+ %]
+
+[% PROCESS "global/setting-descs.none.tmpl" %]
+
+<p>
+This lets you edit the default preferences values.
+</p>
+<p>
+The Default Value displayed for each preference will apply to all users who
+do not choose their own value, and to anyone who is not logged in.
+</p>
+<p>
+The 'Enabled' checkbox controls whether or not this preference is available
+to users.<br>
+If it is checked, users will see this preference on their User Preferences page,
+and will be allowed to choose their own value if they desire.<br>
+If it is not checked, this preference will not appear on the User Preference
+page, and the Default Value will automatically apply to everyone.
+</p>
+<hr>
+
+[% IF settings.size %]
+ <form name="adminsettingform" method="post" action="editsettings.cgi">
+ <table border="1" cellpadding="4">
+ <tr>
+ <th>Preference Text</th>
+ <th>Default Value</th>
+ <th>Enabled</th>
+ </tr>
+
+ [% FOREACH name = settings.keys %]
+ [% checkbox_name = name _ '-enabled' %]
+ <tr>
+ <td align="right">
+ [% setting_descs.$name OR name FILTER html %]
+ </td>
+ <td>
+ <select name="[% name FILTER html %]" id="[% name FILTER html %]">
+ [% FOREACH x = settings.${name}.legal_values %]
+ <option value="[% x FILTER html %]"
+ [% " selected=\"selected\"" IF x == settings.${name}.default_value %]>
+ [% setting_descs.${x} OR x FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ </td>
+ <td align="center">
+ <input type="checkbox"
+ name="[% checkbox_name FILTER html %]"
+ id="[% checkbox_name FILTER html %]"
+ [% " checked=\"checked\"" IF settings.${name}.is_enabled %]>
+ <br>
+ </td>
+ </tr>
+ [% END %]
+ </table>
+
+ <input type="hidden" name="action" value="update">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <table>
+ <tr>
+ <td width="150"></td>
+ <td>
+ <input type="submit" id="update" value="Submit Changes">
+ </td>
+ </tr>
+ </table>
+
+ </form>
+[% ELSE %]
+ There are no preferences to edit.
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/sudo.html.tmpl b/template/en/default/admin/sudo.html.tmpl
new file mode 100644
index 0000000..4d072f1
--- /dev/null
+++ b/template/en/default/admin/sudo.html.tmpl
@@ -0,0 +1,91 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Begin sudo session"
+ style_urls = ['skins/standard/admin.css']
+ doc_section = "useradmin.html#impersonatingusers"
+ %]
+
+[% DEFAULT target_login = "" %]
+
+<p>
+ The <b>sudo</b> feature of [% terms.Bugzilla %] allows you to impersonate a
+ user for a short time While an sudo session is in progress, every action you
+ perform will be taking place as if you had logged in as the user whom will be
+ impersonating.
+</p>
+
+<p class="areyoureallyreallysure">
+ This is a very powerful feature; you should be very careful while using it.
+ Your actions may be logged more carefully than normal.
+</p>
+
+<form action="relogin.cgi" method="POST">
+ <p>
+ To begin,
+ [% IF Param('usemenuforusers') %]
+ select
+ [% ELSE %]
+ enter the login of
+ [% END %]
+ <label for="target_login">the <u>u</u>ser to impersonate</label>:
+ [% INCLUDE global/userselect.html.tmpl
+ id => "target_login"
+ name => "target_login"
+ value => target_login_default
+ accesskey => "u"
+ size => 30
+ %]
+ </p>
+
+ [% IF !Param('usemenuforusers') %]
+ <p>
+ The username must be entered exactly. No matching will be performed.
+ </p>
+ [% END %]
+
+ <p>
+ Next, please take a moment to explain <label for="reason">why you are doing
+ this:<br>
+ <input type="text" id="reason" name="reason" size="80" maxlength="200"
+ value="[% reason_default FILTER html %]">
+ </p>
+
+ <p>
+ The message you enter here will be sent to the impersonated user by email.
+ You may leave this empty if you wish, but they will still know that you
+ are impersonating them.
+ </p>
+
+ [% IF user.authorizer.can_login %]
+ <p>
+ Finally, enter <label for="Bugzilla_password">your [% terms.Bugzilla %]
+ password</label>:
+ <input type="hidden" name="Bugzilla_login" value="[% user.login FILTER html %]">
+ <input type="password" id="Bugzilla_password" name="Bugzilla_password" size="20">
+ <input type="hidden" name="Bugzilla_login_token"
+ value="[% login_request_token FILTER html %]">
+ <br>
+ This is done for two reasons. First of all, it is done to reduce
+ the chances of someone doing large amounts of damage using your
+ already-logged-in account. Second, it is there to force you to take the
+ time to consider if you really need to use this feature.
+ </p>
+ [% END %]
+
+ <p>
+ Click the button to begin the session:
+ <input type="submit" id="begin_sudo" value="Begin Session">
+ <input type="hidden" name="action" value="begin-sudo">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ </p>
+
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/table.html.tmpl b/template/en/default/admin/table.html.tmpl
new file mode 100644
index 0000000..80f6417
--- /dev/null
+++ b/template/en/default/admin/table.html.tmpl
@@ -0,0 +1,164 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ #
+ # columns:
+ # array of hashes representing the columns in the table.
+ # Each hash contains data for a single column. Hash keys:
+ # name: Name of the field in the data param
+ # heading: The text to print at the header cell
+ # contentlink: URI to which the content of a data cell shall be linked to.
+ # Expressions of format %%xxx%% are replaced with value
+ # with the key xxx in data hash of the current row.
+ # content: If specified, the content of this variable is used
+ # instead of the data pulled from the current row.
+ # NOTE: This value is only partially HTML filtered!
+ # content_use_field: If defined and true, then each value in the
+ # column corresponds with a key in the
+ # field_descs field, and that value from the
+ # field_descs hash will be used instead of "content."
+ # See fieldvalues/select-field for an example of use.
+ # This content WILL be HTML-filtered in this case.
+ # align: left/center/right. Controls the horizontal alignment of the
+ # text in the column.
+ # allow_html_content: if defined, then this column allows some html content
+ # and so it will be only partially filtered.
+ # yesno_field: Turn the data from 0/!0 into Yes/No
+ #
+ # data:
+ # array of hashes representing the data for the table.
+ # Each hash contains data for a single row of data. The
+ # keys are column names from columns subhashes name field.
+ #
+ # overrides:
+ # Example:
+ # overrides { # first hash
+ # column_name_to_be_overwriten => { # second hash
+ # name_of_row_to_match_against => { # third hash
+ # value_to_match_against => { # fourth hash
+ # content => "some contents"
+ # override_content => 1
+ # }
+ # }
+ # }
+ # }
+ #
+ # Provides a method for overriding individual table cells. This is a hash
+ # (1), whose key is the column name, so the column must be named for
+ # one of it's cells to be overwritten. The hash value is another hash
+ # (2). The keys of that second hash are the name of the row to match
+ # against. The second hash then again points to another hash. Within this
+ # third hash (3), the keys represent values to match against. The item
+ # contains a fourth hash (4) specifying overridden values.
+ #
+ # Each column value mentioned in the 'columns' documentation above
+ # can be overwritten (apart from name and heading). To override a
+ # table-cell value 'xxx', specify a new 'xxx' value, and specify a
+ # 'override_xxx' value as well. See
+ # admin/milestones/list.html.tmpl for example
+ #
+ #%]
+
+[%################### TABLE HEADER ######################%]
+
+<table id="admin_table" border="1" cellpadding="4" cellspacing="0">
+ <tr bgcolor="#6666FF">
+ [% FOREACH c = columns %]
+ [%# Default to align left for headers %]
+ <th align="[% (c.align || 'left') FILTER html %]">
+ [% c.heading FILTER html %]
+ </th>
+ [% END %]
+ </tr>
+
+
+[%################### TABLE CONTENT ######################%]
+
+[% FOREACH row = data %]
+
+ <tr>
+ [% FOREACH c = columns %]
+
+ [%# Copy to local variables, as we may update these %]
+ [% contentlink = c.contentlink
+ content = c.content
+ content_use_field = c.content_use_field
+ align = c.align
+ class = c.class
+ allow_html_content = c.allow_html_content
+ yesno_field = c.yesno_field
+ %]
+
+ [%# Get any specific "important" overrides for this c.name and row.name ? %]
+ [% SET important = overrides.${c.name}.name.${row.name} %]
+
+ [% IF important %]
+
+ [% FOREACH key IN important.keys %]
+ [% SET ${key} = important.${key} %]
+ [% END %]
+
+ [% ELSE %]
+
+ [%# Are there any specific overrides for this column? %]
+ [% FOREACH match_field = overrides.${c.name}.keys %]
+
+ [% override = overrides.${c.name}.${match_field}.${row.$match_field} %]
+ [% NEXT UNLESS override %]
+
+ [% FOREACH key IN override.keys %]
+ [% SET ${key} = override.${key} %]
+ [% END %]
+
+ [% LAST %]
+
+ [% END %]
+ [% END %]
+
+ <td [% IF align %] align="[% align FILTER html %]" [% END %]
+ [% IF class %] class="[% class FILTER html %]" [% END %]>
+
+ [% IF contentlink %]
+ [% FOREACH m = contentlink.match('%%(.+?)%%', 1) %]
+ [% replacement_value = FILTER uri; row.$m; END %]
+ [% contentlink = contentlink.replace("%%$m%%", replacement_value) %]
+ [% END %]
+ <a href="[% contentlink %]">
+ [% END %]
+
+ [% IF content_use_field %]
+ [% colname = row.${c.name} %]
+ [% field_descs.${colname} FILTER html %]
+ [% ELSIF content %]
+ [% content FILTER html_light %]
+ [% ELSIF yesno_field %]
+ [% row.${c.name} ? "Yes" : "No" %]
+ [% ELSIF allow_html_content %]
+ [% row.${c.name} FILTER html_light %]
+ [% ELSE %]
+ [% row.${c.name} FILTER html %]
+ [% END %]
+
+ [% IF contentlink %]
+ </a>
+ [% END %]
+
+ </td>
+ [% END %]
+ </tr>
+[% END %]
+
+[% IF data.size == 0 %]
+ <tr><td colspan="[% columns.size %]" align="center"><i>&lt;none&gt;</i></td></tr>
+[% END %]
+
+
+[%################### TABLE FOOTER ######################%]
+
+</table>
diff --git a/template/en/default/admin/users/confirm-delete.html.tmpl b/template/en/default/admin/users/confirm-delete.html.tmpl
new file mode 100644
index 0000000..73a72d0
--- /dev/null
+++ b/template/en/default/admin/users/confirm-delete.html.tmpl
@@ -0,0 +1,471 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ #
+ # listselectionvalues: selection values to recreate the current user
+ # list.
+ # editusers: is viewing user member of editusers?
+ # otheruser: Bugzilla::User object of the viewed user.
+ # reporter: number of bugs reported by the user
+ # assignee_or_qa: number of bugs the user is either the assignee
+ # or the QA contact
+ # bugs_activity: number of bugs the viewed user has activity
+ # entries on
+ # cc number of bugs the viewed user is cc list member
+ # of
+ # flags.requestee: number of flags the viewed user is being asked for
+ # flags.setter: number of flags the viewed user has set
+ # longdescs: number of bug comments the viewed user has written
+ # namedqueries: number of named queries the user has created
+ # namedquery_group_map: number of named queries the user has shared
+ # profiles_activity: number of changes made to other users' profiles
+ # series: number of series the viewed user has created
+ # watch.watched: number of users the viewed user is being watched
+ # by
+ # watch.watcher: number of users the viewed user is watching
+ # whine_events: number of whine events the viewed user has created
+ # whine_schedules: number of whine schedules the viewed user has
+ # created
+ #%]
+
+[% title = BLOCK %]Confirm deletion of user [% otheruser.login FILTER html %][% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css',
+ 'skins/standard/editusers.css']
+ doc_section = "useradmin.html#user-account-deletion"
+%]
+
+[% PROCESS admin/users/listselectvars.html.tmpl
+ listselectionvalues = listselectionvalues
+%]
+
+<table class="main">
+ <tr>
+ <th>Login name:</th>
+ <td>[% otheruser.login FILTER html %]</td>
+ </tr>
+ <tr>
+ <th>Real name:</th>
+ <td>[% otheruser.name FILTER html %]</td>
+ </tr>
+ <tr>
+ <th>Group set:</th>
+ <td>
+ [% IF otheruser.groups.size %]
+ <ul>
+ [% FOREACH group = otheruser.groups %]
+ <li>[% group.name FILTER html %]</li>
+ [% END %]
+ </ul>
+ [% ELSE %]
+ None
+ [% END %]
+ </td>
+ </tr>
+ [% IF otheruser.product_responsibilities.size %]
+ <tr>
+ <th>Product responsibilities:</th>
+ <td>
+ [% PROCESS admin/users/responsibilities.html.tmpl otheruser = otheruser %]
+ </td>
+ </tr>
+ [% END %]
+</table>
+
+[% IF otheruser.product_responsibilities.size %]
+ <p>
+ You can't delete this user at this time because
+ [%+ otheruser.login FILTER html %] has got responsibilities for at least
+ one product.
+ </p>
+ <p>
+ [% IF user.in_group("editcomponents", component.product_id) %]
+ Change this by clicking the product editing links above,
+ [% ELSE %]
+ For now, you can
+ [% END %]
+[% ELSE %]
+ [% accept_deletion = 1 %]
+
+ [% IF attachments || reporter || bugs_activity || flags.setter || longdescs || profiles_activity %]
+ <div class="criticalmessages">
+ <p>The following deletions are <b>unsafe</b> and would generate referential
+ integrity inconsistencies!</p>
+
+ <ul>
+ [% IF attachments %]
+ <li>
+ [% otheruser.login FILTER html %]
+ <a href="buglist.cgi?field0-0-0=attachments.submitter&type0-0-0=equals&value0-0-0=
+ [%- otheruser.login FILTER uri %]">has submitted
+ [% IF attachments == 1 %]
+ one attachment
+ [% ELSE %]
+ [%+ attachments %] attachments
+ [% END %]</a>.
+ If you delete the user account, the database records will be
+ inconsistent, resulting in
+ [% IF attachments == 1 %]
+ this attachment
+ [% ELSE %]
+ these attachments
+ [% END %]
+ not appearing in [% terms.bugs %] any more.
+ </li>
+ [% END %]
+ [% IF reporter %]
+ <li>
+ [% otheruser.login FILTER html %]
+ <a href="buglist.cgi?emailreporter1=1&amp;emailtype1=exact&amp;email1=
+ [%- otheruser.login FILTER uri %]">has reported
+ [% IF reporter == 1 %]
+ one [% terms.bug %]
+ [% ELSE %]
+ [%+ reporter %] [%+ terms.bugs %]
+ [% END %]</a>.
+ If you delete the user account, the database records will be
+ inconsistent, resulting in
+ [% IF reporter == 1 %]
+ this [% terms.bug %]
+ [% ELSE %]
+ these [% terms.bugs %]
+ [% END %]
+ not appearing in [% terms.bug %] lists any more.
+ </li>
+ [% END %]
+ [% IF bugs_activity %]
+ <li>
+ [% otheruser.login FILTER html %] has made
+ [% IF bugs_activity == 1 %]
+ a change on [% terms.abug %]
+ [% ELSE %]
+ changes on [% terms.bugs %]
+ [% END %].
+ If you delete the user account, the [% terms.bugs %] activity table in
+ the database will be inconsistent, resulting in
+ [% IF bugs_activity == 1 %]
+ this change
+ [% ELSE %]
+ these changes
+ [% END %]
+ not showing up in [% terms.bug %] activity logs any more.
+ </li>
+ [% END %]
+ [% IF flags.setter %]
+ <li>
+ [% otheruser.login FILTER html %] has
+ <a href="buglist.cgi?field0-0-0=setters.login_name&amp;type0-0-0=equals&amp;value0-0-0=
+ [%- otheruser.login FILTER uri %]">set
+ or requested
+ [% IF flags.setter == 1 %]
+ a flag
+ [% ELSE %]
+ [%+ flags.setter %] flags
+ [% END %]</a>.
+ If you delete the user account, the flags table in the database
+ will be inconsistent, resulting in
+ [% IF flags.setter == 1 %]
+ this flag
+ [% ELSE %]
+ these flags
+ [% END %]
+ not displaying correctly any more.
+ </li>
+ [% END %]
+ [% IF longdescs %]
+ <li>
+ [% otheruser.login FILTER html %] has
+ <a href="buglist.cgi?emaillongdesc1=1&amp;emailtype1=exact&amp;email1=
+ [%- otheruser.login FILTER uri %]">commented
+ [% IF longdescs == 1 %]
+ once on [% terms.abug %]
+ [% ELSE %]
+ [%+ longdescs %] times on [% terms.bugs %]
+ [% END %]</a>.
+ If you delete the user account, the comments table in the database
+ will be inconsistent, resulting in
+ [% IF longdescs == 1 %]
+ this comment
+ [% ELSE %]
+ these comments
+ [% END %]
+ not being visible any more.
+ </li>
+ [% END %]
+ [% IF profiles_activity %]
+ <li>
+ [% otheruser.login FILTER html %] has made
+ [% IF bugs_activity == 1 %]
+ a change on a other user's profile
+ [% ELSE %]
+ changes on other users' profiles
+ [% END %].
+ If you delete the user account, the user profiles activity table in
+ the database will be inconsistent.
+ </li>
+ [% END %]
+ </ul>
+ </div>
+ [% accept_deletion = 0 %]
+ [% END %]
+
+ [% IF assignee_or_qa || cc || component_cc || email_setting || flags.requestee ||
+ namedqueries || profile_setting || quips || series || watch.watched ||
+ watch.watcher || whine_events || whine_schedules || otheruser.has_audit_entries ||
+ other_safe %]
+ <div class="warningmessages">
+ <p>The following deletions are <b>safe</b> and will not generate
+ referential integrity inconsistencies.</p>
+
+ <ul>
+ [% IF assignee_or_qa %]
+ <li>
+ [% otheruser.login FILTER html %]
+ <a href="buglist.cgi?emailassigned_to1=1&amp;emailqa_contact1=1&amp;emailtype1=exact&amp;email1=
+ [%- otheruser.login FILTER uri %]">is
+ the assignee or the QA contact of
+ [% IF assignee_or_qa == 1 %]
+ one [% terms.bug %]
+ [% ELSE %]
+ [%+ assignee_or_qa %] [%+ terms.bugs %]
+ [% END %]</a>.
+ If you delete the user account, these roles will fall back to
+ the default assignee or default QA contact.
+ </li>
+ [% END %]
+ [% IF cc %]
+ <li>
+ [% otheruser.login FILTER html %]
+ <a href="buglist.cgi?emailcc1=1&amp;emailtype1=exact&amp;email1=
+ [%- otheruser.login FILTER uri %]">is
+ on the CC list of
+ [% IF cc == 1 %]
+ [%+ terms.abug %]
+ [% ELSE %]
+ [%+ cc %] [%+ terms.bugs %]
+ [% END %]</a>.
+ If you delete the user account, it will be removed from these CC lists.
+ </li>
+ [% END %]
+ [% IF component_cc %]
+ <li>
+ [% otheruser.login FILTER html %] is on the default CC list of
+ [% IF component_cc == 1 %]
+ one component
+ [% ELSE %]
+ [%+ component_cc %] components
+ [% END %].
+ If you delete the user account, it will be removed from these CC lists.
+ </li>
+ [% END %]
+ [% IF email_setting %]
+ <li>
+ The user's e-mail settings will be deleted along with the user
+ account.
+ </li>
+ [% END %]
+ [% IF flags.requestee %]
+ <li>
+ [% otheruser.login FILTER html %] has been
+ <a href="buglist.cgi?field0-0-0=requestees.login_name&amp;type0-0-0=equals&amp;value0-0-0=
+ [%- otheruser.login FILTER uri %]">asked
+ to set
+ [% IF flags.requestee == 1 %]
+ a flag
+ [% ELSE %]
+ [% flags.requestee %] flags
+ [% END %]</a>.
+ If you delete the user account,
+ [% IF flags.requestee == 1 %]
+ this flag
+ [% ELSE %]
+ these flags
+ [% END %]
+ will change to be unspecifically requested.
+ </li>
+ [% END %]
+ [% IF namedqueries %]
+ <li>
+ [% otheruser.login FILTER html %] has
+ [% IF namedqueries == 1 %]
+ a [% 'shared' IF namedquery_group_map %] named search
+ [% ELSE %]
+ [%+ namedqueries FILTER html %] named searches
+ [% END %].
+ [% IF namedqueries == 1 %]
+ This named search
+ [% ELSE %]
+ These named searches
+ [% END %]
+ will be deleted along with the user account.
+ [% IF namedquery_group_map %]
+ [% IF namedqueries > 1 %]
+ Of these,
+ [% IF namedquery_group_map > 1 %]
+ [%+ namedquery_group_map FILTER html %] are
+ [% ELSE %]
+ one is
+ [% END %]
+ shared.
+ [% END %]
+ Other users will not be able to use
+ [% IF namedquery_group_map > 1 %]
+ these shared named searches
+ [% ELSE %]
+ this shared named search
+ [% END %]
+ any more.
+ [% END %]
+ </li>
+ [% END %]
+ [% IF profile_setting %]
+ <li>
+ The user's preference settings will be deleted along with the user
+ account.
+ </li>
+ [% END %]
+ [% IF series %]
+ <li>
+ [% otheruser.login FILTER html %] has created
+ [% IF series == 1 %]
+ a series
+ [% ELSE %]
+ [%+ series %] series
+ [% END %].
+ [% IF series == 1 %]
+ This series
+ [% ELSE %]
+ These series
+ [% END %]
+ will be deleted along with the user account.
+ </li>
+ [% END %]
+ [% IF quips %]
+ <li>
+ [% otheruser.login FILTER html %] has submitted
+ [% IF quips == 1 %]
+ a quip
+ [% ELSE %]
+ [%+ quips %] quips
+ [% END %].
+ If you delete the user account,
+ [% IF quips == 1 %]
+ this quip
+ [% ELSE %]
+ these quips
+ [% END %]
+ will have no author anymore, but will remain available.
+ </li>
+ [% END %]
+ [% IF watch.watched || watch.watcher %]
+ <li>
+ [% otheruser.login FILTER html %]
+ [% IF watch.watched %]
+ is being watched by
+ [% IF watch.watched == 1 %]
+ a user
+ [% ELSE %]
+ [%+ watch.watched %] users
+ [% END %]
+ [% END %]
+ [% IF watch.watcher %]
+ [%+ 'and' IF watch.watched %]
+ watches
+ [% IF watch.watcher == 1 %]
+ a user
+ [% ELSE %]
+ [%+ watch.watcher %] users
+ [% END %]
+ [% END %].
+ [% IF watch.watched + watch.watcher == 1 %]
+ This watching
+ [% ELSE %]
+ These watchings
+ [% END %]
+ will cease along with the deletion of the user account.
+ </li>
+ [% END %]
+ [% IF whine_events %]
+ <li>
+ [% otheruser.login FILTER html %] has scheduled
+ [% IF whine_events == 1 %]
+ a whine
+ [% ELSE %]
+ [%+ whine_events %] whines
+ [% END %].
+ [% IF whine_events == 1 %]
+ This whine
+ [% ELSE %]
+ These whines
+ [% END %]
+ will be deleted along with the user account.
+ </li>
+ [% END %]
+ [% IF whine_schedules %]
+ <li>
+ [% otheruser.login FILTER html %] is on the receiving end of
+ [% IF whine_schedules == 1 %]
+ a whine
+ [% ELSE %]
+ [%+ whine_schedules %] whines
+ [% END %].
+ The corresponding schedules will be deleted along with the user account,
+ but the whines themselves will be left unaltered.
+ </li>
+ [% END %]
+ [% IF otheruser.has_audit_entries %]
+ <li>
+ The user has performed audited administrative tasks
+ that are logged in the database.
+ If you delete this user account, the audit log entries
+ will no longer be indentifiable.
+ </li>
+ [% END %]
+ [% Hook.process('warn_safe') %]
+ </ul>
+ </div>
+
+ [% IF accept_deletion %]
+ <p class="areyoureallyreallysure">
+ Please be aware of the consequences of this before continuing.
+ </p>
+ <p>Do you really want to delete this user account?</p>
+
+ <form method="post" action="editusers.cgi">
+ <p>
+ <input type="submit" id="delete" value="Yes, delete"/>
+ <input type="hidden" name="action" value="delete" />
+ <input type="hidden" name="userid" value="[% otheruser.id %]" />
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ [% INCLUDE listselectionhiddenfields %]
+ </p>
+ </form>
+ <p>If you do not want to delete the user account at this time,
+ [% ELSE %]
+ <p><b>You cannot delete this user account</b> due to unsafe actions reported above. You can
+ [% END %]
+
+ [% END %]
+[% END %]
+
+ <a href="editusers.cgi?action=edit&amp;userid=[% otheruser.id %]
+ [% INCLUDE listselectionurlparams %]">edit the user</a>,
+ go
+ <a href="editusers.cgi?action=list[% INCLUDE listselectionurlparams %]">back
+ to the user list</a>,
+ [% IF editusers %]
+ <a href="editusers.cgi?action=add[% INCLUDE listselectionurlparams %]">add
+ a new user</a>,
+ [% END %]
+ or <a href="editusers.cgi">find other users</a>.
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/users/create.html.tmpl b/template/en/default/admin/users/create.html.tmpl
new file mode 100644
index 0000000..354ba5f
--- /dev/null
+++ b/template/en/default/admin/users/create.html.tmpl
@@ -0,0 +1,51 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ #
+ # listselectionvalues: selection values to recreate the current user list.
+ # editusers: is viewing user member of editusers?
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Add user"
+ style_urls = ['skins/standard/editusers.css']
+ onload = "document.forms['f'].login.focus()"
+ doc_section = "useradmin.html#createnewusers"
+%]
+
+[% PROCESS admin/users/listselectvars.html.tmpl
+ listselectionvalues = listselectionvalues
+%]
+
+<form name="f" method="post" action="editusers.cgi">
+<table class="main">
+ [% PROCESS admin/users/userdata.html.tmpl
+ editform = 0
+ editusers = editusers
+ otheruser = []
+ %]
+</table>
+<p>
+ <input type="submit" id="add" value="Add"/>
+ <input type="hidden" name="action" value="new" />
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ [% INCLUDE listselectionhiddenfields %]
+</p>
+</form>
+
+<p>
+ You can also <a href="editusers.cgi">find a user</a>
+ [% IF listselectionvalues %],
+ or
+ <a href="editusers.cgi?action=list[% INCLUDE listselectionurlparams %]">go
+ back to the user list</a>
+ [% END %].
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/users/edit.html.tmpl b/template/en/default/admin/users/edit.html.tmpl
new file mode 100644
index 0000000..b75f840
--- /dev/null
+++ b/template/en/default/admin/users/edit.html.tmpl
@@ -0,0 +1,173 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ #
+ # message: message tag specifying a global/messages.html.tmpl
+ # message
+ # listselectionvalues: selection values to recreate the current user list.
+ # editusers: is viewing user member of editusers?
+ # otheruser: Bugzilla::User object of viewed user.
+ # groups: array of group information (name, grant type,
+ # canbless) for viewed user.
+ #%]
+
+[% title = BLOCK %]Edit user [% otheruser.identity FILTER html %][% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ message = message
+ style_urls = ['skins/standard/admin.css', 'skins/standard/editusers.css']
+ doc_section = "useradmin.html#modifyusers"
+ javascript_urls = [ 'js/field.js' ]
+%]
+
+[% PROCESS admin/users/listselectvars.html.tmpl
+ listselectionvalues = listselectionvalues
+%]
+
+<form method="post" action="editusers.cgi">
+<table class="main">
+ [% PROCESS admin/users/userdata.html.tmpl
+ editform = 1
+ editusers = editusers
+ otheruser = otheruser
+ %]
+ [% IF groups.size %]
+ <tr>
+ <th>Group access:</th>
+ <td>
+ <table class="groups">
+ <tr>
+ [% IF editusers %]
+ <th colspan="3">
+ Can turn these bits on for other users
+ </th>
+ [% END %]
+ </tr>
+ <tr>
+ [% IF editusers %]
+ <td style="text-align: center; font-weight: bold">|</td>
+ [% END %]
+ <th colspan="2">User is a member of these groups</th>
+ </tr>
+ [% FOREACH group = groups %]
+ [% perms = permissions.${group.id} %]
+ <tr class="[% 'in' IF perms.regexpmember || perms.derivedmember %]direct">
+ [% IF editusers %]
+ <td class="checkbox">
+ [% '[' IF perms.indirectbless %]
+ [% %]<input type="checkbox"
+ name="bless_[% group.id %]"
+ value="1"
+ [% ' checked="checked"' IF perms.directbless %] />
+ [% ']' IF perms.indirectbless %]</td>
+ [% END %]
+ <td class="checkbox">
+ [% '[' IF perms.derivedmember %]
+ [% '*' IF perms.regexpmember %]
+ [%%]<input type="checkbox"
+ id="group_[% group.id %]"
+ name="group_[% group.id %]"
+ value="1"
+ [% ' checked="checked"' IF perms.directmember %] />
+ [% '*' IF perms.regexpmember %]
+ [% ']' IF perms.derivedmember %]</td>
+ <td class="groupname">
+ <label for="group_[% group.id %]">
+ <strong>[% group.name FILTER html %]:</strong>
+ [%+ group.description FILTER html_light %]
+ </label>
+ </td>
+ </tr>
+ [% END %]
+ </table>
+ </td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <th>Product responsibilities:</th>
+ <td>
+ [% IF otheruser.product_responsibilities.size %]
+ [% PROCESS admin/users/responsibilities.html.tmpl otheruser = otheruser %]
+ [% ELSE %]
+ <em>none</em>
+ [% END %]
+ </td>
+ </tr>
+
+ <tr>
+ <th>Last Login:</th>
+ <td>
+ [% IF otheruser.last_seen_date %]
+ [% otheruser.last_seen_date FILTER html %]
+ [% ELSE %]
+ <em>never</em>
+ [% END %]
+ </td>
+ </tr>
+</table>
+
+<p>
+ <input type="submit" id="update" value="Save Changes" />
+ <input type="hidden" name="userid" value="[% otheruser.id %]" />
+ <input type="hidden" name="action" value="update" />
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ [% INCLUDE listselectionhiddenfields %]
+
+ or <a href="editusers.cgi?action=activity&amp;userid=[% otheruser.id %]"
+ title="View Account History for '
+ [%- otheruser.login FILTER html %]'">View Account History</a>
+</p>
+</form>
+<p>
+ User is a member of any groups shown with a check or grey bar.
+ A grey bar indicates indirect membership, either derived from other
+ groups (marked with square brackets) or via regular expression
+ (marked with '*').
+</p>
+[% IF editusers %]
+ <p>
+ Square brackets around the bless checkbox indicate the ability
+ to bless users (grant them membership in the group) as a result
+ of membership in another group.
+ </p>
+[% END %]
+
+[% IF Param('allowuserdeletion') && editusers %]
+ <form method="post" action="editusers.cgi">
+ <p>
+ <input type="submit" id="delete" value="Delete User" />
+ <input type="hidden" name="action" value="del" />
+ <input type="hidden" name="userid" value="[% otheruser.id %]" />
+ [% INCLUDE listselectionhiddenfields %]
+ </p>
+ </form>
+[% END %]
+
+<p>
+ You can also
+ [% IF editusers %]
+ <a href="editusers.cgi?action=add[% INCLUDE listselectionurlparams %]">add
+ a new user</a>
+ [% IF listselectionvalues %],
+ [% END %]
+ [% END %]
+ [% IF listselectionvalues.matchtype != 'exact' %]
+ go
+ <a href="editusers.cgi?action=list[% INCLUDE listselectionurlparams %]">back
+ to the user list</a>,
+ [% END %]
+ [% IF editusers OR listselectionvalues %]
+ or
+ [% END %]
+ <a href="editusers.cgi">find other users</a>.
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/users/list.html.tmpl b/template/en/default/admin/users/list.html.tmpl
new file mode 100644
index 0000000..ff23b77
--- /dev/null
+++ b/template/en/default/admin/users/list.html.tmpl
@@ -0,0 +1,111 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ #
+ # listselectionvalues: selection values to recreate the current user list.
+ # editusers: is viewing user member of editusers?
+ # users: list of user information (id, login_name, realname,
+ # disabledtext).
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Select user"
+ style_urls = ['skins/standard/editusers.css']
+ doc_section = "useradmin.html"
+%]
+
+[% PROCESS admin/users/listselectvars.html.tmpl
+ listselectionvalues = listselectionvalues
+%]
+
+[% listselectionurlparams = INCLUDE listselectionurlparams %]
+
+[% columns =
+ [{name => 'login_name'
+ heading => 'Edit user...'
+ contentlink => 'editusers.cgi?action=edit&amp;userid=%%userid%%' _
+ listselectionurlparams
+ }
+ {name => 'realname'
+ heading => 'Real name'
+ }
+ {name => 'last_seen_date'
+ heading => 'Last Login'
+ }
+ {heading => 'Account History'
+ content => 'View'
+ contentlink => 'editusers.cgi?action=activity' _
+ '&amp;userid=%%userid%%' _
+ listselectionurlparams
+ }
+ ]
+%]
+
+[% IF Param('allowuserdeletion') && editusers %]
+ [% columns.push({heading => 'Action'
+ content => 'Delete'
+ contentlink => 'editusers.cgi?action=del' _
+ '&amp;userid=%%userid%%' _
+ listselectionurlparams
+ }
+ )
+ %]
+[% END %]
+
+[%# Disabled users are crossed out. Missing realnames are noticed in red. %]
+[% overrides.login_name = {} %]
+[% overrides.realname = {} %]
+
+[% FOREACH thisuser = users %]
+ [% IF !thisuser.realname %]
+ [%# We cannot pass one class now and one class later. %]
+ [% SET classes = (thisuser.is_enabled ? "missing" : "bz_inactive missing") %]
+ [% overrides.realname.login_name.${thisuser.login_name} = {
+ content => "missing"
+ override_content => 1
+ class => "$classes"
+ override_class => 1
+ }
+ %]
+ [% ELSIF !thisuser.is_enabled %]
+ [% overrides.realname.login_name.${thisuser.login_name} = {
+ class => "bz_inactive"
+ override_class => 1
+ }
+ %]
+ [% END %]
+
+ [% IF !thisuser.is_enabled %]
+ [% overrides.login_name.login_name.${thisuser.login_name} = {
+ class => "bz_inactive"
+ override_class => 1
+ }
+ %]
+ [% END %]
+[% END %]
+
+<p>[% users.size %] user[% "s" UNLESS users.size == 1 %] found.</p>
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ data = users
+ overrides = overrides
+%]
+
+<p>
+ If you do not wish to modify a user account at this time, you can
+ <a href="editusers.cgi">find other users</a>
+ [% IF editusers %]
+ or
+ <a href="editusers.cgi?action=add[% INCLUDE listselectionurlparams %]">add
+ a new user</a>
+ [% END %].
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/users/listselectvars.html.tmpl b/template/en/default/admin/users/listselectvars.html.tmpl
new file mode 100644
index 0000000..bd03113
--- /dev/null
+++ b/template/en/default/admin/users/listselectvars.html.tmpl
@@ -0,0 +1,26 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ #
+ # listselectionvalues: selection values to recreate the current user list.
+ #%]
+
+[% BLOCK listselectionurlparams %]
+ [% FOREACH field = listselectionvalues.keys %]&amp;
+ [% field FILTER uri %]=
+ [% listselectionvalues.$field FILTER uri %]
+ [% END %]
+[% END %]
+
+[% BLOCK listselectionhiddenfields %]
+ [% FOREACH field = listselectionvalues.keys %]
+ <input type="hidden" name="[% field FILTER html %]"
+ value="[% listselectionvalues.$field FILTER html %]" />
+ [% END %]
+[% END %]
diff --git a/template/en/default/admin/users/responsibilities.html.tmpl b/template/en/default/admin/users/responsibilities.html.tmpl
new file mode 100644
index 0000000..9e6e48c
--- /dev/null
+++ b/template/en/default/admin/users/responsibilities.html.tmpl
@@ -0,0 +1,57 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% hidden_products = 0 %]
+<table id="user_responsibilities" border="0">
+ [% FOREACH item = otheruser.product_responsibilities %]
+ [% IF !user.can_see_product(item.product.name) %]
+ [% hidden_products = 1 %]
+ [% NEXT %]
+ [% END %]
+ <tbody>
+ <tr>
+ <th colspan="3" class="product">Product: [% item.product.name FILTER html %]</th>
+ </tr>
+ <tr>
+ <th>Component</th>
+ <th>Default Assignee</th>
+ <th>Default QA Contact</th>
+ <th>Default CC</th>
+ </tr>
+ [% FOREACH component = item.components %]
+ <tr>
+ <td>
+ [% IF user.in_group("editcomponents", component.product_id) %]
+ <a href="editcomponents.cgi?action=edit&amp;product=
+ [% item.product.name FILTER uri %]&amp;component=
+ [% component.name FILTER uri %]">
+ [% END %]
+ [% component.name FILTER html %]
+ [% IF user.in_group("editcomponents", component.product_id) %]
+ </a>
+ [% END %]
+ </td>
+ [% FOREACH responsibility = ['default_assignee', 'default_qa_contact'] %]
+ <td class="center">
+ [% component.$responsibility.id == otheruser.id ? "X" : "&nbsp;" %]
+ </td>
+ [% END %]
+ <td class="center">
+ [% component.initial_cc.contains(otheruser) ? "X" : "&nbsp;" %]
+ </td>
+ </tr>
+ [% END %]
+ </tbody>
+ [% END %]
+</table>
+
+[% IF hidden_products %]
+ <p class="criticalmessages">The user is involved in at least one product which you cannot
+ see (and so is not listed above). You have to ask an administrator with enough
+ privileges to edit this user's roles for these products.</p>
+[% END %]
diff --git a/template/en/default/admin/users/search.html.tmpl b/template/en/default/admin/users/search.html.tmpl
new file mode 100644
index 0000000..c66af4c
--- /dev/null
+++ b/template/en/default/admin/users/search.html.tmpl
@@ -0,0 +1,79 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ #
+ # editusers: is viewing user member of editusers?
+ # restrictablegroups: list of groups visible to the user:
+ # id: group id
+ # name: group name
+ #%]
+
+
+[% PROCESS global/header.html.tmpl
+ title = "Search users"
+ style_urls = ['skins/standard/editusers.css']
+ onload = "document.forms['f'].matchstr.focus()"
+ doc_section = "useradmin.html#user-account-search"
+%]
+
+[% PROCESS admin/users/listselectvars.html.tmpl
+ listselectionvalues = listselectionvalues
+%]
+
+<form name="f" method="get" action="editusers.cgi">
+<input type="hidden" name="action" value="list" />
+<p><label for="matchvalue">List users with</label>
+<select id="matchvalue" name="matchvalue">
+ <option value="login_name">login name</option>
+ <option value="realname">real name</option>
+ <option value="userid">user id</option>
+</select>
+<label for="matchstr">matching</label>
+<input size="32" name="matchstr" id="matchstr" />
+<select name="matchtype">
+ <option value="substr" selected="selected">case-insensitive substring</option>
+ <option value="regexp">case-insensitive regexp</option>
+ <option value="notregexp">not (case-insensitive regexp)</option>
+ <option value="exact">exact (find this user)</option>
+</select>
+<input type="submit" id="search" value="Search" /></p>
+
+[% IF restrictablegroups.size %]
+ <p><input type="checkbox" name="grouprestrict" value="1" id="grouprestrict" />
+ <label for="grouprestrict">Restrict to users belonging to group</label>
+ <select name="groupid"
+ onchange="document.forms['f'].grouprestrict.checked=true">
+ [% FOREACH group = restrictablegroups %]
+ <option value="[% group.id FILTER html %]">[% group.name FILTER html %]</option>
+ [% END %]
+ </select></p>
+[% END %]
+
+<p>
+ <input type="checkbox" name="enabled_only" value="1" id="enabled_only"
+ checked="checked">
+ <label for="enabled_only">Enabled user accounts only</label>
+</p>
+
+[% Hook.process('end') %]
+
+</form>
+
+[% IF editusers %]
+ <p>
+ You can also <a href="editusers.cgi?action=add">add a new user</a>
+ [%- IF listselectionvalues %],
+ or
+ <a href="editusers.cgi?action=list[% INCLUDE listselectionurlparams %]">show
+ the user list again</a>
+ [%- END %].
+ </p>
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/users/userdata.html.tmpl b/template/en/default/admin/users/userdata.html.tmpl
new file mode 100644
index 0000000..ae952d1
--- /dev/null
+++ b/template/en/default/admin/users/userdata.html.tmpl
@@ -0,0 +1,109 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ #
+ # editform: is this an edit form? (It's a create form otherwise)
+ # editusers: is viewing user member of editusers?
+ # otheruser: Bugzilla::User object of user to edit
+ #%]
+
+<script type="text/javascript">
+ var disable_mail_manually_set = [% (otheruser.email_disabled ? 1 : 0) FILTER js %];
+</script>
+
+<tr>
+ <th><label for="login">Login name:</label></th>
+ <td>
+ [% IF editusers %]
+ <input size="64" maxlength="255" name="login"
+ id="login" value="[% otheruser.login FILTER html %]" />
+ [% IF editform %]
+ [% IF !otheruser.in_group('bz_sudo_protect') %]
+ <br />
+ <a href="relogin.cgi?action=prepare-sudo&amp;target_login=
+ [%- otheruser.login FILTER uri %]">Impersonate this user</a>
+ [% END %]
+ [% END %]
+ [% ELSE %]
+ [% otheruser.login FILTER html %]
+ [% END %]
+ </td>
+</tr>
+[% IF default_authorizer.extern_id_used %]
+ <tr>
+ <th><label for="extern_id">External Login ID:</label></th>
+ <td>
+ [% IF editusers %]
+ <input size="64" maxlength="64" name="extern_id"
+ id="extern_id" value="[% otheruser.extern_id FILTER html %]">
+ [% ELSE %]
+ [% otheruser.extern_id FILTER html %]
+ [% END %]
+ </td>
+ </tr>
+[% END %]
+<tr>
+ <th><label for="name">Real name:</label></th>
+ <td>
+ [% IF editusers %]
+ <input size="64" maxlength="255" name="name"
+ autocomplete="off"
+ id="name" value="[% otheruser.name FILTER html %]" />
+ [% ELSE %]
+ [% otheruser.name FILTER html %]
+ [% END %]
+ </td>
+</tr>
+
+[%# XXX This condition (can_change_password) will cause a problem
+ # if we ever have a login system that can create accounts through
+ # createaccount.cgi but can't change passwords.
+ #%]
+
+[% IF editusers %]
+ [% IF user.authorizer.can_change_password %]
+ <tr>
+ <th><label for="password">Password:</label></th>
+ <td>
+ <input type="password" size="16" name="password" id="password"
+ value="" autocomplete="off" />
+ [% IF editform %]<br />
+ (Enter new password to change.)
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+ <tr>
+ <th><label for="disable_mail">[% terms.Bug %]mail Disabled:</label></th>
+ <td>
+ <input type="checkbox" name="disable_mail" id="disable_mail" value="1"
+ [% IF otheruser.email_disabled %] checked="checked" [% END %]
+ onchange="disable_mail_manually_set=1;">
+ (This affects [% terms.bug %]mail and whinemail, not password-reset or other
+ non-[% terms.bug %]-related emails)
+ </td>
+ </tr>
+ <tr>
+ <th><label for="disabledtext">Disable text:</label></th>
+ <td>
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'disabledtext'
+ id = 'disabledtext'
+ minrows = 2
+ maxrows = 10
+ defaultrows = 10
+ cols = 60
+ defaultcontent = otheruser.disabledtext
+ onchange = "userDisabledTextOnChange(this);"
+ %]<br>
+ (If non-empty, then it will not be possible to log in using this account,
+ and this text should explain why.)
+ </td>
+ </tr>
+[% END %]
diff --git a/template/en/default/admin/versions/confirm-delete.html.tmpl b/template/en/default/admin/versions/confirm-delete.html.tmpl
new file mode 100644
index 0000000..e6f3922
--- /dev/null
+++ b/template/en/default/admin/versions/confirm-delete.html.tmpl
@@ -0,0 +1,89 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: object; Bugzilla::Product object representing the product to
+ # which the version belongs.
+ # version: object; Bugzilla::Version object representing the
+ # version the user wants to delete.
+ #%]
+
+[% title = BLOCK %]Delete Version of Product '[% product.name FILTER html %]'
+ [% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+%]
+
+<table border="1" cellpadding="4" cellspacing="0">
+<tr bgcolor="#6666FF">
+ <th valign="top" align="left">Field</th>
+ <th valign="top" align="left">Value</th>
+</tr>
+<tr>
+ <td valign="top">Version:</td>
+ <td valign="top">[% version.name FILTER html %]</td>
+</tr>
+<tr>
+ <td valign="top">Version of Product:</td>
+ <td valign="top">[% product.name FILTER html %]</td>
+</tr>
+<tr>
+ <td valign="top">[% terms.Bugs %]:</td>
+ <td valign="top">
+[% IF version.bug_count %]
+ <a title="List of [% terms.bugs %] targetted at version '
+ [%- version.name FILTER html %]'"
+ href="buglist.cgi?version=[% version.name FILTER uri %]&amp;product=
+ [%- product.name FILTER uri %]">
+ [%- version.bug_count FILTER none %]</a>
+[% ELSE %]
+ None
+[% END %]
+ </td>
+</tr>
+</table>
+
+<h2>Confirmation</h2>
+
+[% IF version.bug_count %]
+ <p class="confirmation">
+ Sorry, there
+ [% IF version.bug_count > 1 %]
+ are [% version.bug_count FILTER none %] outstanding [% terms.bugs %]
+ [% ELSE %]
+ is [% version.bug_count FILTER none %] outstanding [% terms.bug %]
+ [% END %]
+
+ for this version. You must move
+
+ [% IF version.bug_count > 1 %]
+ those [% terms.bugs %]
+ [% ELSE %]
+ that [% terms.bug %]
+ [% END %]
+ to another version before this version can be deleted.
+ </p>
+[% ELSE %]
+
+ <p>Do you really want to delete this version?</p>
+
+ <form method="post" action="editversions.cgi">
+ <input type="submit" id="delete" value="Yes, delete">
+ <input type="hidden" name="action" value="delete">
+ <input type="hidden" name="product" value="[% product.name FILTER html %]">
+ <input type="hidden" name="version" value="[% version.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ </form>
+
+[% END %]
+
+[% PROCESS admin/versions/footer.html.tmpl %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/versions/create.html.tmpl b/template/en/default/admin/versions/create.html.tmpl
new file mode 100644
index 0000000..af72582
--- /dev/null
+++ b/template/en/default/admin/versions/create.html.tmpl
@@ -0,0 +1,40 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: object; Bugzilla::Product object representing the product to
+ # which the version is being created for
+ #%]
+
+[% title = BLOCK %]Add Version to Product '[% product.name FILTER html %]'[% END %]
+[% subheader = BLOCK %]This page allows you to add a new version to product
+ '[% product.name FILTER html %]'.[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+ subheader = subheader
+%]
+
+<form method="post" action="editversions.cgi">
+ <table border="0" cellpadding="4" cellspacing="0">
+ <tr>
+ <th align="right"><label for="version">Version:</label></th>
+ <td><input id="version" size="64" maxlength="64" name="version"
+ value=""></td>
+ </tr>
+ </table>
+ <input type="submit" id="create" value="Add">
+ <input type="hidden" name="action" value="new">
+ <input type="hidden" name='product' value="[% product.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+</form>
+
+[% PROCESS admin/versions/footer.html.tmpl
+ no_add_version_link = 1
+ %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/versions/edit.html.tmpl b/template/en/default/admin/versions/edit.html.tmpl
new file mode 100644
index 0000000..195a94c
--- /dev/null
+++ b/template/en/default/admin/versions/edit.html.tmpl
@@ -0,0 +1,47 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: object; Bugzilla::Product object representing the product to
+ # which the version belongs.
+ # version: object; Bugzilla::Version object representing the
+ # version the user wants to edit.
+ #%]
+
+[% title = BLOCK %]Edit Version '[% version.name FILTER html %]' of product '
+ [%- product.name FILTER html %]'[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+%]
+
+<form method="post" action="editversions.cgi">
+ <table border="0" cellpadding="4" cellspacing="0">
+
+ <tr>
+ <th class="field_label"><label for="version">Version:</label></th>
+ <td><input id="version" size="64" maxlength="64" name="version" value="
+ [%- version.name FILTER html %]"></td>
+ </tr>
+ <tr>
+ <th class="field_label"><label for="isactive">Enabled For [% terms.Bugs %]:</label></th>
+ <td><input id="isactive" name="isactive" type="checkbox" value="1"
+ [% 'checked="checked"' IF version.isactive %]></td>
+ </tr>
+ </table>
+
+ <input type="hidden" name="versionold" value="[% version.name FILTER html %]">
+ <input type="hidden" name="action" value="update">
+ <input type="hidden" name="product" value="[% product.name FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="submit" id="update" value="Save Changes">
+</form>
+
+[% PROCESS admin/versions/footer.html.tmpl
+ no_edit_version_link = 1 %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/versions/footer.html.tmpl b/template/en/default/admin/versions/footer.html.tmpl
new file mode 100644
index 0000000..0af63a8
--- /dev/null
+++ b/template/en/default/admin/versions/footer.html.tmpl
@@ -0,0 +1,53 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: object; Bugzilla::Product object representing the product to
+ # which the version belongs.
+ # version: object; Bugzilla::Version object representing the version
+ #
+ # no_XXX_link: boolean; if defined, then don't show the corresponding
+ # link. Supported parameters are:
+ #
+ # no_edit_version_link
+ # no_edit_other_versions_link
+ # no_add_version_link
+ #%]
+
+<hr>
+
+<p>
+
+[% UNLESS no_add_version_link %]
+ <a title="Add a version to product '[% product.name FILTER html %]'"
+ href="editversions.cgi?action=add&amp;product=
+ [%- product.name FILTER uri %]">Add</a> a version.
+[% END %]
+
+[% IF version.name && !no_edit_version_link %]
+ Edit version <a
+ title="Edit Version '[% version.name FILTER html %]' of product '
+ [%- product.name FILTER html %]'"
+ href="editversions.cgi?action=edit&amp;product=
+ [%- product.name FILTER uri %]&amp;version=
+ [%- version.name FILTER uri %]">
+ '[% version.name FILTER html %]'</a>.
+[% END %]
+
+[% UNLESS no_edit_other_versions_link %]
+ Edit other versions of product <a
+ href="editversions.cgi?product=
+ [%- product.name FILTER uri %]">'[% product.name FILTER html %]'</a>.
+
+[% END %]
+
+ Edit product <a
+ href="editproducts.cgi?action=edit&amp;product=
+ [%- product.name FILTER uri %]">'[% product.name FILTER html %]'</a>.
+
+</p>
diff --git a/template/en/default/admin/versions/list.html.tmpl b/template/en/default/admin/versions/list.html.tmpl
new file mode 100644
index 0000000..1cf3e86
--- /dev/null
+++ b/template/en/default/admin/versions/list.html.tmpl
@@ -0,0 +1,79 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: object; Bugzilla::Product object representing the product to
+ # which the versions belongs.
+ #%]
+
+[% title = BLOCK %]Select version of product
+ '[% product.name FILTER html %]'[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+%]
+
+[% edit_contentlink = BLOCK %]editversions.cgi?action=edit&amp;product=
+ [%- product.name FILTER uri %]&amp;version=%%name%%[% END %]
+[% delete_contentlink = BLOCK %]editversions.cgi?action=del&amp;product=
+ [%- product.name FILTER uri %]&amp;version=%%name%%[% END %]
+[% bug_count_contentlink = BLOCK %]buglist.cgi?version=%%name%%&amp;product=
+ [%- product.name FILTER uri %][% END %]
+
+
+[% columns = [
+ {
+ name => "name"
+ heading => "Edit version..."
+ contentlink => edit_contentlink
+ },
+ {
+ name => "isactive"
+ heading => "Active"
+ yesno_field => 1
+ }
+ ]
+%]
+
+[% IF showbugcounts %]
+
+ [% columns.push({
+ name => "bug_count"
+ heading => "$terms.Bugs"
+ align => "right"
+ contentlink => bug_count_contentlink
+ })
+ %]
+
+[% END %]
+
+[% columns.push({
+ heading => "Action"
+ content => "Delete"
+ contentlink => delete_contentlink
+ })
+%]
+
+[% Hook.process('before_table') %]
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ data = product.versions
+%]
+
+[% IF ! showbugcounts %]
+
+ <p><a href="editversions.cgi?product=[% product.name FILTER uri %]&amp;showbugcounts=1">
+ Redisplay table with [% terms.bug %] counts (slower)</a></p>
+
+[% END %]
+
+[% PROCESS admin/versions/footer.html.tmpl
+ no_edit_other_versions_link = 1
+ %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/versions/select-product.html.tmpl b/template/en/default/admin/versions/select-product.html.tmpl
new file mode 100644
index 0000000..e40e408
--- /dev/null
+++ b/template/en/default/admin/versions/select-product.html.tmpl
@@ -0,0 +1,54 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # products: array of product objects
+ # showbugcounts: if defined, then bug counts should be included in the table
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Edit versions for which product?"
+%]
+
+[% columns = [
+ {
+ name => "name"
+ heading => "Edit versions of..."
+ contentlink => "editversions.cgi?product=%%name%%"
+ },
+ {
+ name => "description"
+ heading => "Description"
+ allow_html_content => 1
+ }
+ ]
+%]
+
+[% IF showbugcounts %]
+
+ [% columns.push({
+ name => 'bug_count'
+ heading => "$terms.Bugs"
+ align => "right"
+ contentlink => "buglist.cgi?product=%%name%%"
+ })
+ %]
+
+[% END %]
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ data = products
+%]
+
+[% IF !showbugcounts %]
+ <p><a href="editversions.cgi?showbugcounts=1">
+ Redisplay table with [% terms.bug %] counts (slower)</a></p>
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/workflow/comment.html.tmpl b/template/en/default/admin/workflow/comment.html.tmpl
new file mode 100644
index 0000000..b5907d1
--- /dev/null
+++ b/template/en/default/admin/workflow/comment.html.tmpl
@@ -0,0 +1,82 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% INCLUDE global/header.html.tmpl
+ title = "Comments Required on Status Transitions"
+ style_urls = ['skins/standard/admin.css']
+%]
+
+<script type="text/javascript">
+<!--
+ function toggle_cell(cell) {
+ if (cell.checked)
+ cell.parentNode.className = "checkbox-cell checked";
+ else
+ cell.parentNode.className = "checkbox-cell";
+ }
+//-->
+</script>
+
+<p>
+ This page allows you to define which status transitions require a comment
+ by the user doing the change.
+</p>
+
+<form id="workflow_form" method="POST" action="editworkflow.cgi">
+<table>
+ <tr>
+ <th colspan="2">&nbsp;</th>
+ <th colspan="[% statuses.size FILTER html %]" class="title">To</th>
+ </tr>
+
+ <tr>
+ <th rowspan="[% statuses.size + 2 FILTER html %]" class="title">From</th>
+ <th>&nbsp;</th>
+ [% FOREACH status = statuses %]
+ <th class="col-header[% status.is_open ? " open-status" : " closed-status" %]">
+ [% display_value("bug_status", status.name) FILTER html %]
+ </th>
+ [% END %]
+ </tr>
+
+ [%# This defines the entry point in the workflow %]
+ [% p = [{id => 0, name => "{Start}", is_open => 1}] %]
+ [% FOREACH status = p.merge(statuses) %]
+ <tr class="highlight">
+ <th align="right" class="[% status.is_open ? "open-status" : "closed-status" %]">
+ [% display_value("bug_status", status.name) FILTER html %]
+ </th>
+
+ [% FOREACH new_status = statuses %]
+ [% IF workflow.${status.id}.${new_status.id}.defined %]
+ <td align="center" class="checkbox-cell
+ [% " checked" IF workflow.${status.id}.${new_status.id} %]"
+ title="From [% status.name FILTER html %] to [% new_status.name FILTER html %]">
+ <input type="checkbox" name="c_[% status.id %]_[% new_status.id %]"
+ id="c_[% status.id %]_[% new_status.id %]" onclick="toggle_cell(this)"
+ [% " checked='checked'" IF workflow.${status.id}.${new_status.id} %]>
+ </td>
+ [% ELSE %]
+ <td class="checkbox-cell forbidden">&nbsp;</td>
+ [% END %]
+ [% END %]
+ </tr>
+ [% END %]
+</table>
+
+<p align="center">
+ <input type="hidden" name="action" value="update_comment">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="submit" id="update_comment" value="Commit Changes"> -
+ <a href="editworkflow.cgi?action=edit_comment">Cancel Changes</a> -
+ <a href="editworkflow.cgi">View Current Workflow</a>
+</p>
+
+</form>
+
+[% INCLUDE global/footer.html.tmpl %]
diff --git a/template/en/default/admin/workflow/edit.html.tmpl b/template/en/default/admin/workflow/edit.html.tmpl
new file mode 100644
index 0000000..403405b
--- /dev/null
+++ b/template/en/default/admin/workflow/edit.html.tmpl
@@ -0,0 +1,100 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% INCLUDE global/header.html.tmpl
+ title = "Edit Workflow"
+ style_urls = ['skins/standard/admin.css']
+%]
+
+<script type="text/javascript">
+<!--
+ function toggle_cell(cell) {
+ if (cell.checked)
+ cell.parentNode.className = "checkbox-cell checked";
+ else
+ cell.parentNode.className = "checkbox-cell";
+ }
+//-->
+</script>
+
+<p>
+ This page allows you to define which status transitions are valid in your workflow.
+ For compatibility with older versions of [% terms.Bugzilla %], reopening [% terms.abug %]
+ will only display either [% display_value("bug_status", "UNCONFIRMED") FILTER html %] or
+ [%+ display_value("bug_status", "REOPENED") FILTER html %] (if allowed by your workflow) but not
+ both. The decision depends on whether the [% terms.bug %] has ever been confirmed or not.
+ So it is a good idea to allow both transitions and let [% terms.Bugzilla %] select the
+ correct one.
+</p>
+
+<form id="workflow_form" method="POST" action="editworkflow.cgi">
+<table>
+ <tr>
+ <th colspan="2">&nbsp;</th>
+ <th colspan="[% statuses.size FILTER html %]" class="title">To</th>
+ </tr>
+
+ <tr>
+ <th rowspan="[% statuses.size + 2 FILTER html %]" class="title">From</th>
+ <th>&nbsp;</th>
+ [% FOREACH status = statuses %]
+ <th class="col-header[% status.is_open ? " open-status" : " closed-status" %]">
+ [% display_value("bug_status", status.name) FILTER html %]
+ </th>
+ [% END %]
+ </tr>
+
+ [%# This defines the entry point in the workflow %]
+ [% p = [{id => 0, name => "{Start}", is_open => 1}] %]
+ [% FOREACH status = p.merge(statuses) %]
+ <tr class="highlight">
+ <th align="right" class="[% status.is_open ? "open-status" : "closed-status" %]">
+ [% display_value("bug_status", status.name) FILTER html %]
+ </th>
+
+ [% FOREACH new_status = statuses %]
+ [% IF status.id != new_status.id %]
+ [% checked = workflow.${status.id}.${new_status.id}.defined ? 1 : 0 %]
+ [% mandatory = (status.id && new_status.name == Param("duplicate_or_move_bug_status")) ? 1 : 0 %]
+ <td align="center" class="checkbox-cell[% " checked" IF checked || mandatory %]"
+ title="From [% status.name FILTER html %] to [% new_status.name FILTER html %]">
+ <input type="checkbox" name="w_[% status.id %]_[% new_status.id %]"
+ id="w_[% status.id %]_[% new_status.id %]" onclick="toggle_cell(this)"
+ [%+ "checked='checked'" IF checked || mandatory %]
+ [%+ "disabled='disabled'" IF mandatory %]>
+ </td>
+ [% ELSE %]
+ <td class="checkbox-cell forbidden">&nbsp;</td>
+ [% END %]
+ [% END %]
+ </tr>
+ [% END %]
+</table>
+
+<p>
+ When [% terms.abug %] is marked as a duplicate of another one or is moved
+ to another installation, the [% terms.bug %] status is automatically set to
+ <b>[% display_value("bug_status", Param("duplicate_or_move_bug_status")) FILTER html %]</b>. All transitions to
+ this [% terms.bug %] status must then be valid (this is the reason why you cannot edit
+ them above).<br>
+ Note: you can change this setting by visiting the
+ <a href="editparams.cgi?section=bugchange#duplicate_or_move_bug_status">Parameters</a>
+ page and editing the <i>duplicate_or_move_bug_status</i> parameter.
+</p>
+
+<p align="center">
+ <input type="hidden" name="action" value="update">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="submit" id="update_workflow" value="Commit Changes"> -
+ <a href="editworkflow.cgi">Cancel Changes</a> -
+ <a href="editworkflow.cgi?action=edit_comment">View Comments Required on Status Transitions</a>
+</p>
+
+</form>
+
+[% INCLUDE global/footer.html.tmpl %]
diff --git a/template/en/default/attachment/choose.html.tmpl b/template/en/default/attachment/choose.html.tmpl
new file mode 100644
index 0000000..c6b94d7
--- /dev/null
+++ b/template/en/default/attachment/choose.html.tmpl
@@ -0,0 +1,29 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Locate attachment",
+ onload = "document.forms['choose-id'].id.focus()"
+ %]
+
+<form name="choose-id" method="get" action="attachment.cgi">
+ <p>Access an attachment by entering its ID into the form below:</p>
+ <p>Attachment ID: <input name="id" size="6">
+ <button name="action" value="edit" id="edit">Details</button>
+ <button name="action" value="view" id="view">View</button>
+ </p>
+</form>
+
+<form method="get" action="show_bug.cgi">
+ <p>Or, access it from the list of attachments in its associated [% terms.bug %] report:</p>
+ <p>[% terms.Bug %] ID: <input name="id" size="6">
+ <input type="submit" name="action" value="View" id="action">
+ </p>
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/attachment/confirm-delete.html.tmpl b/template/en/default/attachment/confirm-delete.html.tmpl
new file mode 100644
index 0000000..4557af6
--- /dev/null
+++ b/template/en/default/attachment/confirm-delete.html.tmpl
@@ -0,0 +1,83 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # a: attachment object; attachment the user wants to delete.
+ # token: string; The token used to identify the session.
+ #%]
+
+[% title = BLOCK %]
+ Delete Attachment [% a.id FILTER html %] of [% terms.Bug %] [%+ a.bug_id FILTER html %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ doc_section = "attachments.html"
+%]
+
+<table border="1" cellpadding="4" cellspacing="0">
+ <tr bgcolor="#6666FF">
+ <th valign="top" align="left">Field</th>
+ <th valign="top" align="left">Value</th>
+ </tr>
+ <tr>
+ <td valign="top">Attachment ID:</td>
+ <td valign="top">
+ <a href="attachment.cgi?id=[% a.id FILTER html %]">[% a.id FILTER html %]</a>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">File name:</td>
+ <td valign="top">[% a.filename FILTER html %]</td>
+ </tr>
+ <tr>
+ <td valign="top">Description:</td>
+ <td valign="top">[% a.description FILTER html %]</td>
+ </tr>
+ <tr>
+ <td valign="top">Contained in [% terms.Bug %]:</td>
+ <td valign="top">[% a.bug_id FILTER bug_link(a.bug_id) FILTER none %]</td>
+ </tr>
+ <tr>
+ <td valign="top">Creator:</td>
+ <td valign="top">[% a.attacher.identity FILTER html %]</td>
+ </tr>
+ <tr>
+ <td valign="top">Creation Date:</td>
+ <td valign="top">[% a.attached FILTER time %]</td>
+ </tr>
+</table>
+
+<h2>Confirmation</h2>
+
+<table border="0" cellpadding="20" width="70%" bgcolor="red">
+ <tr>
+ <td>
+ The content of this attachment will be deleted in an <b>irreversible</b> way.
+ </td>
+ </tr>
+</table>
+
+<p>Do you really want to delete this attachment?</p>
+
+<form action="attachment.cgi" method="POST">
+ <label for="reason">Reason of the deletion:</label>
+ <input type="text" id="reason" name="reason" value="" size="80" maxlength="200">
+ <br>
+ <input type="submit" value="Yes, delete" id="delete">
+ <input type="hidden" name="action" value="delete">
+ <input type="hidden" name="id" value="[% a.id FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+</form>
+
+<p>
+ No, cancel this deletion and return to
+ [%+ "$terms.bug " _ a.bug_id FILTER bug_link(a.bug_id) FILTER none %].
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/attachment/create.html.tmpl b/template/en/default/attachment/create.html.tmpl
new file mode 100644
index 0000000..abc0f97
--- /dev/null
+++ b/template/en/default/attachment/create.html.tmpl
@@ -0,0 +1,133 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# Define strings that will serve as the title and header of this page %]
+[% title = BLOCK %]Create New Attachment for [% terms.Bug %] #[% bug.bug_id %][% END %]
+[% header = BLOCK %]Create New Attachment for
+ [%+ "$terms.Bug $bug.bug_id" FILTER bug_link(bug) FILTER none %][% END %]
+[% subheader = BLOCK %][% bug.short_desc FILTER html %][% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ header = header
+ subheader = subheader
+ style_urls = [ 'skins/standard/attachment.css' ]
+ yui = [ 'autocomplete' ]
+ javascript_urls = [ "js/attachment.js", 'js/field.js', "js/util.js", "js/TUI.js" ]
+ doc_section = "attachments.html"
+%]
+
+<script type="text/javascript">
+<!--
+TUI_hide_default('attachment_text_field');
+-->
+</script>
+
+<form name="entryform" method="post" action="attachment.cgi"
+ enctype="multipart/form-data"
+ onsubmit="return validateAttachmentForm(this)">
+ <input type="hidden" name="bugid" value="[% bug.bug_id %]">
+ <input type="hidden" name="action" value="insert">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+
+ <table class="attachment_entry">
+ [% PROCESS attachment/createformcontents.html.tmpl %]
+
+ [%# Additional fields for attachments on existing bugs: %]
+ [% IF attachments.size %]
+ <tr>
+ <th>Obsoletes:</th>
+ <td>
+ <em>(optional) Check each existing attachment made obsolete by your new attachment.</em><br>
+ [% FOREACH attachment = attachments %]
+ <input type="checkbox" id="[% attachment.id %]"
+ name="obsolete" value="[% attachment.id %]">
+ <a href="attachment.cgi?id=[% attachment.id %]&amp;action=edit">[% attachment.id %]: [% attachment.description FILTER html %]</a><br>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+
+ [% IF (user.id != bug.assigned_to.id) AND user.in_group("editbugs", bug.product_id) %]
+ <tr>
+ <th>Reassignment:</th>
+ <td>
+ <em>If you want to assign this [% terms.bug %] to yourself,
+ check the box below.</em><br>
+ <input type="checkbox" id="takebug" name="takebug" value="1">
+ <label for="takebug">take [% terms.bug %]</label>
+ [% bug_statuses = [] %]
+ [% FOREACH bug_status = bug.status.can_change_to %]
+ [% NEXT IF bug_status.name == "UNCONFIRMED"
+ && !bug.product_obj.allows_unconfirmed %]
+ [% bug_statuses.push(bug_status) IF bug_status.is_open %]
+ [% END %]
+ [% IF bug_statuses.size %]
+ <label for="takebug">and set the [% terms.bug %] status to</label>
+ <select id="bug_status" name="bug_status">
+ <option value="[% bug.status.name FILTER html %]">[% display_value("bug_status", bug.status.name) FILTER html %] (current)</option>
+ [% FOREACH bug_status = bug_statuses %]
+ [% NEXT IF bug_status.id == bug.status.id %]
+ <option value="[% bug_status.name FILTER html %]">[% display_value("bug_status", bug_status.name) FILTER html %]</option>
+ [% END %]
+ </select>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+ <tr>
+ <th><label for="comment">Comment:</label></th>
+ <td>
+ <em>(optional) Add a comment about this attachment to the [% terms.bug %].</em><br>
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'comment'
+ id = 'comment'
+ minrows = 6
+ maxrows = 15
+ cols = constants.COMMENT_COLS
+ wrap = 'soft'
+ %]
+ [% IF NOT bug.cc.contains(user.login) %]
+ <br>
+ <input type="checkbox" id="addselfcc" name="addselfcc"
+ [%~ ' checked="checked"'
+ IF user.settings.state_addselfcc.value == 'always'
+ || (!bug.user.has_any_role
+ && user.settings.state_addselfcc.value == 'cc_unless_role') %]>
+ <label for="addselfcc">Add me to CC list</label>
+ [% END %]
+ </td>
+ </tr>
+ [% IF user.is_insider %]
+ <tr>
+ <th>Privacy:</th>
+ <td>
+ <input type="checkbox" name="isprivate" id="isprivate"
+ value="1" onClick="updateCommentPrivacy(this)">
+ <label for="isprivate">
+ Make attachment and comment private (visible only to members of
+ the <strong>[% Param('insidergroup') FILTER html %]</strong>
+ group)
+ </label>
+ </td>
+ </tr>
+ [% END %]
+
+ [% Hook.process('form_before_submit') %]
+
+ <tr>
+ <th>&nbsp;</th>
+ <td><input type="submit" id="create" value="Submit"></td>
+ </tr>
+ </table>
+
+</form>
+
+[% Hook.process('end') %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/attachment/created.html.tmpl b/template/en/default/attachment/created.html.tmpl
new file mode 100644
index 0000000..cbfd260
--- /dev/null
+++ b/template/en/default/attachment/created.html.tmpl
@@ -0,0 +1,54 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # attachment: object of the attachment just created.
+ # contenttypemethod: string. How we got the content type of the attachment.
+ # Possible values: autodetect, list, manual.
+ #%]
+
+[% bug = bugs.0 %]
+[% PROCESS "bug/show-header.html.tmpl" %]
+[% PROCESS global/header.html.tmpl
+ title = "Attachment $attachment.id added to $terms.Bug $attachment.bug_id"
+%]
+
+<dl>
+ <dt>
+ <a title="[% attachment.description FILTER html %]"
+ href="attachment.cgi?id=[% attachment.id %]&amp;action=edit">Attachment #[% attachment.id %]</a>
+ to [% "$terms.bug $attachment.bug_id" FILTER bug_link(attachment.bug_id) FILTER none %] created
+ </dt>
+ <dd>
+ [% PROCESS "bug/process/bugmail.html.tmpl" mailing_bugid = attachment.bug_id %]
+ [% IF convertedbmp %]
+ <p>
+ <b>Note:</b> [% terms.Bugzilla %] automatically converted your BMP image file to a
+ compressed PNG format.
+ </p>
+ [% END %]
+ [% IF contenttypemethod == 'autodetect' %]
+ <p>
+ <b>Note:</b> [% terms.Bugzilla %] automatically detected the content type
+ <em>[% attachment.contenttype FILTER html %]</em> for this attachment. If this is
+ incorrect, correct the value by editing the attachment's
+ <a href="attachment.cgi?id=[% attachment.id %]&amp;action=edit">details</a>.
+ </p>
+ [% END %]
+
+ [%# Links to more information about the changed bug. %]
+ [% Hook.process("links") %]
+ </dd>
+</dl>
+
+<p>
+<a href="attachment.cgi?bugid=[% attachment.bug_id %]&amp;action=enter">Create
+ Another Attachment to [% terms.Bug %] [%+ attachment.bug_id %]</a>
+</p>
+
+[% PROCESS bug/show.html.tmpl %]
diff --git a/template/en/default/attachment/createformcontents.html.tmpl b/template/en/default/attachment/createformcontents.html.tmpl
new file mode 100644
index 0000000..48e4f4a
--- /dev/null
+++ b/template/en/default/attachment/createformcontents.html.tmpl
@@ -0,0 +1,98 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% max_local = Param('maxlocalattachment') * 1024 %]
+[% max_limit = Param('maxattachmentsize')> max_local ? Param('maxattachmentsize') : max_local %]
+<tr class="attachment_data">
+ <th><label for="data">File</label>:</th>
+ <td>
+ <em>Enter the path to the file on your computer</em> (or
+ <a id="attachment_data_controller" href="javascript:TUI_toggle_class('attachment_text_field');
+ javascript:TUI_toggle_class('attachment_data')"
+ >paste text as attachment</a>).<br>
+ <input type="file" id="data" name="data" size="50" onchange="DataFieldHandler()">
+ <br><em>(File size limit: [% max_limit FILTER html %] KB)</em>
+ </td>
+</tr>
+<tr class="attachment_text_field">
+ <th><label for="attach_text">File</label>:</th>
+ <td>
+ <em>Paste the text to be added as an attachment</em> (or
+ <a id="attachment_text_field_controller" href="javascript:TUI_toggle_class('attachment_text_field');
+ javascript:TUI_toggle_class('attachment_data')"
+ >attach a file</a>).<br>
+ <textarea id="attach_text" name="attach_text" cols="80" rows="15"
+ onkeyup="TextFieldHandler()" onblur="TextFieldHandler()"></textarea>
+ </td>
+</tr>
+<tr>
+ <th class="required"><label for="description">Description</label>:</th>
+ <td>
+ <em>Describe the attachment briefly.</em><br>
+ <input type="text" id="description" name="description" class="required"
+ size="60" maxlength="200">
+ </td>
+</tr>
+<tr[% ' class="expert_fields"' UNLESS bug.id %]>
+ <th>Content Type:</th>
+ <td>
+ <em>If the attachment is a patch, check the box below.</em><br>
+ <input type="checkbox" id="ispatch" name="ispatch" value="1"
+ onchange="setContentTypeDisabledState(this.form);">
+ <label for="ispatch">patch</label><br><br>
+ [%# Reset this whenever the page loads so that the JS state is up to date %]
+ <script type="text/javascript">
+ YAHOO.util.Event.onDOMReady(function() {
+ bz_fireEvent(document.getElementById('ispatch'), 'change');
+ });
+ </script>
+
+ <em>Otherwise, choose a method for determining the content type.</em><br>
+ <input type="radio" id="autodetect"
+ name="contenttypemethod" value="autodetect" checked="checked">
+ <label for="autodetect">auto-detect</label><br>
+ <input type="radio" id="list"
+ name="contenttypemethod" value="list">
+ <label for="list">select from list</label>:
+ <select name="contenttypeselection" id="contenttypeselection"
+ onchange="this.form.contenttypemethod[1].checked = true;">
+ [% PROCESS content_types %]
+ </select><br>
+ <input type="radio" id="manual"
+ name="contenttypemethod" value="manual">
+ <label for="manual">enter manually</label>:
+ <input type="text" name="contenttypeentry" id="contenttypeentry"
+ size="30" maxlength="200"
+ onchange="if (this.value) this.form.contenttypemethod[2].checked = true;">
+ </td>
+</tr>
+<tr[% ' class="expert_fields"' UNLESS bug.id %]>
+ <td> </td>
+ <td>
+ [% IF flag_types && flag_types.size > 0 %]
+ [% PROCESS "flag/list.html.tmpl" %]<br>
+ [% END %]
+ </td>
+</tr>
+
+[% BLOCK content_types %]
+ [% mimetypes = [{type => "text/plain", desc => "plain text"},
+ {type => "text/html", desc => "HTML source"},
+ {type => "application/xml", desc => "XML source"},
+ {type => "image/gif", desc => "GIF image"},
+ {type => "image/jpeg", desc => "JPEG image"},
+ {type => "image/png", desc => "PNG image"},
+ {type => "application/pdf", desc => "PDF document"},
+ {type => "application/octet-stream", desc => "binary file"}]
+ %]
+ [% Hook.process("mimetypes", "attachment/createformcontents.html.tmpl") %]
+
+ [% FOREACH m = mimetypes %]
+ <option value="[% m.type FILTER html %]">[% m.desc FILTER html %] ([% m.type FILTER html %])</option>
+ [% END %]
+[% END %]
diff --git a/template/en/default/attachment/delete_reason.txt.tmpl b/template/en/default/attachment/delete_reason.txt.tmpl
new file mode 100644
index 0000000..1631555
--- /dev/null
+++ b/template/en/default/attachment/delete_reason.txt.tmpl
@@ -0,0 +1,18 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # attachment: object of the attachment the user wants to delete.
+ # reason: string; The reason provided by the user.
+ #%]
+
+The content of attachment [% attachment.id %] has been deleted
+[%~ IF reason %] for the following reason:
+
+[%+ reason %]
+[% END %]
diff --git a/template/en/default/attachment/diff-file.html.tmpl b/template/en/default/attachment/diff-file.html.tmpl
new file mode 100644
index 0000000..815b6de
--- /dev/null
+++ b/template/en/default/attachment/diff-file.html.tmpl
@@ -0,0 +1,164 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# This line is really long for a reason: to get rid of any possible textnodes
+ # between the elements. This is necessary because DOM parent-child-sibling
+ # relations can change and screw up the javascript for restoring, collapsing
+ # and expanding. Do not change without testing all three of those.
+ # Also, the first empty row is required because 'table-layout: fixed' only
+ # considers the first row to determine column widths. If a colspan is found,
+ # it then share the width equally among all columns, which we don't want.
+ #%]
+<table class="file_table"><thead><tr><td class="num"></td><td></td><td class="num"></td><td></td></tr><tr><td class="file_head" colspan="4"><a href="#" onclick="return twisty_click(this)">[% collapsed ? '(+)' : '(-)' %]</a><input type="checkbox" name="[% file.filename FILTER html %]"[% collapsed ? '' : ' checked' %] style="display: none">
+ [% IF lxr_prefix && !file.is_add %]
+ <a href="[% lxr_prefix %]">[% file.filename FILTER html %]</a>
+ [% ELSE %]
+ [% file.filename FILTER html %]
+ [% END %]
+ [% IF file.plus_lines %]
+ [% IF file.minus_lines %]
+ (-[% file.minus_lines %]&nbsp;/&nbsp;+[% file.plus_lines %]&nbsp;lines)
+ [% ELSE %]
+ (+[% file.plus_lines %]&nbsp;lines)
+ [% END %]
+ [% ELSE %]
+ [% IF file.minus_lines %]
+ (-[% file.minus_lines %]&nbsp;lines)
+ [% END %]
+ [% END %]
+</td></tr></thead><tbody class="[% collapsed ? 'file_collapse' : 'file' %]">
+<script type="text/javascript">
+incremental_restore()
+</script>
+
+[% section_num = 0 %]
+[% FOREACH section = sections %]
+ [% section_num = section_num + 1 %]
+ <tr><th colspan="4" class="section_head">
+ <table id="[% file.filename FILTER html %]_sec[% section_num %]" cellpadding="0" cellspacing="0">
+ <tr><th width="95%" align="left">
+ [% IF file.is_add %]
+ Added
+ [% ELSIF file.is_remove %]
+ [% IF bonsai_prefix %]
+ <a href="[% bonsai_prefix %]">Removed</a>
+ [% ELSE %]
+ Removed
+ [% END %]
+ [% ELSE %]
+ [% IF bonsai_prefix %]
+ <a href="[% bonsai_prefix %]#[% section.old_start %]">
+ [% END %]
+ [% IF section.old_lines > 1 %]
+ &nbsp;Lines&nbsp;[% section.old_start %]-[% section.old_start +
+ section.old_lines - 1 %]
+ [% ELSE %]
+ Line&nbsp;[% section.old_start %]
+ [% END %]
+ [% IF bonsai_prefix %]
+ </a>
+ [% END %]
+ &nbsp;&nbsp;[% section.func_info FILTER html IF section.func_info %]
+ [% END %]
+ </th><th>
+ <a href="#[% file.filename FILTER html %]_sec[% section_num %]">Link&nbsp;Here</a>&nbsp;
+ </th></tr></table>
+ </th></tr>
+ [% current_line_old = section.old_start %]
+ [% current_line_new = section.new_start %]
+ [% FOREACH group = section.groups %]
+ [% IF group.context %]
+ [% FOREACH line = group.context %]
+ <tr>
+ <td class="num">[% current_line_old %]</td>
+ <td><pre>[% line FILTER html %]</pre></td>
+ <td class="num">[% current_line_new %]</td>
+ <td><pre>[% line FILTER html %]</pre></td>
+ </tr>
+ [% current_line_old = current_line_old + 1 %]
+ [% current_line_new = current_line_new + 1 %]
+ [% END %]
+ [% END %]
+ [% IF group.plus.size %]
+ [% IF group.minus.size %]
+ [% i = 0 %]
+ [% WHILE (i < group.plus.size || i < group.minus.size) %]
+ [%# WHILE cannot loop more than 1000 times by default, so we break it every 500 times. %]
+ [% currentloop = 0 %]
+ [% WHILE currentloop < 500 && (i < group.plus.size || i < group.minus.size) %]
+ <tr>
+ [% IF i < group.minus.size %]
+ <td class="num">[% current_line_old + i %]</td>
+ <td class="changed"><pre>[% group.minus.$i FILTER html %]</pre></td>
+ [% ELSIF i == group.minus.size %]
+ [% rowspan = group.plus.size - group.minus.size %]
+ <td class="num"[% IF rowspan > 1 %] rowspan="[% rowspan FILTER none %]"[% END %]></td>
+ <td class="changed"[% IF rowspan > 1 %] rowspan="[% rowspan FILTER none %]"[% END %]></td>
+ [% END %]
+
+ [% IF i < group.plus.size %]
+ <td class="num">[% current_line_new + i %]</td>
+ <td class="changed"><pre>[% group.plus.$i FILTER html %]</pre></td>
+ [% ELSIF i == group.plus.size %]
+ [% rowspan = group.minus.size - group.plus.size %]
+ <td class="num"[% IF rowspan > 1 %] rowspan="[% rowspan FILTER none %]"[% END %]></td>
+ <td class="changed"[% IF rowspan > 1 %] rowspan="[% rowspan FILTER none %]"[% END %]></td>
+ [% END %]
+ </tr>
+ [% currentloop = currentloop + 1 %]
+ [% i = i + 1 %]
+ [% END %]
+ [% END %]
+ [% current_line_old = current_line_old + group.minus.size %]
+ [% current_line_new = current_line_new + group.plus.size %]
+ [% ELSE %]
+ [% FOREACH line = group.plus %]
+ [% IF file.is_add %]
+ <tr>
+ <td class="num">[% current_line_new %]</td>
+ <td class="added" colspan="3"><pre>[% line FILTER html %]</pre></td>
+ </tr>
+ [% ELSE %]
+ <tr>
+ [% IF loop.first %]
+ <td class="num"[% IF group.plus.size > 1 %] rowspan="[% group.plus.size %]"[% END %]></td>
+ <td[% IF group.plus.size > 1 %] rowspan="[% group.plus.size %]"[% END %]></td>
+ [% END %]
+ <td class="num">[% current_line_new %]</td>
+ <td class="added"><pre>[% line FILTER html %]</pre></td>
+ </tr>
+ [% END %]
+ [% current_line_new = current_line_new + 1 %]
+ [% END %]
+ [% END %]
+ [% ELSE %]
+ [% IF group.minus.size %]
+ [% FOREACH line = group.minus %]
+ [% IF file.is_remove %]
+ <tr>
+ <td class="num">[% current_line_old %]</td>
+ <td class="removed" colspan="3"><pre>[% line FILTER html %]</pre></td>
+ </tr>
+ [% ELSE %]
+ <tr>
+ <td class="num">[% current_line_old %]</td>
+ <td class="removed"><pre>[% line FILTER html %]</pre></td>
+ [% IF loop.first %]
+ <td class="num"[% IF group.minus.size > 1 %] rowspan="[% group.minus.size %]"[% END %]></td>
+ <td[% IF group.minus.size > 1 %] rowspan="[% group.minus.size %]"[% END %]></td>
+ [% END %]
+ </tr>
+ [% END %]
+ [% current_line_old = current_line_old + 1 %]
+ [% END %]
+ [% END %]
+ [% END %]
+ [% END %]
+[% END %]
+
+</table>
diff --git a/template/en/default/attachment/diff-footer.html.tmpl b/template/en/default/attachment/diff-footer.html.tmpl
new file mode 100644
index 0000000..0e95423
--- /dev/null
+++ b/template/en/default/attachment/diff-footer.html.tmpl
@@ -0,0 +1,21 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+</form>
+
+[% IF headers %]
+
+ <br>
+ <span>Return to [% "$terms.bug $bugid" FILTER bug_link(bugid) FILTER none %]</span>
+
+ [% PROCESS global/footer.html.tmpl %]
+
+[% ELSE %]
+</body>
+</html>
+[% END %]
diff --git a/template/en/default/attachment/diff-header.html.tmpl b/template/en/default/attachment/diff-header.html.tmpl
new file mode 100644
index 0000000..ed4d44e
--- /dev/null
+++ b/template/en/default/attachment/diff-header.html.tmpl
@@ -0,0 +1,139 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# Define strings that will serve as the title and header of this page %]
+
+[% title = BLOCK %]
+ [% IF attachid %]
+Attachment #[% attachid %] for [% terms.bug %] #[% bugid %]
+ [% ELSE %]
+Interdiff of #[% oldid %] and #[% newid %] for [% terms.bug %] #[% bugid %]
+ [% END %]
+[% END %]
+
+[% onload = 'restore_all(); document.checkboxform.restore_indicator.checked = true' %]
+
+[% BLOCK viewurl %]attachment.cgi?id=[% id %][% END %]
+[% BLOCK editurl %][% PROCESS viewurl %]&amp;action=edit[% END %]
+[% BLOCK diffurl %][% PROCESS viewurl %]&amp;action=diff[% END %]
+
+[% IF headers %]
+ [% header = BLOCK %]
+ [% IF attachid %]
+ Attachment #[% attachid %]: [% description FILTER html %]
+ [% ELSE %]
+ Diff Between
+ #[% oldid %]: <a href="[% PROCESS diffurl id=oldid %]">[% old_desc FILTER html %]</a>
+ and
+ #[% newid %]: <a href="[% PROCESS diffurl id=newid %]">[% new_desc FILTER html %]</a>
+ [% END %]
+ for <a href="show_bug.cgi?id=[% bugid %]">[% terms.bug %] #[% bugid %]</a>
+ [% END %]
+ [% subheader = BLOCK %]
+ [% bugsummary FILTER html %]
+ [% END %]
+ [% PROCESS global/header.html.tmpl doc_section = "attachments.html#patchviewer"
+ javascript_urls = "js/attachment.js"
+ style_urls = ['skins/standard/attachment.css'] %]
+[% ELSE %]
+ <html>
+ <head>
+ <link href="[% 'skins/standard/attachment.css' FILTER mtime %]"
+ rel="stylesheet" type="text/css">
+ <script src="[% 'js/attachment.js' FILTER mtime %]"
+ type="text/javascript"></script>
+ </head>
+ <body onload="[% onload FILTER html %]">
+[% END %]
+
+[%# If we have attachid, we are in diff, otherwise we're in interdiff %]
+[% IF attachid %]
+ [%# HEADER %]
+ [% IF headers %]
+ <a href="[% PROCESS viewurl id=attachid %]">View</a>
+ | <a href="[% PROCESS editurl id=attachid %]">Details</a>
+ | <a href="[% PROCESS diffurl id=attachid %]&amp;context=[% context FILTER uri %]&amp;collapsed=[% collapsed FILTER uri %]&amp;headers=[% headers FILTER uri %]&amp;format=raw">Raw&nbsp;Unified</a>
+ | Return to [% "$terms.bug $bugid" FILTER bug_link(bugid) FILTER none %]
+ [% END %]
+ [% IF other_patches.size > 0 %]
+ [% IF headers %] |[%END%]
+ Differences between
+ <form style="display: inline" action="attachment.cgi">
+ <select name="oldid">
+ [% FOREACH patch = other_patches %]
+ <option value="[% patch.id %]"
+ [% IF patch.selected %] selected[% END %]
+ >[% patch.desc FILTER html %]</option>
+ [% END %]
+ </select>
+ and this patch
+ <input type="submit" id="diff" value="Diff">
+ <input type="hidden" name="action" value="interdiff">
+ <input type="hidden" name="newid" value="[% attachid %]">
+ <input type="hidden" name="headers" value="[% headers FILTER html %]">
+ </form>
+ [% END %]
+ <br>
+[% ELSE %]
+ [% IF headers %]
+ <a href="attachment.cgi?oldid=[% oldid %]&amp;newid=[% newid %]&amp;action=interdiff&amp;format=raw">Raw Unified</a>
+ | Return to [% "$terms.bug $bugid" FILTER bug_link(bugid) FILTER none %]
+ |
+ [% END %]
+[% END %]
+
+[%# Collapse / Expand %]
+<a href="#"
+ onmouseover="lastStatus = window.status; window.status='Collapse All'; return true"
+ onmouseout="window.status = lastStatus; return true"
+ onclick="return collapse_all()">Collapse All</a> |
+<a href="#"
+ onmouseover="lastStatus = window.status; window.status='Expand All'; return true"
+ onmouseout="window.status = lastStatus; return true"
+ onclick="return expand_all()">Expand All</a>
+
+[% IF do_context %]
+ [%# only happens for normal viewing, not interdiff %]
+ | <span style='font-weight: bold'>Context:</span>
+ [% IF context == "patch" %]
+ (<strong>Patch</strong> /
+ [% ELSE %]
+ (<a href="[% PROCESS diffurl id=attachid %]&amp;headers=[% headers FILTER uri %]">Patch</a> /
+ [% END %]
+ [% IF context == "file" %]
+ <strong>File</strong> /
+ [% ELSE %]
+ <a href="[% PROCESS diffurl id=attachid %]&amp;headers=[% headers FILTER uri %]&amp;context=file">File</a> /
+ [% END %]
+
+ [% IF context == "patch" || context == "file" %]
+ [% context = 3 %]
+ [% END %]
+ [%# textbox for context %]
+ <form style="display: inline" action="attachment.cgi"><input type="hidden" name="action" value="diff"><input type="hidden" name="id" value="[% attachid %]"><input type="hidden" name="collapsed" value="[% collapsed FILTER html %]"><input type="hidden" name="headers" value="[% headers FILTER html %]"><input type="text" name="context" value="[% context FILTER html %]" size="3"></form>)
+[% END %]
+
+[% IF warning %]
+<h2 class="warning">Warning:
+ [% IF warning == "interdiff1" %]
+ this difference between two patches may show things in the wrong places due
+ to a limitation in [% terms.Bugzilla %] when comparing patches with different
+ sets of files.
+ [% END %]
+ [% IF warning == "interdiff2" %]
+ this difference between two patches may be inaccurate due to a limitation in
+ [%+ terms.Bugzilla %] when comparing patches made against different revisions.
+ [% END %]
+</h2>
+[% ELSE %]
+ <br><br>
+[% END %]
+
+[%# Restore Stuff %]
+<form name="checkboxform" action="attachment.cgi">
+<input type="checkbox" name="restore_indicator" style="display: none">
diff --git a/template/en/default/attachment/edit.html.tmpl b/template/en/default/attachment/edit.html.tmpl
new file mode 100644
index 0000000..5187377
--- /dev/null
+++ b/template/en/default/attachment/edit.html.tmpl
@@ -0,0 +1,331 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# Define strings that will serve as the title and header of this page %]
+[% title = BLOCK %]
+ Attachment [% attachment.id %] Details for [% terms.Bug %] [%+ attachment.bug_id %]
+[% END %]
+[% header = BLOCK %]
+ Attachment [% attachment.id %] Details for
+ [%+ "$terms.Bug ${attachment.bug_id}" FILTER bug_link(attachment.bug_id) FILTER none %]
+[% END %]
+[% subheader = BLOCK %][% attachment.bug.short_desc FILTER html %][% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ header = header
+ subheader = subheader
+ doc_section = "attachments.html"
+ javascript_urls = ['js/attachment.js', 'js/field.js']
+ style_urls = ['skins/standard/attachment.css']
+ yui = [ 'autocomplete' ]
+ bodyclasses = "no_javascript"
+%]
+
+[%# No need to display the Diff button and iframe if the attachment is not a patch. %]
+[% use_patchviewer = (feature_enabled('patch_viewer') && attachment.ispatch) %]
+[% can_edit = attachment.validate_can_edit %]
+[% editable_or_hide = can_edit ? "" : " bz_hidden_option" %]
+
+<form method="post" action="attachment.cgi" onsubmit="normalizeComments();">
+ <input type="hidden" name="id" value="[% attachment.id %]">
+ <input type="hidden" name="action" value="update">
+ <input type="hidden" name="contenttypemethod" value="manual">
+ <input type="hidden" name="delta_ts" value="[% attachment.modification_time FILTER html %]">
+ [% IF user.id %]
+ <input type="hidden" name="token" value="[% issue_hash_token([attachment.id, attachment.modification_time]) FILTER html %]">
+ [% END %]
+
+ <div id="attachment_info" class="attachment_info [% IF can_edit %] edit[% ELSE %] read[% END%]">
+ <div id="attachment_attributes">
+ <div id="attachment_information_read_only" class="[% "bz_private" IF attachment.isprivate %]">
+ <div class="title">
+ [% "[patch]" IF attachment.ispatch%]
+ <span class="[% "bz_obsolete" IF attachment.isobsolete %]" title="[% "obsolete" IF attachment.isobsolete %]">
+ [% attachment.description FILTER html %]
+ </span>
+ [% IF can_edit %]
+ <span class="bz_edit">(<a href="javascript:toggle_attachment_details_visibility()">edit details</a>)</span>
+ [% END %]
+ </div>
+ <div class="details">
+ [% attachment.filename FILTER html %] ([% attachment.contenttype FILTER html %]),
+ [% IF attachment.datasize %]
+ [%+ attachment.datasize FILTER unitconvert %]
+ [% ELSE %]
+ <em>deleted</em>
+ [% END %], created by [%+ INCLUDE global/user.html.tmpl who = attachment.attacher %] on [%+ attachment.attached FILTER time %]
+ [% IF attachment.isprivate %];
+ <span class="bz_private">only visible to <strong>[% Param('insidergroup') FILTER html %]</strong> members</span>
+ [% END %]
+ </div>
+ </div>
+ <div id="attachment_information_edit">
+ <span class="bz_hide">
+ (<a href="javascript:toggle_attachment_details_visibility();">hide</a>)
+ </span>
+ <div id="attachment_description">
+ <label for="description">Description:</label>&nbsp;
+ [% INCLUDE global/textarea.html.tmpl
+ id = 'description'
+ name = 'description'
+ minrows = 3
+ cols = 25
+ wrap = 'soft'
+ classes = 'block' _ editable_or_hide
+ defaultcontent = attachment.description
+ %]
+ </div>
+
+ <div id="attachment_filename">
+ <label for="filename">Filename:</label>
+ <input type="text" size="20" class="text block[% editable_or_hide %]"
+ id="filename" name="filename"
+ value="[% attachment.filename FILTER html %]">
+ </div>
+
+ <div id="attachment_mimetype">
+ <label for="contenttypeentry">MIME Type:</label>
+ <input type="text" size="20" class="text block[% editable_or_hide %]"
+ id="contenttypeentry" name="contenttypeentry"
+ value="[% attachment.contenttype FILTER html %]">
+ </div>
+
+ <div id="attachment_creator">
+ <span class="label">Creator:</span>
+ [%+ INCLUDE global/user.html.tmpl who = attachment.attacher %]
+ </div>
+
+ <div id="attachment_created">
+ <span class="label">Created:</span>
+ [%+ attachment.attached FILTER time %]
+ </div>
+
+ <div id="attachment_size">
+ <span class="label">Size:</span>
+ [% IF attachment.datasize %]
+ [%+ attachment.datasize FILTER unitconvert %]
+ [% ELSE %]
+ <em>deleted</em>
+ [% END %]
+ </div>
+
+ <div id="attachment_ispatch">
+ <input type="checkbox" id="ispatch" name="ispatch" value="1"
+ [%+ 'checked="checked"' IF attachment.ispatch %]>
+ <label for="ispatch">patch</label>
+ </div>
+
+ <div class="readonly">
+ <div class="checkboxes">
+ <div id="attachment_isobsolete">
+ <input type="checkbox" id="isobsolete" name="isobsolete" value="1"
+ [%+ 'checked="checked"' IF attachment.isobsolete %]>
+ <label for="isobsolete">obsolete</label>
+ </div>
+
+ [% IF user.is_insider %]
+ <div id="attachment_isprivate">
+ <input type="checkbox" id="isprivate" name="isprivate" value="1"
+ [%+ 'checked="checked"' IF attachment.isprivate %]>
+ [% IF can_edit %]
+ <label for="isprivate">private (only visible to
+ <strong>[% Param('insidergroup') FILTER html %]</strong>)
+ </label>
+ [% ELSE %]
+ <span class="label">Is Private:</span>
+ [%+ attachment.isprivate ? "yes" : "no" %]
+ [% END %]
+ </div>
+ [% END %]
+ </div>
+ </div>
+ </div>
+
+ <div id="attachment_view_window">
+ [% IF !attachment.datasize %]
+ <div><b>The content of this attachment has been deleted.</b></div>
+ [% ELSIF !Param("allow_attachment_display") %]
+ <div id="view_disabled">
+ <p><b>
+ The attachment is not viewable in your browser due to security
+ restrictions enabled by your [% terms.Bugzilla %] administrator.
+ </b></p>
+ <p><b>
+ In order to view the attachment, you first have to
+ <a href="attachment.cgi?id=[% attachment.id %]">download it</a>.
+ </b></p>
+ </div>
+ [% ELSIF attachment.is_viewable %]
+ <div>
+ [% INCLUDE global/textarea.html.tmpl
+ id = 'editFrame'
+ name = 'comment'
+ classes = 'bz_default_hidden'
+ minrows = 10
+ cols = 80
+ wrap = 'soft'
+ disabled = 'disabled'
+ defaultcontent = (attachment.contenttype.match('^text\/')) ?
+ attachment.data.replace('(.*\n|.+)', '>$1') : undef
+ %]
+ [% IF attachment.contenttype == 'text/plain' AND is_safe_url(attachment.data) %]
+ <p>
+ <a href="[% attachment.data FILTER html %]">
+ [% IF attachment.datasize < 120 %]
+ [% attachment.data FILTER html %]
+ [% ELSE %]
+ [% attachment.data FILTER truncate(80) FILTER html %]
+ ...
+ [% attachment.data.match('.*(.{20})$').0 FILTER html %]
+ [% END %]
+ </a>
+ </p>
+ [% ELSIF attachment.contenttype == "text/html" %]
+ [%# For security reasons (clickjacking, embedded scripts), we never
+ # render HTML pages from here. The source code is displayed instead. %]
+ [% INCLUDE global/textarea.html.tmpl
+ id = 'viewFrame'
+ minrows = 10
+ cols = 80
+ defaultcontent = attachment.data
+ readonly = 'readonly'
+ %]
+ [% ELSE %]
+ <iframe id="viewFrame" src="attachment.cgi?id=[% attachment.id %]">
+ <b>You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
+ <a href="attachment.cgi?id=[% attachment.id %]">View the attachment on a separate page</a>.</b>
+ </iframe>
+ [% END %]
+ <script type="text/javascript">
+ <!--
+ var patchviewerinstalled = 0;
+ var attachment_id = [% attachment.id %];
+ if (typeof document.getElementById == "function") {
+ [% IF use_patchviewer %]
+ var patchviewerinstalled = 1;
+ document.write('<iframe id="viewDiffFrame" class="bz_default_hidden"><\/iframe>');
+ [% END %]
+ [% IF user.id %]
+ document.write('<button type="button" id="editButton" onclick="editAsComment(patchviewerinstalled);">Edit Attachment As Comment<\/button>');
+ document.write('<button type="button" id="undoEditButton" onclick="undoEditAsComment(patchviewerinstalled);" class="bz_default_hidden">Undo Edit As Comment<\/button>');
+ document.write('<button type="button" id="redoEditButton" onclick="redoEditAsComment(patchviewerinstalled);" class="bz_default_hidden">Redo Edit As Comment<\/button>');
+ var editFrame = document.getElementById('editFrame');
+ if (editFrame) {
+ editFrame.disabled = false;
+ }
+ [% END %]
+ [% IF use_patchviewer %]
+ document.write('<button type="button" id="viewDiffButton" onclick="viewDiff(attachment_id, patchviewerinstalled);">View Attachment As Diff<\/button>');
+ [% END %]
+ document.write('<button type="button" id="viewRawButton" onclick="viewRaw(patchviewerinstalled);" class="bz_default_hidden">View Attachment As Raw<\/button>');
+ }
+ //-->
+ </script>
+ </div>
+ [% ELSE %]
+ <div id="noview">
+ <p><b>
+ Attachment is not viewable in your browser because its MIME type
+ ([% attachment.contenttype FILTER html %]) is not one that your browser is
+ able to display.
+ </b></p>
+ <p><b>
+ <a href="attachment.cgi?id=[% attachment.id %]">Download the attachment</a>.
+ </b></p>
+ </div>
+ [% END %]
+ </div>
+ <div id="attachment_comments_and_flags">
+ [% IF user.id %]
+ <div id="smallCommentFrame" >
+ <label for="comment">Comment (on the [% terms.bug %]):</label>
+ [% classNames = 'block' %]
+ [% classNames = "$classes bz_private" IF attachment.isprivate %]
+ [% INCLUDE global/textarea.html.tmpl
+ id = 'comment'
+ name = 'comment'
+ minrows = 10
+ cols = 80
+ wrap = 'soft'
+ classes = classNames
+ %]
+ [% IF NOT attachment.bug.cc.contains(user.login) %]
+ <input type="checkbox" id="addselfcc" name="addselfcc"
+ [%~ ' checked="checked"'
+ IF user.settings.state_addselfcc.value == 'always'
+ || (!attachment.bug.user.has_any_role
+ && user.settings.state_addselfcc.value == 'cc_unless_role') %]>
+ <label for="addselfcc">Add me to CC list</label>
+ [% END %]
+ </div>
+ [% END %]
+ <div id="attachment_flags">
+ [% IF attachment.flag_types.size > 0 %]
+ [% PROCESS "flag/list.html.tmpl" flag_types = attachment.flag_types
+ read_only_flags = !can_edit
+ %]
+
+ [% END %]
+ </div>
+
+ [% Hook.process('form_before_submit') %]
+
+ [% IF user.id %]
+ <div id="update_container">
+ <input type="submit" value="Submit" id="update">
+ </div>
+ [% END %]
+ </div>
+ </div>
+ </div>
+</form>
+
+<div id="attachment_actions">
+ <span class="label">Actions:</span>
+ <a href="attachment.cgi?id=[% attachment.id %]">View</a>
+ [% IF use_patchviewer %]
+ | <a href="attachment.cgi?id=[% attachment.id %]&amp;action=diff">Diff</a>
+ [% END %]
+ [% IF Param("allow_attachment_deletion")
+ && user.in_group('admin')
+ && attachment.datasize > 0 %]
+ | <a href="attachment.cgi?id=[% attachment.id %]&amp;action=delete">Delete</a>
+ [% END %]
+ [% Hook.process('action') %]
+</div>
+
+<div id="attachment_list">
+ Attachments on [% "$terms.bug ${attachment.bug_id}" FILTER bug_link(attachment.bug_id) FILTER none %]:
+ [% FOREACH a = attachments %]
+ [% IF a.isobsolete %]
+ <span class="bz_obsolete">
+ [% END %]
+ [% IF a.id == attachment.id %]
+ [%+ a.id FILTER html %]
+ [% ELSE %]
+ <a href="attachment.cgi?id=[% a.id FILTER uri %]&amp;action=edit"
+ title="[% a.description FILTER html %]">[% a.id FILTER html %]</a>
+ [% END %]
+ [% IF a.isobsolete %]
+ </span>
+ [% END %]
+ [% " |" UNLESS loop.last() %]
+ [% END %]
+</div>
+[% IF can_edit %]
+ <script type="text/javascript">
+ <!--
+ YAHOO.util.Dom.removeClass( document.body, "no_javascript" );
+ toggle_attachment_details_visibility( );
+ -->
+ </script>
+[% END %]
+[% Hook.process('end') %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/attachment/list.html.tmpl b/template/en/default/attachment/list.html.tmpl
new file mode 100644
index 0000000..e30492c
--- /dev/null
+++ b/template/en/default/attachment/list.html.tmpl
@@ -0,0 +1,165 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% RETURN UNLESS attachments.size || Param("maxattachmentsize") || Param("maxlocalattachment") %]
+
+<script type="text/javascript">
+<!--
+function toggle_display(link) {
+ var table = document.getElementById("attachment_table");
+ var view_all = document.getElementById("view_all");
+ var hide_obsolete_url_parameter = "&hide_obsolete=1";
+ // Store current height for scrolling later
+ var originalHeight = table.offsetHeight;
+ var rows = YAHOO.util.Dom.getElementsByClassName(
+ 'bz_tr_obsolete', 'tr', table);
+
+ for (var i = 0; i < rows.length; i++) {
+ bz_toggleClass(rows[i], 'bz_default_hidden');
+ }
+
+ if (YAHOO.util.Dom.hasClass(rows[0], 'bz_default_hidden')) {
+ link.innerHTML = "Show Obsolete";
+ view_all.href = view_all.href + hide_obsolete_url_parameter
+ }
+ else {
+ link.innerHTML = "Hide Obsolete";
+ view_all.href = view_all.href.replace(hide_obsolete_url_parameter,"");
+ }
+
+ var newHeight = table.offsetHeight;
+ // This scrolling makes the window appear to not move at all.
+ window.scrollBy(0, newHeight - originalHeight);
+
+ return false;
+}
+//-->
+</script>
+
+<br>
+<table id="attachment_table" cellspacing="0" cellpadding="4">
+ <tr id="a0">
+ <th colspan="[% show_attachment_flags ? 3 : 2 %]" align="left">
+ Attachments
+ </th>
+ </tr>
+
+ [% count = 0 %]
+ [% obsolete_attachments = 0 %]
+ [% user_cache = template_cache.users %]
+
+ [% FOREACH attachment = attachments %]
+ [% count = count + 1 %]
+ [% IF !attachment.isprivate || user.is_insider || attachment.attacher.id == user.id %]
+ [% IF attachment.isobsolete %]
+ [% obsolete_attachments = obsolete_attachments + 1 %]
+ [% END %]
+ <tr id="a[% count %]" class="[% "bz_contenttype_" _ attachment.contenttype
+ FILTER css_class_quote %]
+ [% " bz_patch" IF attachment.ispatch %]
+ [% " bz_private" IF attachment.isprivate %]
+ [% " bz_tr_obsolete bz_default_hidden"
+ IF attachment.isobsolete %]">
+ <td valign="top">
+ [% IF attachment.datasize %]
+ <a href="attachment.cgi?id=[% attachment.id %]"
+ title="View the content of the attachment">
+ [% END %]
+ <b>[% attachment.description FILTER html FILTER obsolete(attachment.isobsolete) %]</b>
+ [% "</a>" IF attachment.datasize %]
+
+ <span class="bz_attach_extra_info">
+ [% IF attachment.datasize %]
+ ([% attachment.datasize FILTER unitconvert %],
+ [% IF attachment.ispatch %]
+ patch)
+ [% ELSE %]
+ [%+ attachment.contenttype FILTER html %])
+ [% END %]
+ [% ELSE %]
+ (<em>deleted</em>)
+ [% END %]
+
+ <br>
+ <a href="#attach_[% attachment.id %]"
+ title="Go to the comment associated with the attachment">
+ [%- attachment.attached FILTER time %]</a>,
+
+ [%# No need to recreate the exact same template if we already have it. %]
+ [% attacher_id = attachment.attacher.id %]
+ [% UNLESS user_cache.$attacher_id %]
+ [% user_cache.$attacher_id = BLOCK %]
+ [% INCLUDE global/user.html.tmpl who = attachment.attacher %]
+ [% END %]
+ [% END %]
+ [% user_cache.$attacher_id FILTER none %]
+ </span>
+ </td>
+
+ [% IF show_attachment_flags %]
+ <td class="bz_attach_flags" valign="top">
+ [% IF attachment.flags.size == 0 %]
+ <i>no flags</i>
+ [% ELSE %]
+ [% FOREACH flag = attachment.flags %]
+ [% IF user.id %]
+ <span title="[% flag.setter.identity FILTER html %]">[% flag.setter.nick FILTER html %]</span>:
+ [% ELSIF flag.setter.name %]
+ <span title="[% flag.setter.name FILTER html %]">[% flag.setter.nick FILTER html %]</span>:
+ [% ELSE %]
+ [% flag.setter.nick FILTER html %]:
+ [% END %]
+ [%+ flag.type.name FILTER html FILTER no_break %][% flag.status %]
+ [%+ IF flag.status == "?" && flag.requestee %]
+ [% IF user.id %]
+ (<span title="[% flag.requestee.identity FILTER html %]">[% flag.requestee.nick FILTER html %]</span>)
+ [% ELSIF flag.requestee.name %]
+ (<span title="[% flag.requestee.name FILTER html %]">[% flag.requestee.nick FILTER html %]</span>)
+ [% ELSE %]
+ ([% flag.requestee.nick FILTER html %])
+ [% END %]
+ [% END %]<br>
+ [% END %]
+ [% END %]
+ </td>
+ [% END %]
+
+ <td valign="top">
+ <a href="attachment.cgi?id=[% attachment.id %]&amp;action=edit">Details</a>
+ [% IF attachment.ispatch && feature_enabled('patch_viewer') %]
+ | <a href="attachment.cgi?id=[% attachment.id %]&amp;action=diff">Diff</a>
+ [% END %]
+ [% Hook.process("action") %]
+ </td>
+ </tr>
+ [% END %]
+ [% END %]
+
+ <tr class="bz_attach_footer">
+ <td colspan="[% show_attachment_flags ? 3 : 2 %]">
+ [% IF attachments.size %]
+ <span class="bz_attach_view_hide">
+ [% IF obsolete_attachments %]
+ <a href="#a0" onclick="return toggle_display(this);">Show
+ Obsolete</a> ([% obsolete_attachments %])
+ [% END %]
+ [% IF Param("allow_attachment_display") %]
+ <a id="view_all" href="attachment.cgi?bugid=
+ [%- bugid %]&amp;action=viewall
+ [%- "&amp;hide_obsolete=1" IF obsolete_attachments %]">View All</a>
+ [% END %]
+ </span>
+ [% END %]
+ [% IF Param("maxattachmentsize") || Param("maxlocalattachment") %]
+ <a href="attachment.cgi?bugid=[% bugid %]&amp;action=enter">Add an attachment</a>
+ (proposed patch, testcase, etc.)
+ [% END %]
+ </td>
+ </tr>
+</table>
+<br>
diff --git a/template/en/default/attachment/midair.html.tmpl b/template/en/default/attachment/midair.html.tmpl
new file mode 100644
index 0000000..68db5d9
--- /dev/null
+++ b/template/en/default/attachment/midair.html.tmpl
@@ -0,0 +1,64 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # operations: array; bug activity since the user last displayed the attachment form,
+ # used by bug/activity/table.html.tmpl to display recent changes that will
+ # be overwritten if the user submits these changes. See that template
+ # for further documentation.
+ # attachment: object; the attachment being changed.
+ #%]
+
+[%# The global Bugzilla->cgi object is used to obtain form variable values. %]
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+[% PROCESS global/header.html.tmpl title = "Mid-air collision!" %]
+
+<h1>Mid-air collision detected!</h1>
+
+<p>
+ Someone else has made changes to
+ <a href="attachment.cgi?id=[% attachment.id %]&amp;action=edit">attachment [% attachment.id %]</a>
+ of [% "$terms.bug $attachment.bug_id" FILTER bug_link(attachment.bug_id) FILTER none %]
+ at the same time you were trying to. The changes made were:
+</p>
+
+<p>
+ [% PROCESS "bug/activity/table.html.tmpl" incomplete_data=0 %]
+</p>
+
+[% IF cgi.param("comment") %]
+<p>
+ Your comment was:<br>
+ <blockquote><pre class="bz_comment_text">
+ [% cgi.param("comment") FILTER html %]
+ </pre></blockquote>
+</p>
+[% END %]
+
+<p>
+You have the following choices:
+</p>
+
+<ul>
+ <li>
+ <form method="post" action="attachment.cgi">
+ [% PROCESS "global/hidden-fields.html.tmpl" exclude="^Bugzilla_(login|password)$" %]
+ <input type="submit" id="process" value="Submit my changes anyway">
+ This will cause all of the above changes to be overwritten.
+ </form>
+ </li>
+ <li>
+ Throw away my changes, and
+ <a href="attachment.cgi?id=[% attachment.id %]&amp;action=edit">revisit
+ attachment [% attachment.id %]</a>
+ </li>
+</ul>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/attachment/show-multiple.html.tmpl b/template/en/default/attachment/show-multiple.html.tmpl
new file mode 100644
index 0000000..8791e0d
--- /dev/null
+++ b/template/en/default/attachment/show-multiple.html.tmpl
@@ -0,0 +1,106 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% filtered_summary = bugsummary FILTER html %]
+[% header = BLOCK %]View All Attachments for
+ [%+ "$terms.Bug $bug.id" FILTER bug_link(bug) FILTER none %][% END %]
+
+[% title = BLOCK %]
+ View All Attachments for [% terms.Bug %] [%+ bug.bug_id FILTER html %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ header = header
+ subheader = filtered_summary
+ style_urls = ['skins/standard/attachment.css']
+%]
+[% IF hide_obsolete %]
+ <div id="hidden_obsolete_message">
+ Obsolete attachments are hidden. To view all attachments (including obsolete)
+ <a href="attachment.cgi?bugid=[% bug.id FILTER html %]&amp;action=viewall">click here</a>.
+ </div>
+[% END %]
+<br>
+
+[% FOREACH a = attachments %]
+
+ <div align="center">
+ <table class="attachment_info" cellspacing="0" cellpadding="4" border="1" width="75%">
+ <tr>
+ <td valign="top" bgcolor="#cccccc" colspan="6">
+ <big><b>Attachment #[% a.id %]</b></big>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ [% a.description FILTER html FILTER obsolete(a.isobsolete) %]
+ </td>
+
+ <td valign="top">
+ [% IF a.ispatch %]
+ <i>patch</i>
+ [% ELSE %]
+ [% a.contenttype FILTER html %]
+ [% END %]
+ </td>
+
+ <td valign="top">[% a.attached FILTER time %]</td>
+ <td valign="top">[% a.datasize FILTER unitconvert %]</td>
+
+ <td valign="top">
+ [% IF a.flags.size == 0 %]
+ <i>no flags</i>
+ [% ELSE %]
+ [% FOREACH flag = a.flags %]
+ [% flag.setter.nick FILTER html %]:
+ [%+ flag.type.name FILTER html %][% flag.status %]
+ [% IF flag.status == "?" && flag.requestee %]
+ ([% flag.requestee.nick FILTER html %])
+ [% END %]
+ [% ", " IF !loop.last %]
+ [% END %]
+ [% END %]
+ </td>
+
+ <td valign="top">
+ <a href="attachment.cgi?id=[% a.id %]&amp;action=edit">Details</a>
+ </td>
+ </tr>
+ </table>
+
+ [% IF a.is_viewable %]
+ [% IF a.contenttype == "text/html" %]
+ [%# For security reasons (clickjacking, embedded scripts), we never
+ # render HTML pages from here. The source code is displayed instead. %]
+ [% INCLUDE global/textarea.html.tmpl
+ minrows = 10
+ cols = 80
+ defaultcontent = a.data
+ readonly = 'readonly'
+ classes = 'viewall_frame'
+ %]
+ [% ELSE %]
+ <iframe src="attachment.cgi?id=[% a.id %]" class="viewall_frame">
+ <b>You cannot view the attachment on this page because your browser does not support IFRAMEs.
+ <a href="attachment.cgi?id=[% a.id %]">View the attachment on a separate page</a>.</b>
+ </iframe>
+ [% END %]
+ [% ELSE %]
+ <p><b>
+ Attachment cannot be viewed because its MIME type is not text/*, image/*, or application/vnd.mozilla.*.
+ <a href="attachment.cgi?id=[% a.id %]">Download the attachment instead</a>.
+ </b></p>
+ [% END %]
+ </div>
+
+ <br><br>
+
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/attachment/updated.html.tmpl b/template/en/default/attachment/updated.html.tmpl
new file mode 100644
index 0000000..af1cbcd
--- /dev/null
+++ b/template/en/default/attachment/updated.html.tmpl
@@ -0,0 +1,32 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # attachment: object of the attachment we just attached.
+ #%]
+
+[% bug = bugs.0 %]
+
+[% PROCESS "bug/show-header.html.tmpl" %]
+[% PROCESS global/header.html.tmpl
+ title = "Changes Submitted to Attachment $attachment.id of $terms.Bug $attachment.bug_id"
+%]
+
+<dl>
+ <dt>Changes to
+ <a href="attachment.cgi?id=[% attachment.id %]&amp;action=edit">attachment [% attachment.id %]</a>
+ of [% "$terms.bug $attachment.bug_id" FILTER bug_link(attachment.bug_id) FILTER none %] submitted
+ </dt>
+ <dd>
+ [% PROCESS "bug/process/bugmail.html.tmpl" mailing_bugid = attachment.bug_id %]
+ [%# Links to more information about the changed bug. %]
+ [% Hook.process("links") %]
+ </dd>
+</dl>
+
+[% PROCESS bug/show.html.tmpl %]
diff --git a/template/en/default/bug/activity/show.html.tmpl b/template/en/default/bug/activity/show.html.tmpl
new file mode 100644
index 0000000..a442abd
--- /dev/null
+++ b/template/en/default/bug/activity/show.html.tmpl
@@ -0,0 +1,35 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # bug: object. The bug whose activity is being displayed.
+ # operations: array of hashes, see activity/table.html.tmpl.
+ #
+ # This template also needs to be called with the interface to the
+ # activity/table.html.tmpl template fulfilled.
+ #%]
+
+[% filtered_desc = bug.short_desc FILTER html %]
+[% PROCESS global/header.html.tmpl
+ title = "Changes made to $terms.bug $bug.bug_id"
+ header = "Activity log for $terms.bug $bug.bug_id: $filtered_desc"
+ %]
+
+<p>
+ [% "Back to $terms.bug $bug.bug_id" FILTER bug_link(bug) FILTER none %]
+</p>
+
+[% PROCESS bug/activity/table.html.tmpl %]
+
+[% IF operations.size > 0 %]
+ <p>
+ [% "Back to $terms.bug $bug.bug_id" FILTER bug_link(bug) FILTER none %]
+ </p>
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/bug/activity/table.html.tmpl b/template/en/default/bug/activity/table.html.tmpl
new file mode 100644
index 0000000..253d161
--- /dev/null
+++ b/template/en/default/bug/activity/table.html.tmpl
@@ -0,0 +1,103 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # operations: array of hashes. May be empty. Each has has three members:
+ # who: string. who performed the operation
+ # when: string. when they performed it
+ # changes: hash. Details of what they changed. This hash has three
+ # compulsory and one optional member:
+ # field: string. The name of the field
+ # removed: string. What was removed from the field
+ # added: string. What was added to the field
+ # attach_id: integer. If the change was adding an attachment, its id.
+ # incomplete_data: boolean. True if some of the data is incomplete (because
+ # it was affected by an old Bugzilla bug.)
+ #%]
+
+[% PROCESS bug/time.html.tmpl %]
+
+[% IF incomplete_data %]
+ <p>
+ There used to be an issue in <a href="http://www.bugzilla.org/">Bugzilla</a>
+ which caused activity data to be lost if there were a large number of cc's
+ or dependencies. That has been fixed, but some data was already lost in
+ your activity table that could not be regenerated. The changes that the
+ script could not reliably determine are prefixed by '?'.
+ </p>
+[% END %]
+
+[% IF operations.size > 0 %]
+ <table border cellpadding="4">
+ <tr>
+ <th>Who</th>
+ <th>When</th>
+ <th>What</th>
+ <th>Removed</th>
+ <th>Added</th>
+ </tr>
+
+ [% FOREACH operation = operations %]
+ <tr>
+ <td rowspan="[% operation.changes.size %]" valign="top">
+ [% operation.who FILTER email FILTER html %]
+ </td>
+ <td rowspan="[% operation.changes.size %]" valign="top">
+ [% operation.when FILTER time %]
+ </td>
+ [% FOREACH change = operation.changes %]
+ [% "</tr><tr>" IF loop.index > 0 %]
+ <td>
+ [% IF change.attachid %]
+ <a href="attachment.cgi?id=[% change.attachid %]">
+ Attachment #[% change.attachid %]</a>
+ [% END %]
+ [% IF change.comment.defined %]
+ [% comment_desc = field_descs.${change.fieldname} %]
+ [% comment_num = "Comment $change.comment.count" FILTER bug_link(bug.bug_id, comment_num => change.comment.count) %]
+ [% comment_desc.replace('^(Comment )?', "$comment_num ") FILTER none %]
+ [% ELSE %]
+ [%+ field_descs.${change.fieldname} FILTER html %]
+ [% END %]
+ </td>
+ [% PROCESS change_column change_type = change.removed %]
+ [% PROCESS change_column change_type = change.added %]
+ [% END %]
+ </tr>
+ [% END %]
+ </table>
+[% ELSE %]
+ <p>
+ No changes have been made to this [% terms.bug %] yet.
+ </p>
+[% END %]
+
+[% BLOCK change_column %]
+ <td>
+ [% IF change_type.defined %]
+ [% IF change.fieldname == 'estimated_time' ||
+ change.fieldname == 'remaining_time' ||
+ change.fieldname == 'work_time' %]
+ [% PROCESS formattimeunit time_unit=change_type %]
+ [% ELSIF change.fieldname == 'blocked' ||
+ change.fieldname == 'dependson' %]
+ [% change_type FILTER bug_list_link FILTER none %]
+ [% ELSIF change.fieldname == 'assigned_to' ||
+ change.fieldname == 'reporter' ||
+ change.fieldname == 'qa_contact' ||
+ change.fieldname == 'cc' ||
+ change.fieldname == 'flagtypes.name' %]
+ [% display_value(change.fieldname, change_type) FILTER email FILTER html %]
+ [% ELSE %]
+ [% display_value(change.fieldname, change_type) FILTER html %]
+ [% END %]
+ [% ELSE %]
+ &nbsp;
+ [% END %]
+ </td>
+[% END %]
diff --git a/template/en/default/bug/choose.html.tmpl b/template/en/default/bug/choose.html.tmpl
new file mode 100644
index 0000000..e2289c4
--- /dev/null
+++ b/template/en/default/bug/choose.html.tmpl
@@ -0,0 +1,21 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Search by $terms.bug number"
+ %]
+
+<form method="get" action="show_bug.cgi">
+ <p>
+ You may find a single [% terms.bug %] by entering its [% terms.bug %] id here:
+ <input name="id" size="6">
+ <input type="submit" id="show" value="Show Me This [% terms.Bug %]">
+ </p>
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/bug/comments.html.tmpl b/template/en/default/bug/comments.html.tmpl
new file mode 100644
index 0000000..61d1c67
--- /dev/null
+++ b/template/en/default/bug/comments.html.tmpl
@@ -0,0 +1,196 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS bug/time.html.tmpl %]
+
+<script src="[% 'js/comments.js' FILTER mtime %]" type="text/javascript">
+</script>
+
+<script type="text/javascript">
+<!--
+ /* Adds the reply text to the `comment' textarea */
+ function replyToComment(id, real_id, name) {
+ var prefix = "(In reply to " + name + " from comment #" + id + ")\n";
+ var replytext = "";
+ [% IF user.settings.quote_replies.value == 'quoted_reply' %]
+ /* pre id="comment_name_N" */
+ var text_elem = document.getElementById('comment_text_'+id);
+ var text = getText(text_elem);
+ replytext = prefix + wrapReplyText(text);
+ [% ELSIF user.settings.quote_replies.value == 'simple_reply' %]
+ replytext = prefix;
+ [% END %]
+
+ [% IF user.is_insider %]
+ if (document.getElementById('isprivate_' + real_id).checked) {
+ document.getElementById('newcommentprivacy').checked = 'checked';
+ updateCommentTagControl(document.getElementById('newcommentprivacy'), 'comment');
+ }
+ [% END %]
+
+ /* <textarea id="comment"> */
+ var textarea = document.getElementById('comment');
+ if (textarea.value != replytext) {
+ textarea.value += replytext;
+ }
+
+ textarea.focus();
+ }
+//-->
+</script>
+
+[% DEFAULT start_at = 0 mode = "show" %]
+[% sort_order = user.settings.comment_sort_order.value %]
+[% user_cache = template_cache.users %]
+
+[%# NOTE: (start_at > 0) means we came here from a midair collision,
+ # in which case we don't care what the user's preference is.
+ %]
+[% IF (start_at > 0) %]
+ [% sort_order = "oldest_to_newest" %]
+[% END %]
+
+<!-- This auto-sizes the comments and positions the collapse/expand links
+ to the right. -->
+<table class="bz_comment_table" cellpadding="0" cellspacing="0"><tr>
+<td>
+
+[% FOREACH comment = comments %]
+ [% IF comment.count >= start_at %]
+ [% PROCESS a_comment %]
+ [% END %]
+[% END %]
+
+[% IF mode == "edit" && user.id
+ && user.settings.comment_box_position.value == "before_comments" %]
+ <div class="bz_add_comment">
+ <a href="#"
+ onclick="return goto_add_comments();">
+ Add Comment</a>
+ </div>
+[% END %]
+
+[%# Note: this template is used in multiple places; if you use this hook,
+ # make sure you are aware of this fact.
+ #%]
+[% Hook.process("aftercomments") %]
+
+</td>
+<td>
+ [% IF mode == "edit" %]
+ <ul class="bz_collapse_expand_comments">
+ <li><a href="#" onclick="toggle_all_comments('collapse');
+ return false;">Collapse All Comments</a></li>
+ <li><a href="#" onclick="toggle_all_comments('expand');
+ return false;">Expand All Comments</a></li>
+ [% IF user.settings.comment_box_position.value == "after_comments" && user.id %]
+ <li class="bz_add_comment"><a href="#"
+ onclick="return goto_add_comments('bug_status_bottom');">
+ Add Comment</a></li>
+ [% END %]
+ </ul>
+ [% END %]
+</td>
+</tr></table>
+
+[%############################################################################%]
+[%# Block for individual comments #%]
+[%############################################################################%]
+
+[% BLOCK a_comment %]
+ [% RETURN IF comment.is_private AND NOT (user.is_insider || user.id == comment.author.id) %]
+ [% comment_text = comment.body_full %]
+ [% RETURN IF comment_text == '' AND (comment.work_time - 0) != 0 AND !user.is_timetracker %]
+
+ <div id="c[% comment.count %]" class="bz_comment[% " bz_private" IF comment.is_private %]
+ [% " bz_comment_hilite" IF marks.${comment.count} %]
+ [% " bz_first_comment" IF comment.count == 0 %]">
+ [% IF comment.count == 0 %]
+ [% class_name = "bz_first_comment_head" %]
+ [% comment_label = "Description" %]
+ [% ELSE %]
+ [% class_name = "bz_comment_head" %]
+ [% comment_label = "Comment " _ comment.count %]
+ [% END %]
+
+ <div class="[% class_name FILTER html %]">
+
+ [% IF mode == "edit" %]
+ <span class="bz_comment_actions">
+ [% IF bug.check_can_change_field('longdesc', 0, 1) %]
+ [<a class="bz_reply_link" href="#add_comment"
+ [% IF user.settings.quote_replies.value != 'off' %]
+ onclick="replyToComment('[% comment.count %]', '[% comment.id %]', '[% comment.author.name || comment.author.nick FILTER html FILTER js %]'); return false;"
+ [% END %]
+ >reply</a>]
+ [% END %]
+ <script type="text/javascript"><!--
+ addCollapseLink([% comment.count %], 'Toggle comment display'); // -->
+ </script>
+ </span>
+ [% END %]
+
+ [% IF mode == "edit" && user.is_insider && bug.check_can_change_field('longdesc', 0, 1) %]
+ <div class="bz_private_checkbox">
+ <input type="hidden" value="1"
+ name="defined_isprivate_[% comment.id %]">
+ <input type="checkbox"
+ name="isprivate_[% comment.id %]" value="1"
+ id="isprivate_[% comment.id %]"
+ onClick="updateCommentPrivacy(this, [% comment.count %])"
+ [% " checked=\"checked\"" IF comment.is_private %]>
+ <label for="isprivate_[% comment.id %]">Private</label>
+ </div>
+ [% END %]
+
+ <span class="bz_comment_number">
+ <a
+ href="show_bug.cgi?id=[% bug.bug_id %]#c[% comment.count %]">
+ [%- comment_label FILTER html %]</a>
+ </span>
+
+ <span class="bz_comment_user">
+ [%# No need to recreate the exact same template if we already have it. %]
+ [% commenter_id = comment.author.id %]
+ [% UNLESS user_cache.$commenter_id %]
+ [% user_cache.$commenter_id = BLOCK %]
+ [% INCLUDE global/user.html.tmpl who = comment.author %]
+ [% END %]
+ [% END %]
+ [% user_cache.$commenter_id FILTER none %]
+ </span>
+
+ <span class="bz_comment_user_images">
+ [% FOREACH group = comment.author.groups_with_icon %]
+ <img src="[% group.icon_url FILTER html %]"
+ alt="[% group.name FILTER html %]"
+ title="[% group.name FILTER html %] - [% group.description FILTER html %]">
+ [% END %]
+ </span>
+
+ <span class="bz_comment_time">
+ [%+ comment.creation_ts FILTER time %]
+ </span>
+ </div>
+
+ [% IF user.is_timetracker &&
+ (comment.work_time > 0 || comment.work_time < 0) %]
+ <br>
+ Additional hours worked:
+ [% PROCESS formattimeunit time_unit=comment.work_time %]
+ [% END %]
+
+[%# Don't indent the <pre> block, since then the spaces are displayed in the
+ # generated HTML
+ #%]
+<pre class="bz_comment_text"
+ [% ' id="comment_text_' _ comment.count _ '"' IF mode == "edit" %]>
+ [%- comment_text FILTER quoteUrls(bug, comment) -%]
+</pre>
+ </div>
+[% END %]
diff --git a/template/en/default/bug/create/comment-guided.txt.tmpl b/template/en/default/bug/create/comment-guided.txt.tmpl
new file mode 100644
index 0000000..e85a364
--- /dev/null
+++ b/template/en/default/bug/create/comment-guided.txt.tmpl
@@ -0,0 +1,34 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+User-Agent: [%+ cgi.user_agent() %]
+Build Identifier: [%+ cgi.param("buildid") %]
+
+[%+ cgi.param("comment") IF cgi.param("comment") %]
+
+[%+ IF cgi.param("reproducible") != "Choose one..." -%]
+Reproducible: [%+ cgi.param("reproducible") %]
+[% END %]
+
+[% IF !(cgi.param("reproduce_steps").match('^1\.\s*2\.\s*3\.\s*$') || cgi.param("reproduce_steps").match('^\s*$')) %]
+Steps to Reproduce:
+[%+ cgi.param("reproduce_steps") %]
+[% END %]
+
+[% IF cgi.param("actual_results") -%]
+Actual Results:
+[%+ cgi.param("actual_results") %]
+[% END %]
+
+[% IF cgi.param("expected_results") %]
+Expected Results:
+[%+ cgi.param("expected_results") %]
+[% END %]
+
+[%+ cgi.param("additional_info") %]
diff --git a/template/en/default/bug/create/comment.txt.tmpl b/template/en/default/bug/create/comment.txt.tmpl
new file mode 100644
index 0000000..4cd78dd
--- /dev/null
+++ b/template/en/default/bug/create/comment.txt.tmpl
@@ -0,0 +1,12 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[% USE Bugzilla %]
+[% Hook.process("form") %]
+
+
+[% Bugzilla.cgi.param("comment") %]
diff --git a/template/en/default/bug/create/create-guided.html.tmpl b/template/en/default/bug/create/create-guided.html.tmpl
new file mode 100644
index 0000000..e7de847
--- /dev/null
+++ b/template/en/default/bug/create/create-guided.html.tmpl
@@ -0,0 +1,511 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # This template has the same interface as create.html.tmpl
+ #%]
+
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+[% PROCESS global/header.html.tmpl
+ title = "Enter $terms.ABug"
+ onload = "PutDescription()"
+ style = "#somebugs { width: 100%; height: 500px }"
+ %]
+
+[% style = "" %]
+
+<p>
+ <font color="red">
+ This is a template used on mozilla.org. This template, and the
+ comment-guided.txt.tmpl template that formats the data submitted via
+ the form in this template, are included as a demo of what it's
+ possible to do with custom templates in general, and custom [% terms.bug %]
+ entry templates in particular. As much of the text will not apply,
+ you should alter it
+ if you want to use this form on your [% terms.Bugzilla %] installation.
+ </font>
+</p>
+
+[% tablecolour = "#FFFFCC" %]
+
+[%# This script displays the descriptions for selected components. %]
+<script type="text/javascript">
+var descriptions = [
+[% FOREACH c = product.components %]
+ [% NEXT IF NOT c.is_active %]
+ '[% c.description FILTER js %]',
+[% END %]
+];
+
+function PutDescription() {
+ if ((document.getElementById) && (document.body.innerHTML)) {
+ var componentIndex = document.getElementById('component').selectedIndex;
+ if (componentIndex != -1) {
+ var description = document.getElementById('description');
+ description.innerHTML = descriptions[componentIndex];
+ }
+ }
+}
+</script>
+
+<h3 id="step1">Step 1 of 3 - has your [% terms.bug %] already been reported?</h3>
+
+<p>
+ <font color="red">Please don't skip this step - half of all
+ [% terms.bugs %] filed are
+ reported already.</font>
+ Check the two lists of frequently-reported [% terms.bugs %]:
+</p>
+
+[%# Include other products if sensible %]
+[% IF product.name == "Firefox" %]
+ [% productstring = "product=Mozilla%20Application%20Suite&amp;product=Firefox" %]
+[% ELSIF product.name == "Thunderbird" %]
+ [% productstring = "product=Mozilla%20Application%20Suite&amp;product=Thunderbird" %]
+[% ELSE %]
+ [% productstring = BLOCK %]product=[% product.name FILTER uri %][% END %]
+[% END %]
+
+<p>
+ <a href="duplicates.cgi?[% productstring %]&amp;format=simple" target="somebugs">All-time Top 100</a> (loaded initially) |
+ <a href="duplicates.cgi?[% productstring %]&amp;format=simple&amp;sortby=delta&amp;reverse=1&amp;maxrows=100&amp;changedsince=14" target="somebugs">Hot in the last two weeks</a>
+</p>
+
+<iframe name="somebugs" id="somebugs"
+ style="border: 2px black solid"
+ src="duplicates.cgi?[% productstring %]&amp;format=simple">
+</iframe>
+
+<p>
+ If your [% terms.bug %] isn't there, search [% terms.Bugzilla %] by entering
+ a few key words having to do with your [% terms.bug %] in this box.
+ For example: <tt><b>pop3 mail</b></tt> or <tt><b>copy paste</b></tt>.
+ The results will appear above.
+ </p>
+
+[%# All bugs opened inside the past six months %]
+ <form action="buglist.cgi" method="get" target="somebugs">
+ <input type="hidden" name="format" value="simple">
+ <input type="hidden" name="order" value="relevance desc">
+ <input type="hidden" name="bug_status" value="__all__">
+ <input type="hidden" name="product" value="[% product.name FILTER html %]">
+ [% IF product.name == "Firefox" OR
+ product.name == "Thunderbird" OR
+ product.name == "Mozilla Application Suite" OR
+ product.name == "Camino" %]
+ <input type="hidden" name="product" value="Core">
+ <input type="hidden" name="product" value="Toolkit">
+ <input type="hidden" name="product" value="PSM">
+ <input type="hidden" name="product" value="NSPR">
+ <input type="hidden" name="product" value="NSS">
+ [% END %]
+ <input type="hidden" name="chfieldfrom" value="-6m">
+ <input type="hidden" name="chfieldto" value="Now">
+ <input type="hidden" name="chfield" value="[Bug creation]">
+ <input type="text" name="content" size="40">
+ <input type="submit" id="search" value="Search">
+ </form>
+
+<p>
+ Look through the search results. If you get the
+ <tt><b>[% terms.zeroSearchResults %]</b></tt> message, [% terms.Bugzilla %]
+ found no [% terms.bugs %] that
+ match. Check for typing mistakes, or try fewer or different keywords.
+ If you find [% terms.abug %] that looks the same as yours, please add
+ any useful extra information you have to it, rather than opening a new one.
+</p>
+
+
+<h3 id="step2">Step 2 of 3 - give information</h3>
+
+<p>
+ If you've tried a few searches and your [% terms.bug %] really isn't in
+ there, tell us all about it.
+</p>
+
+<form method="post" action="post_bug.cgi">
+ <input type="hidden" name="format" value="guided">
+ <input type="hidden" name="assigned_to" value="">
+ <input type="hidden" name="priority"
+ value="[% default.priority FILTER html %]">
+ <input type="hidden" name="version"
+ value="[% default.version FILTER html %]">
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+
+<table valign="top" cellpadding="5" cellspacing="5" border="0">
+
+ <tr bgcolor="[% tablecolour %]">
+ <td align="right" valign="top">
+ <b>Product</b>
+ </td>
+ <td valign="top">
+ <input type="hidden" name="product" value="[% product.name FILTER html %]">
+ [% product.name FILTER html %]
+ </td>
+ </tr>
+
+ <tr>
+ <td align="right" valign="top">
+ <b>Component</b>
+ </td>
+ <td valign="top">
+ <table border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td valign="top">
+ <select name="component" id="component"
+ size="5" onchange="PutDescription()">
+ [% IF NOT default.component_ %]
+ [%# Various b.m.o. products have a "General" component,
+ which is a useful default. %]
+ [% default.component_ = "General" %]
+ [% END %]
+ [% FOREACH c = product.components %]
+ [% NEXT IF NOT c.is_active %]
+ <option value="[% c.name FILTER html %]"
+ [% " selected=\"selected\"" IF c.name == default.component_ %]>
+ [% c.name FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ </td>
+ <td valign="top" width="100%">
+ <div id="description" style="color: green; margin-left: 10px;
+ height: 5em; overflow: auto;">
+ <script type="text/javascript">
+ if ((document.getElementById) && (document.body.innerHTML)) {
+ document.write("\
+ Select a component to see its description here.");
+ }
+ </script>
+ </div>
+ </td>
+ </tr>
+ </table>
+
+ <p>
+ The area where the problem occurs.
+ To pick the right component, you could use the same one as
+ similar [% terms.bugs %] you found in your search, or read the full list of
+ <a target="_blank" href="describecomponents.cgi?product=
+ [% product.name FILTER uri %]">component
+ descriptions</a> (opens in new window) if you need more help.
+ </p>
+ </td>
+ </tr>
+
+ [%# We override rep_platform and op_sys for simplicity. The values chosen
+ are based on which are most common in the b.m.o database %]
+ [% rep_platform = [ "PC", "Macintosh", "All", "Other" ] %]
+
+ <tr bgcolor="[% tablecolour %]">
+ <td align="right" valign="top">
+ <b>[% field_descs.rep_platform FILTER html %]</b>
+ </td>
+ <td valign="top">
+ [% PROCESS select sel = 'rep_platform' %]
+ </td>
+ </tr>
+
+ [% op_sys = [ "Windows 2000", "Windows XP", "Windows Vista", "Windows 7",
+ "Mac OS X", "Linux", "All", "Other" ] %]
+
+ <tr>
+ <td align="right" valign="top">
+ <b>Operating System</b>
+ </td>
+ <td valign="top">
+ [% PROCESS select sel = 'op_sys' %]
+ </td>
+ </tr>
+
+ [% IF product.name.match("Firefox|Camino|Mozilla Application Suite") %]
+ [% matches = cgi.user_agent('Gecko/(\d+)') %]
+ [% buildid = cgi.user_agent() IF matches %]
+ [% END %]
+
+ [%# Accept URL parameter build ID for non-browser products %]
+ [% IF cgi.param("buildid") %]
+ [% buildid = cgi.param("buildid") %]
+ [% END %]
+
+ <tr bgcolor="[% tablecolour %]">
+ <td align="right" valign="top">
+ <b>Build Identifier</b>
+ </td>
+ <td valign="top">
+ <input type="text" size="80" name="buildid" value="[% buildid FILTER html %]">
+ <p>
+ This should identify the exact version of the product you were using.
+ If the above field is blank or you know it is incorrect, copy the
+ version text from the product's Help |
+ About menu (for browsers this will begin with "Mozilla/5.0...").
+ If the product won't start, instead paste the complete URL you downloaded
+ it from.
+ </p>
+ </td>
+ </tr>
+
+ <tr>
+ <td align="right" valign="top">
+ <b>URL</b>
+ </td>
+ <td valign="top">
+ <input type="text" size="80" name="bug_file_loc" value="http://">
+ <p>
+ URL that demonstrates the problem you are seeing (optional).<br>
+ <b>IMPORTANT</b>: if the problem is with a broken web page, you need
+ to report it
+ <a href="https://bugzilla.mozilla.org/page.cgi?id=broken-website.html">a different way</a>.
+ </p>
+ </td>
+ </tr>
+
+ <tr bgcolor="[% tablecolour %]">
+ <td align="right" valign="top">
+ <b>Summary</b>
+ </td>
+ <td valign="top">
+ <input type="text" size="80" name="short_desc" id="short_desc"
+ maxlength="255" spellcheck="true">
+ <p>
+ A sentence which summarises the problem.
+ Please be descriptive and use lots of keywords.
+ </p>
+ <p>
+ <tt>
+ <font color="#990000">Bad example</font>: mail crashed
+ </tt>
+ <br>
+ <tt>
+ <font color="#009900">Good example</font>:
+ crash if I close the mail window while checking for new POP mail
+ </tt>
+ </p>
+ </td>
+ </tr>
+
+ <tr>
+ <td align="right" valign="top">
+ <b>Details</b>
+ </td>
+ <td valign="top">
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'comment'
+ minrows = 6
+ cols = constants.COMMENT_COLS
+ %]
+ <p>
+ Expand on the Summary. Please be
+ as specific as possible about what is wrong.
+ </p>
+ <p>
+ <tt>
+ <font color="#990000">Bad example</font>: Mozilla crashed.
+ You suck!
+ </tt>
+ <br>
+ <tt>
+ <font color="#009900">Good example</font>: After a crash which
+ happened when I was sorting in the Bookmark Manager,<br> all of my
+ top-level bookmark folders beginning with the letters Q to Z are
+ no longer present.
+ </tt>
+ </p>
+ </td>
+ </tr>
+
+ <tr bgcolor="[% tablecolour %]">
+ <td align="right" valign="top">
+ <b>Reproducibility</b>
+ </td>
+ <td valign="top">
+ <select name="reproducible">
+ <option name="AlwaysReproducible" value="Always">
+ Happens every time.
+ </option>
+ <option name="Sometimes" value="Sometimes">
+ Happens sometimes, but not always.
+ </option>
+ <option name="DidntTry" value="Didn't try">
+ Haven't tried to reproduce it.
+ </option>
+ <option name="NotReproducible" value="Couldn't Reproduce">
+ Tried, but couldn't reproduce it.
+ </option>
+ </select>
+ </td>
+ </tr>
+
+ <tr>
+ <td align="right" valign="top">
+ <b>Steps to Reproduce</b>
+ </td>
+ <td valign="top">
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'reproduce_steps'
+ minrows = 4
+ cols = constants.COMMENT_COLS
+ defaultcontent = "1.\n2.\n3."
+ %]
+ <p>
+ Describe how to reproduce the problem, step by
+ step. Include any special setup steps.
+ </p>
+ </td>
+ </tr>
+
+ <tr bgcolor="[% tablecolour %]">
+ <td valign="top" align="right">
+ <b>Actual Results</b>
+ </td>
+ <td valign="top">
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'actual_results'
+ minrows = 4
+ cols = constants.COMMENT_COLS
+ %]
+ <p>
+ What happened after you performed the steps above?
+ </p>
+ </td>
+ </tr>
+
+ <tr>
+ <td valign="top" align="right">
+ <b>Expected Results</b>
+ </td>
+ <td valign="top">
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'expected_results'
+ minrows = 4
+ cols = constants.COMMENT_COLS
+ %]
+ <p>
+ What should the software have done instead?
+ </p>
+ </td>
+ </tr>
+
+ <tr bgcolor="[% tablecolour %]">
+ <td valign="top" align="right">
+ <b>Additional Information</b>
+ </td>
+ <td valign="top">
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'additional_info'
+ minrows = 8
+ cols = constants.COMMENT_COLS
+ %]
+ <p>
+ Add any additional information you feel may be
+ relevant to this [% terms.bug %], such as the <b>theme</b> you were
+ using (does the [% terms.bug %] still occur
+ with the default theme?), a
+ <b><a href="http://kb.mozillazine.org/Quality_Feedback_Agent">Talkback crash ID</a></b>, or special
+ information about <b>your computer's configuration</b>. Any information
+ longer than a few lines, such as a <b>stack trace</b> or <b>HTML
+ testcase</b>, should be added
+ using the "Add an Attachment" link on the [% terms.bug %], after
+ it is filed. If you believe that it's relevant, please also include
+ your build configuration, obtained by typing <tt>about:buildconfig</tt>
+ into your URL bar.
+ <br>
+ <br>
+ If you are reporting a crash, note the module in
+ which the software crashed (e.g., <tt>Application Violation in
+ gkhtml.dll</tt>).
+ </p>
+ </td>
+ </tr>
+
+ <tr>
+ <td valign="top" align="right">
+ <b>[% field_descs.bug_severity FILTER html %]</b>
+ </td>
+ <td valign="top">
+ <select name="bug_severity">
+ <option name="critical" value="critical">
+ Critical: The software crashes, hangs, or causes you to
+ lose data.
+ </option>
+ <option name="major" value="major">
+ Major: A major feature is broken.
+ </option>
+ <option name="normal" value="normal" selected="selected">
+ Normal: It's [% terms.abug %] that should be fixed.
+ </option>
+ <option name="minor" value="minor">
+ Minor: Minor loss of function, and there's an easy workaround.
+ </option>
+ <option name="trivial" value="trivial">
+ Trivial: A cosmetic problem, such as a misspelled word or
+ misaligned text.
+ </option>
+ <option name="enhancement" value="enhancement">
+ Enhancement: Request for new feature or enhancement.
+ </option>
+ </select>
+ <p>
+ Say how serious the problem is, or if your [% terms.bug %] is a
+ request for a new feature.
+ </p>
+ </td>
+ </tr>
+
+ [% Hook.process('form') %]
+</table>
+
+
+<h3 id="step3">Step 3 of 3 - submit the [% terms.bug %] report</h3>
+
+<p>
+ <input type="submit" id="report" value=" Submit [% terms.Bug %] Report "
+ onclick="if (this.form.comment.value == '')
+ { alert('Please enter some details about this [% terms.bug %].');
+ this.form.comment.focus();
+ return false; } return true;">
+</p>
+
+<p>
+ That's it! Thanks very much. You'll be notified by email about any
+ progress that is made on fixing your [% terms.bug %].
+
+<p>
+ Please be warned
+ that we get a lot of [% terms.bug %] reports filed - it may take quite a
+ while to get around to yours. You can help the process by making sure your
+ [%+ terms.bug %] is
+ complete and easy to understand, and by quickly replying to any questions
+ which may arrive by email.
+</p>
+
+ </form>
+
+[% PROCESS global/footer.html.tmpl %]
+
+[%############################################################################%]
+[%# Block for SELECT fields #%]
+[%############################################################################%]
+
+[% BLOCK select %]
+ <select name="[% sel %]">
+ [%- IF default.$sel %]
+ <option value="[% default.$sel FILTER html %]" selected="selected">
+ [% default.$sel FILTER html -%]
+ </option>
+ [% END %]
+ [%- FOREACH x = $sel %]
+ [% NEXT IF x == default.$sel %]
+ <option value="[% x FILTER html %]">
+ [% x FILTER html -%]
+ </option>
+ [%- END %]
+ </select>
+[% END %]
diff --git a/template/en/default/bug/create/create.html.tmpl b/template/en/default/bug/create/create.html.tmpl
new file mode 100644
index 0000000..c3e18ad
--- /dev/null
+++ b/template/en/default/bug/create/create.html.tmpl
@@ -0,0 +1,727 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% title = BLOCK %]Enter [% terms.Bug %]: [% product.name FILTER html %][% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ yui = [ 'autocomplete', 'calendar', 'datatable', 'button' ]
+ style_urls = [ 'skins/standard/attachment.css',
+ 'skins/standard/enter_bug.css' ]
+ javascript_urls = [ "js/attachment.js", "js/util.js",
+ "js/field.js", "js/TUI.js", "js/bug.js" ]
+ onload = "set_assign_to(); hideElementById('attachment_true');
+ showElementById('attachment_false'); showElementById('btn_no_attachment');"
+%]
+
+<script type="text/javascript">
+<!--
+
+var initialowners = new Array([% product.components.size %]);
+var last_initialowner;
+var initialccs = new Array([% product.components.size %]);
+var components = new Array([% product.components.size %]);
+var comp_desc = new Array([% product.components.size %]);
+var flags = new Array([% product.components.size %]);
+[% IF Param("useqacontact") %]
+ var initialqacontacts = new Array([% product.components.size %]);
+ var last_initialqacontact;
+[% END %]
+[% count = 0 %]
+[%- FOREACH c = product.components %]
+ [% NEXT IF NOT c.is_active %]
+ components[[% count %]] = "[% c.name FILTER js %]";
+ comp_desc[[% count %]] = "[% c.description FILTER html_light FILTER js %]";
+ initialowners[[% count %]] = "[% c.default_assignee.login FILTER js %]";
+ [% flag_list = [] %]
+ [% FOREACH f = c.flag_types.bug %]
+ [% NEXT UNLESS f.is_active %]
+ [% flag_list.push(f.id) %]
+ [% END %]
+ [% FOREACH f = c.flag_types.attachment %]
+ [% NEXT UNLESS f.is_active %]
+ [% flag_list.push(f.id) %]
+ [% END %]
+ flags[[% count %]] = [[% flag_list.join(",") FILTER js %]];
+ [% IF Param("useqacontact") %]
+ initialqacontacts[[% count %]] = "[% c.default_qa_contact.login FILTER js %]";
+ [% END %]
+
+ [% SET initial_cc_list = [] %]
+ [% FOREACH cc_user = c.initial_cc %]
+ [% initial_cc_list.push(cc_user.login) %]
+ [% END %]
+ initialccs[[% count %]] = "[% initial_cc_list.join(', ') FILTER js %]";
+
+ [% count = count + 1 %]
+[%- END %]
+
+function set_assign_to() {
+ // Based on the selected component, fill the "Assign To:" field
+ // with the default component owner, and the "QA Contact:" field
+ // with the default QA Contact. It also selectively enables flags.
+ var form = document.Create;
+ var assigned_to = form.assigned_to.value;
+
+[% IF Param("useqacontact") %]
+ var qa_contact = form.qa_contact.value;
+[% END %]
+
+ var index = -1;
+ if (form.component.type == 'select-one') {
+ index = form.component.selectedIndex;
+ } else if (form.component.type == 'hidden') {
+ // Assume there is only one component in the list
+ index = 0;
+ }
+ if (index != -1) {
+ var owner = initialowners[index];
+ var component = components[index];
+ if (assigned_to == last_initialowner
+ || assigned_to == owner
+ || assigned_to == '') {
+ form.assigned_to.value = owner;
+ last_initialowner = owner;
+ }
+
+ document.getElementById('initial_cc').innerHTML = initialccs[index];
+ document.getElementById('comp_desc').innerHTML = comp_desc[index];
+
+ [% IF Param("useqacontact") %]
+ var contact = initialqacontacts[index];
+ if (qa_contact == last_initialqacontact
+ || qa_contact == contact
+ || qa_contact == '') {
+ form.qa_contact.value = contact;
+ last_initialqacontact = contact;
+ }
+ [% END %]
+
+ // We show or hide the available flags depending on the selected component.
+ var flag_rows = YAHOO.util.Dom.getElementsByClassName('bz_flag_type', 'tbody');
+ for (var i = 0; i < flag_rows.length; i++) {
+ // Each flag table row should have one flag form select element
+ // We get the flag type id from the id attribute of the select.
+ var flag_select = YAHOO.util.Dom.getElementsByClassName('flag_select',
+ 'select',
+ flag_rows[i])[0];
+ var type_id = flag_select.id.split('-')[1];
+ var can_set = flag_select.options.length > 1 ? 1 : 0;
+ var show = 0;
+ // Loop through the allowed flag ids for the selected component
+ // and if we match, then show the row, otherwise hide the row.
+ for (var j = 0; j < flags[index].length; j++) {
+ if (flags[index][j] == type_id) {
+ show = 1;
+ break;
+ }
+ }
+ if (show && can_set) {
+ flag_select.disabled = false;
+ YAHOO.util.Dom.removeClass(flag_rows[i], 'bz_default_hidden');
+ } else {
+ flag_select.disabled = true;
+ YAHOO.util.Dom.addClass(flag_rows[i], 'bz_default_hidden');
+ }
+ }
+ }
+}
+
+var status_comment_required = new Array();
+[% FOREACH status = bug_status %]
+ status_comment_required['[% status.name FILTER js %]'] =
+ [% status.comment_required_on_change_from() ? 'true' : 'false' %]
+[% END %]
+
+TUI_alternates['expert_fields'] = 'Show Advanced Fields';
+// Hide the Advanced Fields by default, unless the user has a cookie
+// that specifies otherwise.
+TUI_hide_default('expert_fields');
+// Also hide the "Paste text as attachment" textarea by default.
+TUI_hide_default('attachment_text_field');
+-->
+</script>
+
+<form name="Create" id="Create" method="post" action="post_bug.cgi"
+ class="enter_bug_form" enctype="multipart/form-data"
+ onsubmit="return validateEnterBug(this)">
+<input type="hidden" name="product" value="[% product.name FILTER html %]">
+<input type="hidden" name="token" value="[% token FILTER html %]">
+
+<table>
+<tbody>
+ <tr>
+ <td colspan="4">
+ [%# Migration note: The following file corresponds to the old Param
+ # 'entryheaderhtml'
+ #%]
+ [% PROCESS 'bug/create/user-message.html.tmpl' %]
+ </td>
+ </tr>
+
+ <tr>
+ <td colspan="2">
+ <a id="expert_fields_controller" class="controller bz_default_hidden"
+ href="javascript:TUI_toggle_class('expert_fields')">Hide
+ Advanced Fields</a>
+ [%# Show the link if the browser supports JS %]
+ <script type="text/javascript">
+ YAHOO.util.Dom.removeClass('expert_fields_controller',
+ 'bz_default_hidden');
+ </script>
+ </td>
+ <td colspan="2">
+ (<span class="required_star">*</span> =
+ <span class="required_explanation">Required Field</span>)
+ </td>
+ </tr>
+
+ <tr>
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.product, editable = 0,
+ value = product.name %]
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.reporter, editable = 0,
+ value = user.login %]
+ </tr>
+
+ [%# We can't use the select block in these two cases for various reasons. %]
+ <tr>
+ [% component_desc_url = BLOCK -%]
+ describecomponents.cgi?product=[% product.name FILTER uri %]
+ [% END %]
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.component editable = 1
+ desc_url = component_desc_url
+ %]
+ <td id="field_container_component">
+ <select name="component" id="component" onchange="set_assign_to();"
+ size="7" aria-required="true" class="required">
+ [%# Build the lists of assignees and QA contacts if "usemenuforusers" is enabled. %]
+ [% IF Param("usemenuforusers") %]
+ [% assignees_list = user.get_userlist.clone %]
+ [% qa_contacts_list = user.get_userlist.clone %]
+ [% END %]
+
+ [%- FOREACH c = product.components %]
+ [% NEXT IF NOT c.is_active %]
+ <option value="[% c.name FILTER html %]"
+ id="v[% c.id FILTER html %]_component"
+ [% IF c.name == default.component_ %]
+ [%# This is for bug/field.html.tmpl, for visibility-related
+ # controls. %]
+ [% default.component_id = c.id %]
+ selected="selected"
+ [% END %]>
+ [% c.name FILTER html -%]
+ </option>
+ [% IF Param("usemenuforusers") %]
+ [% INCLUDE build_userlist default_user = c.default_assignee,
+ userlist = assignees_list %]
+ [% INCLUDE build_userlist default_user = c.default_qa_contact,
+ userlist = qa_contacts_list %]
+ [% END %]
+ [%- END %]
+ </select>
+
+ <script type="text/javascript">
+ <!--
+ [%+ INCLUDE "bug/field-events.js.tmpl"
+ field = bug_fields.component, product = product %]
+ //-->
+ </script>
+ </td>
+
+ <td colspan="2" id="comp_desc_container">
+ [%# Enclose the fieldset in a nested table so that its width changes based
+ # on the length on the component description. %]
+ <table>
+ <tr>
+ <td>
+ <fieldset>
+ <legend>Component Description</legend>
+ <div id="comp_desc" class="comment">Select a component to read its description.</div>
+ </fieldset>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.version editable = 1 rowspan = 3
+ %]
+ <td rowspan="3">
+ <select name="version" id="version" size="5" aria-required="true"
+ class="required">
+ [%- FOREACH v = version %]
+ [% NEXT IF NOT v.is_active %]
+ <option value="[% v.name FILTER html %]"
+ [% ' selected="selected"' IF v.name == default.version %]>[% v.name FILTER html -%]
+ </option>
+ [%- END %]
+ </select>
+ </td>
+
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.bug_severity, editable = 1,
+ value = default.bug_severity %]
+ </tr>
+
+ <tr>
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.rep_platform, editable = 1,
+ value = default.rep_platform %]
+ </tr>
+
+ <tr>
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.op_sys, editable = 1,
+ value = default.op_sys %]
+ </tr>
+ [% IF (!Param('defaultplatform') || !Param('defaultopsys')) && !cloned_bug_id %]
+ <tr>
+ <th colspan="3">&nbsp;</th>
+ <td id="os_guess_note" class="comment">
+ <div>We've made a guess at your
+ [% IF Param('defaultplatform') %]
+ operating system. Please check it
+ [% ELSIF Param('defaultopsys') %]
+ platform. Please check it
+ [% ELSE %]
+ operating system and platform. Please check them
+ [% END %]
+ and make any corrections if necessary.</div>
+ </td>
+ </tr>
+ [% END %]
+</tbody>
+
+<tbody class="expert_fields">
+ <tr>
+ [% IF Param('usetargetmilestone') && Param('letsubmitterchoosemilestone') %]
+ [% INCLUDE select field = bug_fields.target_milestone %]
+ [% ELSE %]
+ <td colspan="2">&nbsp;</td>
+ [% END %]
+
+ [% IF Param('letsubmitterchoosepriority') %]
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.priority, editable = 1,
+ value = default.priority %]
+ [% ELSE %]
+ <td colspan="2">&nbsp;</td>
+ [% END %]
+ </tr>
+</tbody>
+
+<tbody class="expert_fields">
+ <tr>
+ <td colspan="4">&nbsp;</td>
+ </tr>
+
+ <tr>
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.bug_status,
+ editable = (bug_status.size > 1), value = default.bug_status
+ override_legal_values = bug_status %]
+
+ <td>&nbsp;</td>
+ [%# Calculate the number of rows we can use for flags %]
+ [% num_rows = 7 + (Param("useqacontact") ? 1 : 0) +
+ (user.is_timetracker ? 3 : 0)
+ %]
+
+ <td rowspan="[% num_rows FILTER html %]">
+ [% IF product.flag_types.bug.size > 0 %]
+ [% display_flag_headers = 0 %]
+ [% any_flags_requesteeble = 0 %]
+
+ [% FOREACH flag_type = product.flag_types.bug %]
+ [% NEXT UNLESS flag_type.is_active %]
+ [% display_flag_headers = 1 %]
+ [% SET any_flags_requesteeble = 1 IF flag_type.is_requestable && flag_type.is_requesteeble %]
+ [% END %]
+
+ [% IF display_flag_headers %]
+ [% PROCESS "flag/list.html.tmpl" flag_types = product.flag_types.bug
+ any_flags_requesteeble = any_flags_requesteeble
+ flag_table_id = "bug_flags"
+ %]
+ [% END %]
+ [% END %]
+ </td>
+ </tr>
+
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.assigned_to editable = 1
+ %]
+ <td colspan="2">
+ [% INCLUDE global/userselect.html.tmpl
+ id => "assigned_to"
+ name => "assigned_to"
+ value => assigned_to
+ disabled => assigned_to_disabled
+ size => 30
+ emptyok => 1
+ custom_userlist => assignees_list
+ %]
+ <noscript>(Leave blank to assign to component's default assignee)</noscript>
+ </td>
+ </tr>
+
+[% IF Param("useqacontact") %]
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.qa_contact editable = 1
+ %]
+ <td colspan="2">
+ [% INCLUDE global/userselect.html.tmpl
+ id => "qa_contact"
+ name => "qa_contact"
+ value => qa_contact
+ disabled => qa_contact_disabled
+ size => 30
+ emptyok => 1
+ custom_userlist => qa_contacts_list
+ %]
+ <noscript>(Leave blank to assign to default qa contact)</noscript>
+ </td>
+ </tr>
+[% END %]
+
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.cc editable = 1
+ %]
+ <td colspan="2">
+ [% INCLUDE global/userselect.html.tmpl
+ id => "cc"
+ name => "cc"
+ value => cc
+ disabled => cc_disabled
+ size => 30
+ multiple => 5
+ %]
+ </td>
+ </tr>
+
+ <tr>
+ <th>Default [% field_descs.cc FILTER html %]:</th>
+ <td colspan="2">
+ <div id="initial_cc">
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td colspan="3">&nbsp;</td>
+ </tr>
+
+[% IF user.is_timetracker %]
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.estimated_time editable = 1
+ %]
+ <td colspan="2">
+ <input name="estimated_time" size="6" maxlength="6" value="[% estimated_time FILTER html %]">
+ </td>
+ </tr>
+ <tr>
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.deadline, value = deadline,
+ editable = 1, value_span = 2 %]
+ </tr>
+
+ <tr>
+ <td colspan="3">&nbsp;</td>
+ </tr>
+[% END %]
+
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.alias editable = 1
+ %]
+ <td colspan="2">
+ <input name="alias" size="20" value="[% alias FILTER html %]">
+ </td>
+ </tr>
+
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.bug_file_loc editable = 1
+ %]
+ <td colspan="2" class="field_value">
+ <input name="bug_file_loc" id="bug_file_loc" class="text_input"
+ size="40" value="[% bug_file_loc FILTER html %]">
+ </td>
+ </tr>
+</tbody>
+
+<tbody>
+ [% USE Bugzilla %]
+
+ [% FOREACH field = Bugzilla.active_custom_fields %]
+ [% NEXT UNLESS field.enter_bug %]
+ [% SET value = ${field.name}.defined ? ${field.name} : "" %]
+ <tr [% 'class="expert_fields"' IF !field.is_mandatory %]>
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = field, value = value, editable = 1,
+ value_span = 3 %]
+ </tr>
+ [% END %]
+</tbody>
+
+<tbody>
+
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.short_desc editable = 1
+ %]
+ <td colspan="3" class="field_value">
+ <input name="short_desc" size="70" value="[% short_desc FILTER html %]"
+ maxlength="255" spellcheck="true" aria-required="true"
+ class="required text_input" id="short_desc">
+ </td>
+ </tr>
+
+ [% IF feature_enabled('jsonrpc') AND !cloned_bug_id %]
+ <tr id="possible_duplicates_container" class="bz_default_hidden">
+ <th>Possible<br>Duplicates:</th>
+ <td colspan="3">
+ <div id="possible_duplicates"></div>
+ <script type="text/javascript">
+ var dt_columns = [
+ { key: "id", label: "[% field_descs.bug_id FILTER js %]",
+ formatter: YAHOO.bugzilla.dupTable.formatBugLink },
+ { key: "summary",
+ label: "[% field_descs.short_desc FILTER js %]",
+ formatter: "text" },
+ { key: "status",
+ label: "[% field_descs.bug_status FILTER js %]",
+ formatter: YAHOO.bugzilla.dupTable.formatStatus },
+ { key: "update_token", label: '',
+ formatter: YAHOO.bugzilla.dupTable.formatCcButton }
+ ];
+ YAHOO.bugzilla.dupTable.addCcMessage = "Add Me to the CC List";
+ YAHOO.bugzilla.dupTable.init({
+ container: 'possible_duplicates',
+ columns: dt_columns,
+ product_name: '[% product.name FILTER js %]',
+ summary_field: 'short_desc',
+ options: {
+ MSG_LOADING: 'Searching for possible duplicates...',
+ MSG_EMPTY: 'No possible duplicates found.',
+ SUMMARY: 'Possible Duplicates'
+ }
+ });
+ </script>
+ </td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <th>Description:</th>
+ <td colspan="3">
+
+ [% defaultcontent = BLOCK %]
+ [% IF cloned_bug_id %]
++++ This [% terms.bug %] was initially created as a clone of [% terms.Bug %] #[% cloned_bug_id %] +++
+
+
+ [% END %]
+ [%-# We are within a BLOCK. The comment will be correctly HTML-escaped
+ # by global/textarea.html.tmpl. So we must not escape the comment here. %]
+ [% comment FILTER none %]
+ [%- END %]
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'comment'
+ id = 'comment'
+ minrows = 10
+ maxrows = 25
+ cols = constants.COMMENT_COLS
+ defaultcontent = defaultcontent
+ %]
+ <br>
+ </td>
+ </tr>
+
+ [% IF user.is_insider %]
+ <tr class="expert_fields">
+ <th>&nbsp;</th>
+ <td colspan="3">
+ &nbsp;&nbsp;
+ <input type="checkbox" id="comment_is_private" name="comment_is_private"
+ [% ' checked="checked"' IF comment_is_private %]
+ onClick="updateCommentTagControl(this, 'comment')">
+ <label for="comment_is_private">
+ Make description and any new attachment private (visible only to members
+ of the <strong>[% Param('insidergroup') FILTER html %]</strong> group)
+ </label>
+ <script>
+ updateCommentTagControl(document.getElementById('comment_is_private'), 'comment');
+ </script>
+ </td>
+ </tr>
+ [% END %]
+
+ [% IF Param("maxattachmentsize") || Param("maxlocalattachment") %]
+ <tr>
+ <th>Attachment:</th>
+ <td colspan="3">
+ <div id="attachment_false" class="bz_default_hidden">
+ <input type="button" value="Add an attachment" onClick="handleWantsAttachment(true)">
+ </div>
+
+ <div id="attachment_true">
+ <input type="button" id="btn_no_attachment" value="Don't add an attachment"
+ class="bz_default_hidden" onClick="handleWantsAttachment(false)">
+ <fieldset>
+ <legend>Add an attachment</legend>
+ <table class="attachment_entry">
+ [% PROCESS attachment/createformcontents.html.tmpl
+ flag_types = product.flag_types.attachment
+ any_flags_requesteeble = 1
+ flag_table_id ="attachment_flags" %]
+ </table>
+ </fieldset>
+ </div>
+ </td>
+ </tr>
+ [% END %]
+</tbody>
+
+<tbody class="expert_fields">
+ [% IF user.in_group('editbugs', product.id) %]
+ [% IF use_keywords %]
+ <tr>
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.keywords, editable = 1,
+ value = keywords, possible_values = all_keywords,
+ desc_url = "describekeywords.cgi", value_span = 2
+ %]
+ </tr>
+ [% END %]
+
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.dependson editable = 1
+ %]
+ <td colspan="3">
+ <input name="dependson" accesskey="d" value="[% dependson FILTER html %]">
+ </td>
+ </tr>
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.blocked editable = 1
+ %]
+ <td colspan="3">
+ <input name="blocked" accesskey="b" value="[% blocked FILTER html %]">
+ </td>
+ </tr>
+ [% END %]
+</tbody>
+
+<tbody class="expert_fields">
+ [% IF product.groups_available.size %]
+ <tr>
+ <th>&nbsp;</th>
+ <td colspan="3">
+ <br>
+ <strong>
+ Only users in all of the selected groups can view this
+ [%+ terms.bug %]:
+ </strong>
+ <br>
+ <font size="-1">
+ (Leave all boxes unchecked to make this a public [% terms.bug %].)
+ </font>
+ <br>
+ <br>
+
+ <!-- Checkboxes -->
+ <input type="hidden" name="defined_groups" value="1">
+ [% FOREACH group = product.groups_available %]
+ <input type="checkbox" id="group_[% group.id FILTER html %]"
+ name="groups" value="[% group.name FILTER html %]"
+ [% ' checked="checked"' IF default.groups.contains(group.name)
+ OR group.is_default %]>
+ <label for="group_[% group.id FILTER html %]">
+ [%- group.description FILTER html_light %]</label><br>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+</tbody>
+
+<tbody>
+ [%# Form controls for entering additional data about the bug being created. %]
+ [% Hook.process("form") %]
+
+ <tr>
+ <th>&nbsp;</th>
+ <td colspan="3">
+ <input type="submit" id="commit" value="Submit [% terms.Bug %]">
+ &nbsp;&nbsp;&nbsp;&nbsp;
+ <input type="submit" name="maketemplate" id="maketemplate"
+ value="Remember values as bookmarkable template"
+ onclick="bz_no_validate_enter_bug=true" class="expert_fields">
+ </td>
+ </tr>
+</tbody>
+ </table>
+ <input type="hidden" name="form_name" value="enter_bug">
+</form>
+
+[%# Links or content with more information about the bug being created. %]
+[% Hook.process("end") %]
+
+[% PROCESS global/footer.html.tmpl %]
+
+[%############################################################################%]
+[%# Block for SELECT fields #%]
+[%############################################################################%]
+
+[% BLOCK select %]
+
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = field editable = 1
+ %]
+ <td>
+ <select name="[% field.name FILTER html %]"
+ id="[% field.name FILTER html %]">
+ [%- FOREACH x = ${field.name} %]
+ [% NEXT IF NOT x.is_active %]
+ <option value="[% x.name FILTER html %]"
+ [% " selected=\"selected\"" IF x.name == default.${field.name} %]>
+ [% display_value(field.name, x.name) FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ </td>
+[% END %]
+
+[% BLOCK build_userlist %]
+ [% user_found = 0 %]
+ [% default_login = default_user.login %]
+ [% RETURN UNLESS default_login %]
+
+ [% FOREACH user = userlist %]
+ [% IF user.login == default_login %]
+ [% user_found = 1 %]
+ [% LAST %]
+ [% END %]
+ [% END %]
+
+ [% userlist.push({login => default_login,
+ identity => default_user.identity,
+ visible => 1})
+ UNLESS user_found %]
+[% END %]
diff --git a/template/en/default/bug/create/created.html.tmpl b/template/en/default/bug/create/created.html.tmpl
new file mode 100644
index 0000000..ea227b3
--- /dev/null
+++ b/template/en/default/bug/create/created.html.tmpl
@@ -0,0 +1,47 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # id: number; the ID of the bug that was created.
+ # sentmail: array of hash; bugs for which BugMail should be sent, contains:
+ # type: string; type of change for this bug, either 'created' if this bug
+ # was created or 'dep' if it was added as a dependent/blocker
+ # id: integer; the ID of the bug
+ # bug: object; Bugzilla::Bug object of the bug that was created (used in
+ # template bug/edit.html.tmpl
+ #%]
+
+[% PROCESS "bug/show-header.html.tmpl" %]
+[% PROCESS global/header.html.tmpl
+ title = "$terms.Bug $id Submitted &ndash; $filtered_desc"
+ header = "$terms.Bug&nbsp;$id Submitted"
+%]
+
+[% header_done = 1 %]
+
+[% FOREACH item = sentmail %]
+ [% PROCESS bug/process/results.html.tmpl
+ type = item.type
+ id = item.id
+ sent_bugmail = item
+ %]
+[% END %]
+
+<br>
+
+<hr>
+
+[% PROCESS bug/edit.html.tmpl %]
+
+<hr>
+
+[% PROCESS bug/navigate.html.tmpl bottom_navigator => 1 %]
+
+<br>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/bug/create/make-template.html.tmpl b/template/en/default/bug/create/make-template.html.tmpl
new file mode 100644
index 0000000..4b1b0c0
--- /dev/null
+++ b/template/en/default/bug/create/make-template.html.tmpl
@@ -0,0 +1,31 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # url: URL to a pre-filled bug entry form.
+ # short_desc: Bug summary as entered in the form.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Bookmarks are your friend"
+ header = "Template constructed"
+%]
+
+<p>
+ You can bookmark this link:
+ &ldquo;<a href="enter_bug.cgi?[% url FILTER html %]">
+ [% IF short_desc %]
+ [% short_desc FILTER html %]
+ [% ELSE %]
+ [% terms.Bug %] entry template
+ [% END %]</a>&rdquo;.
+ This bookmark will bring up the <em>Enter [% terms.Bug %]</em> page with the
+ fields initialized as you've requested.
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/bug/create/user-message.html.tmpl b/template/en/default/bug/create/user-message.html.tmpl
new file mode 100644
index 0000000..197cf1a
--- /dev/null
+++ b/template/en/default/bug/create/user-message.html.tmpl
@@ -0,0 +1,22 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# Migration note: this file corresponds to the old Param
+ # 'entryheaderhtml'
+ #%]
+
+[%# You can make the output of this template product-specific by using
+ # Template Toolkit IF statements. The current product name is stored in
+ # the 'product' variable.
+ #%]
+
+Before reporting [% terms.abug %], please read the
+<a href="page.cgi?id=bug-writing.html">
+[% terms.bug %] writing guidelines</a>, please look at the list of
+<a href="duplicates.cgi">most frequently reported [% terms.bugs %]</a>, and please
+<a href="query.cgi">search</a> for the [% terms.bug %].
diff --git a/template/en/default/bug/dependency-graph.html.tmpl b/template/en/default/bug/dependency-graph.html.tmpl
new file mode 100644
index 0000000..153cebd
--- /dev/null
+++ b/template/en/default/bug/dependency-graph.html.tmpl
@@ -0,0 +1,89 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # bug_id: integer. The number of the bug(s).
+ # multiple_bugs: boolean. True if bug_id contains > 1 bug number.
+ # showsummary: boolean. True if we are showing bug summaries.
+ # rankdir: string. "TB" if we are ranking top-to-bottom,
+ "LR" if left-to-right.
+ # image_url: string. The URL of the graphic showing the dependencies.
+ # map_url: string. The URL of the map file for the image. (Optional)
+ # image_map: string. The image map for the graphic showing the
+ dependencies. (Optional)
+ #%]
+
+[% title = "Dependency Graph"
+ header = title
+ %]
+
+[% IF NOT multiple_bugs %]
+ [% filtered_desc = short_desc FILTER html %]
+ [% title = "$title for $terms.bug $bug_id"
+ header = "$header for $terms.bug <a href=\"show_bug.cgi?id=$bug_id\">$bug_id</a>"
+ subheader = filtered_desc
+ %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl %]
+
+[% image_map %]
+
+<p>
+ Green circles represent open [% terms.bugs %].
+</p>
+
+[% IF image_map %]
+ <img src="[% image_url %]" alt="Dependency graph" usemap="#imagemap">
+[% ELSE %]
+ <a href="[% map_url %]">
+ <img src="[% image_url %]" alt="Dependency graph" ismap="ismap">
+ </a>
+[% END %]
+
+<hr>
+
+<form action="showdependencygraph.cgi" method="GET">
+ <table>
+ <tr>
+ <th align="left"><label for="id">[% terms.Bug %] numbers</label>:</th>
+ <td><input id="id" name="id" value="[% bug_id %]"></td>
+ <td>
+ <input type="checkbox" id="showsummary" name="showsummary" [% " checked" IF showsummary %]>
+ <label for="showsummary">Show the summaries of all displayed [% terms.bugs %]</label>
+ </td>
+ </tr>
+
+ <tr>
+ <th align="left"><label for="display">Display:</label></th>
+ <td colspan="2">
+ <select id="display" name="display">
+ <option value="tree"[% 'selected="selected"' IF (!display || display == "tree") %]>
+ Restrict to [% terms.bugs %] having a direct relationship with entered [% terms.bugs %]</option>
+ <option value="web" [% 'selected="selected"' IF display == "web" %]>
+ Show all [% terms.bugs %] having any relationship with entered [% terms.bugs %]</option>
+ </select>
+ </td>
+ </tr>
+
+ <tr>
+ <th align="left"><label for="rankdir">Orientation:</label></th>
+ <td colspan="2">
+ <select id="rankdir" name="rankdir">
+ <option value="TB"[% " selected" IF rankdir == "TB" %]>Top to bottom</option>
+ <option value="BT"[% " selected" IF rankdir == "BT" %]>Bottom to top</option>
+ <option value="LR"[% " selected" IF rankdir == "LR" %]>Left to right</option>
+ <option value="RL"[% " selected" IF rankdir == "RL" %]>Right to left</option>
+ </select>
+ </td>
+ </tr>
+ </table>
+ <input type="submit" id="change" value="Change Parameters">
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/bug/dependency-tree.html.tmpl b/template/en/default/bug/dependency-tree.html.tmpl
new file mode 100644
index 0000000..a4bb0e6
--- /dev/null
+++ b/template/en/default/bug/dependency-tree.html.tmpl
@@ -0,0 +1,265 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% filtered_desc = blocked_tree.$bugid.short_desc FILTER html %]
+[% PROCESS global/header.html.tmpl
+ title = "Dependency tree for $terms.Bug $bugid"
+ header = "Dependency tree for
+ <a href=\"show_bug.cgi?id=$bugid\">$terms.Bug $bugid</a>"
+ javascript_urls = ["js/expanding-tree.js"]
+ style_urls = ["skins/standard/dependency-tree.css"]
+ subheader = filtered_desc
+ doc_section = "hintsandtips.html#dependencytree"
+%]
+
+[% PROCESS depthControlToolbar %]
+
+[% INCLUDE tree_section ids=dependson_ids type=1 %]
+
+[% INCLUDE tree_section ids=blocked_ids type=2 %]
+
+[% PROCESS depthControlToolbar %]
+
+[% PROCESS global/footer.html.tmpl %]
+
+[%###########################################################################%]
+[%# Tree-drawing blocks #%]
+[%###########################################################################%]
+
+[% BLOCK tree_section %]
+ [%# INTERFACE
+ # - ids: a list of bug IDs to be displayed as children
+ # - type: the type of tree. 1 = depends on, 2 = blockeds
+ # GLOBALS
+ # - seen: Maintains a global hash of bugs that have been displayed
+ #%]
+ [% global.seen = {} %]
+ [%# Display the tree of bugs that this bug depends on. %]
+ <h3>
+ <a href="show_bug.cgi?id=[% bugid %]">[% terms.Bug %] [%+ bugid %]</a>
+ [% IF type == 1 %]
+ [% tree_name = "dependson_tree" %]
+ [% IF ids.size %]
+ depends on
+ [% ELSE %]
+ does not depend on any [% 'open ' IF hide_resolved %][% terms.bugs %].
+ [% END %]
+ [% ELSIF type == 2 %]
+ [% tree_name = "blocked_tree" %]
+ [% IF ids.size %]
+ blocks
+ [% ELSE %]
+ does not block any [% 'open ' IF hide_resolved %][% terms.bugs %].
+ [% END %]
+ [% END %]
+ [% IF ids.size %]
+ [%+ (ids.size == 1) ? "one" : ids.size %]
+ [%+ IF hide_resolved %]open[% END %]
+ [%+ (ids.size == 1) ? terms.bug : terms.bugs %]:
+ [% END %]
+ </h3>
+ [% IF ids.size %]
+ [%# 27 chars is the length of buglist.cgi?tweak=&bug_id=" %]
+ [% use_post = (ids.join(",").length > constants.CGI_URI_LIMIT - 27 ) ? 1 : 0 %]
+ [% IF use_post %]
+ <form action="buglist.cgi" method="post">
+ <input type="hidden" name="bug_id" value="[% ids.join(",") %]">
+ [% END %]
+
+ [% IF maxdepth -%]Up to [% maxdepth %] level[% "s" IF maxdepth > 1 %] deep | [% END -%]
+ [% IF use_post %]
+ <button>view as [% terms.bug %] list</button>
+ [% IF user.in_group('editbugs') && ids.size > 1 %]
+ | <button type="submit" name="tweak" value="1">change several</button>
+ [% END %]
+ </form>
+ [% ELSE %]
+ <a href="buglist.cgi?bug_id=[% ids.join(",") %]">view as [% terms.bug %] list</a>
+ [% IF user.in_group('editbugs') && ids.size > 1 %]
+ | <a href="buglist.cgi?bug_id=[% ids.join(",") %]&amp;tweak=1">change several</a>
+ [% END %]
+ [% END %]
+
+ <ul class="tree">
+ [% INCLUDE display_tree tree=$tree_name %]
+ </ul>
+ [% END %]
+[% END %]
+
+
+[% BLOCK display_tree %]
+ [%# INTERFACE
+ # - bugid: the ID of the bug being displayed
+ # - tree: a hash of bug objects and of bug dependencies
+ #%]
+ [% bug = tree.$bugid %]
+ <li>
+ [%- INCLUDE bullet bugid=bugid tree=tree -%]
+ <span class="summ[% "_deep" IF tree.dependencies.$bugid.size %]"
+ id="[% bugid FILTER html %]"
+ [% IF global.seen.$bugid %]
+ onMouseover="duplicatedover('[% bugid FILTER html %]')"
+ onMouseout="duplicatedout('[% bugid FILTER html %]')"
+ [% END %]>
+ [%- INCLUDE buglink bug=bug bugid=bugid %]
+ </span>
+ [% IF global.seen.$bugid %]
+ <b><a title="Already displayed above; click to locate"
+ onclick="duplicated('[% bugid FILTER html %]')"
+ href="#b[% bugid %]">(*)</a></b>
+ [% ELSIF tree.dependencies.$bugid.size %]
+ <ul>
+ [% FOREACH depid = tree.dependencies.$bugid %]
+ [% INCLUDE display_tree bugid=depid %]
+ [% END %]
+ </ul>
+ [% END %]
+ </li>
+ [% global.seen.$bugid = 1 %]
+[% END %]
+
+[% BLOCK bullet %]
+ [% IF tree.dependencies.$bugid.size && ! global.seen.$bugid %]
+ [% extra_class = " b_open" %]
+ [% extra_args = 'onclick="return doToggle(this, event)"' %]
+ [% END %]
+ <a id="b[% bugid %]"
+ class="b [%+ extra_class FILTER none %]"
+ title="Click to expand or contract this portion of the tree. Hold down the Ctrl key while clicking to expand or contract all subtrees."
+ [% extra_args FILTER none %]>&nbsp;&nbsp;</a>
+[% END %]
+
+[% BLOCK buglink %]
+ [% isclosed = !bug.isopened %]
+ [% FILTER closed(isclosed) -%]
+ <a title="[% INCLUDE buginfo bug=bug %]"
+ href="show_bug.cgi?id=[% bugid %]">
+ <b>[%- bugid %]:</b>
+ <span class="summ_text">[%+ bug.short_desc FILTER html %]</span>
+ <span class="summ_info">[[% INCLUDE buginfo %]]</span>
+ </a>
+ <a href="showdependencytree.cgi?id=[% bugid FILTER uri %]"
+ class="tree_link">
+ <img src="skins/standard/dependency-tree/tree.png"
+ title="See dependency tree for [% terms.bug %] [%+ bugid FILTER html %]">
+ </a>
+ [% END %]
+[% END %]
+
+[% BLOCK buginfo %]
+ [% display_value("bug_status", bug.bug_status) FILTER html -%] [%+ display_value("resolution", bug.resolution) FILTER html %];
+ [%-%] assigned to [% bug.assigned_to.login FILTER email FILTER html %]
+ [%-%][% "; Target: " _ bug.target_milestone IF bug.target_milestone %]
+[% END %]
+
+[%###########################################################################%]
+[%# Block for depth control toolbar #%]
+[%###########################################################################%]
+
+[% BLOCK depthControlToolbar %]
+ <table cellpadding="3" border="0" cellspacing="0" bgcolor="#e0e0e0">
+ <tr>
+ [%# Hide/show resolved button
+ Swaps text depending on the state of hide_resolved %]
+ <td align="center">
+ <form method="get" action="showdependencytree.cgi"
+ style="display: inline; margin: 0px;">
+ <input name="id" type="hidden" value="[% bugid %]">
+ [% IF maxdepth %]
+ <input name="maxdepth" type="hidden" value="[% maxdepth %]">
+ [% END %]
+ <input type="hidden" name="hide_resolved" value="[% hide_resolved ? 0 : 1 %]">
+ <input type="submit" id="toggle_visibility"
+ value="[% IF hide_resolved %]Show[% ELSE %]Hide[% END %] Resolved">
+ </form>
+ </td>
+
+ <td>
+ Max Depth:
+ </td>
+
+ <td>
+ &nbsp;
+ </td>
+
+ <td>
+ <form method="get" action="showdependencytree.cgi"
+ style="display: inline; margin: 0px;">
+ [%# set to one form %]
+ <input type="submit" id="change_maxdepth"
+ value="&nbsp;1&nbsp;"
+ [% "disabled" IF realdepth < 2 || maxdepth == 1 %]>
+ <input name="id" type="hidden" value="[% bugid %]">
+ <input name="maxdepth" type="hidden" value="1">
+ <input name="hide_resolved" type="hidden" value="[% hide_resolved %]">
+ </form>
+ </td>
+
+ <td>
+ <form method="get" action="showdependencytree.cgi"
+ style="display: inline; margin: 0px;">
+ [%# Minus one form
+ Allow subtracting only when realdepth and maxdepth > 1 %]
+ <input name="id" type="hidden" value="[% bugid %]">
+ <input name="maxdepth" type="hidden" value="[%
+ maxdepth == 1 ? 1
+ : ( maxdepth ? maxdepth - 1 : realdepth - 1 )
+ %]">
+ <input name="hide_resolved" type="hidden" value="[% hide_resolved %]">
+ <input type="submit" id="decrease_depth" value="&nbsp;&lt;&nbsp;"
+ [% "disabled" IF realdepth < 2 || ( maxdepth && maxdepth < 2 ) %]>
+ </form>
+ </td>
+
+ <td>
+ <form method="get" action="showdependencytree.cgi"
+ style="display: inline; margin: 0px;">
+ [%# Limit entry form: the button cannot do anything when total depth
+ is less than two, so disable it %]
+ <input name="maxdepth" size="4" maxlength="4" value="[%
+ maxdepth > 0 && maxdepth <= realdepth ? maxdepth : ""
+ %]">
+ <input name="id" type="hidden" value="[% bugid %]">
+ <input name="hide_resolved" type="hidden" value="[% hide_resolved %]">
+ <noscript>
+ <input type="submit" id="change_depth" value="Change"
+ [% "disabled" IF realdepth < 2 %]>
+ </noscript>
+ </form>
+ </td>
+
+ <td>
+ <form method="get" action="showdependencytree.cgi"
+ style="display: inline; margin: 0px;">
+ [%# plus one form
+ Disable button if total depth < 2, or if depth set to unlimited %]
+ <input name="id" type="hidden" value="[% bugid %]">
+ [% IF maxdepth %]
+ <input name="maxdepth" type="hidden" value="[% maxdepth + 1 %]">
+ [% END %]
+ <input name="hide_resolved" type="hidden" value="[% hide_resolved %]">
+ <input type="submit" id="increase_depth" value="&nbsp;&gt;&nbsp;"
+ [% "disabled" IF realdepth < 2 || !maxdepth || maxdepth >= realdepth %]>
+ </form>
+ </td>
+
+ <td>
+ <form method="get" action="showdependencytree.cgi"
+ style="display: inline; margin: 0px;">
+ [%# Unlimited button %]
+ <input name="id" type="hidden" value="[% bugid %]">
+ <input name="hide_resolved" type="hidden" value="[% hide_resolved %]">
+ <input type="submit" id="remove_limit"
+ value="&nbsp;Unlimited&nbsp;"
+ [% "disabled" IF maxdepth == 0 || maxdepth == realdepth %]>
+ </form>
+ </td>
+ </tr>
+</table>
+
+[% END %]
diff --git a/template/en/default/bug/edit.html.tmpl b/template/en/default/bug/edit.html.tmpl
new file mode 100644
index 0000000..7b7c0df
--- /dev/null
+++ b/template/en/default/bug/edit.html.tmpl
@@ -0,0 +1,1172 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS bug/time.html.tmpl %]
+
+<script type="text/javascript">
+<!--
+[% IF user.is_timetracker %]
+ var fRemainingTime = [% bug.remaining_time %]; // holds the original value
+ function adjustRemainingTime() {
+ // subtracts time spent from remaining time
+ var new_time;
+
+ // prevent negative values if work_time > fRemainingTime
+ new_time =
+ Math.max(fRemainingTime - document.changeform.work_time.value, 0.0);
+ // get upto 2 decimal places
+ document.changeform.remaining_time.value =
+ Math.round(new_time * 100)/100;
+ }
+
+ function updateRemainingTime() {
+ // if the remaining time is changed manually, update fRemainingTime
+ fRemainingTime = document.changeform.remaining_time.value;
+ }
+[% END %]
+
+[% IF user.id %]
+ /* Index all classifications so we can keep track of the classification
+ * for the selected product, which could control field visibility.
+ */
+ var all_classifications = new Array([% bug.choices.product.size %]);
+ [%- FOREACH product = bug.choices.product %]
+ all_classifications['[% product.name FILTER js %]'] = '
+ [%- product.classification.name FILTER js %]';
+ [%- END %]
+[% END %]
+//-->
+</script>
+
+<form name="changeform" id="changeform" method="post" action="process_bug.cgi">
+
+ <input type="hidden" name="delta_ts" value="[% bug.delta_ts %]">
+ <input type="hidden" name="longdesclength" value="[% bug.comments.size %]">
+ <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 %]">
+
+ [% PROCESS section_title %]
+ <table class="edit_form">
+ <tr>
+ [%# 1st Column %]
+ <td id="bz_show_bug_column_1" class="bz_show_bug_column">
+ <table>
+ [%# *** ID, product, component, status, resolution, Hardware, and OS *** %]
+ [% PROCESS section_status %]
+
+ [% PROCESS section_spacer %]
+
+ [% PROCESS section_details1 %]
+
+ [% PROCESS section_spacer %]
+
+ [%# *** severity, priority, version and milestone *** %]
+ [% PROCESS section_details2 %]
+
+ [%# *** assigned to and qa contact *** %]
+ [% PROCESS section_people %]
+
+ [% PROCESS section_spacer %]
+
+ [% PROCESS section_url_keyword_whiteboard %]
+
+ [% PROCESS section_spacer %]
+
+ [%# *** Dependencies and duplicates *** %]
+ [% PROCESS section_duplicates %]
+
+ [% PROCESS section_dependson_blocks %]
+
+ </table>
+ </td>
+ <td>
+ <div class="bz_column_spacer">&nbsp;</div>
+ </td>
+ [%# 2nd Column %]
+ <td id="bz_show_bug_column_2" class="bz_show_bug_column">
+ <table cellpadding="3" cellspacing="1">
+ [%# *** Reported and modified dates *** %]
+ [% PROCESS section_dates %]
+
+ [% PROCESS section_cclist %]
+
+ [% PROCESS section_spacer %]
+
+ [% PROCESS section_see_also %]
+
+ [% PROCESS section_customfields %]
+
+ [% PROCESS section_spacer %]
+
+ [% Hook.process("after_custom_fields") %]
+
+ [% PROCESS section_flags %]
+
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="3">
+ <hr id="bz_top_half_spacer">
+ </td>
+ </tr>
+ </table>
+
+ <table id="bz_big_form_parts" cellspacing="0" cellpadding="0"><tr>
+ <td>
+ [% IF user.is_timetracker %]
+ [% PROCESS section_timetracking %]
+ [% END %]
+
+ [%# *** Attachments *** %]
+
+ [% PROCESS attachment/list.html.tmpl
+ attachments = bug.attachments
+ bugid = bug.bug_id
+ num_attachment_flag_types = bug.num_attachment_flag_types
+ show_attachment_flags = bug.show_attachment_flags
+ %]
+
+ [% IF user.settings.comment_box_position.value == 'before_comments' %]
+ [% PROCESS comment_box %]
+ [% END %]
+ </td>
+ <td>
+ [% PROCESS section_restrict_visibility %]
+ </td>
+ </tr></table>
+
+ [%# *** Additional Comments *** %]
+ <div id="comments">
+ [% PROCESS bug/comments.html.tmpl
+ comments = bug.comments
+ mode = user.id ? "edit" : "show"
+ %]
+ </div>
+
+ [% IF user.settings.comment_box_position.value == 'after_comments' %]
+ <hr>
+ [% PROCESS comment_box %]
+ [% END %]
+
+</form>
+
+[%############################################################################%]
+[%# Block for the Title (alias and short desc) #%]
+[%############################################################################%]
+
+[% BLOCK section_title %]
+ [%# That's the main table, which contains all editable fields. %]
+ <div class="bz_alias_short_desc_container edit_form">
+ [% PROCESS commit_button id="_top"%]
+ <a href="show_bug.cgi?id=[% bug.bug_id %]">
+ [%-# %]<b>[% terms.Bug %]&nbsp;[% bug.bug_id FILTER html %]</b>
+ [%-# %]</a> -<span id="summary_alias_container" class="bz_default_hidden">
+ [% IF bug.alias != "" %]
+ (<span id="alias_nonedit_display">[% bug.alias FILTER html %]</span>)
+ [% END %]
+ <span id="short_desc_nonedit_display">[% bug.short_desc FILTER quoteUrls(bug) %]</span>
+ [% IF bug.check_can_change_field('short_desc', 0, 1) ||
+ bug.check_can_change_field('alias', 0, 1) %]
+ <small class="editme">(<a href="#" id="editme_action">edit</a>)</small>
+ [% END %]
+ </span>
+
+
+ <div id="summary_alias_input">
+ <table id="summary">
+ <tr>
+ [% IF bug.check_can_change_field('alias', 0, 1) %]
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.alias
+ editable = 1
+ %]
+ <td>
+ [% ELSIF bug.alias %]
+ <td colspan="2">(
+ [% ELSE %]
+ <td colspan="2">
+ [% END %]
+ [% PROCESS input inputname => "alias"
+ size => "20"
+ maxlength => "20"
+ no_td => 1
+ %][% ")" IF NOT bug.check_can_change_field('alias', 0, 1)
+ && bug.alias %]
+ </td>
+ </tr>
+ [%# *** Summary *** %]
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.short_desc
+ editable = 1
+ accesskey = "s"
+ %]
+ <td>
+ [% PROCESS input inputname => "short_desc" size => "80" colspan => 2
+ maxlength => 255 spellcheck => "true" no_td => 1 %]
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ <script type="text/javascript">
+ hideAliasAndSummary('[% bug.short_desc FILTER js %]', '[% bug.alias FILTER js %]');
+ </script>
+[% END %]
+
+[%############################################################################%]
+[%# Block for the first table in the "Details" section #%]
+[%############################################################################%]
+
+[% BLOCK section_details1 %]
+
+ [%#############%]
+ [%# PRODUCT #%]
+ [%#############%]
+ <tr>
+ [% INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.product,
+ override_legal_values = bug.choices.product
+ desc_url = 'describecomponents.cgi', value = bug.product
+ editable = bug.check_can_change_field('product', 0, 1) %]
+ </tr>
+
+ [%# Classification is here so that it can be used in value controllers
+ # and visibility controllers. It comes after product because
+ # it uses some javascript that depends on the existence of the
+ # product field.
+ #%]
+ <tr class="bz_default_hidden">
+ [% INCLUDE bug/field.html.tmpl
+ bug = bug field = bug_fields.classification
+ override_legal_values = bug.choices.classification
+ value = bug.classification
+ editable = bug.check_can_change_field('product', 0, 1) %]
+ </tr>
+ [%###############%]
+ [%# Component #%]
+ [%###############%]
+ <tr>
+ [% INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.component, value = bug.component
+ override_legal_values = bug.choices.component
+ desc_url = "describecomponents.cgi?product=$bug.product"
+ editable = bug.check_can_change_field('component', 0, 1)
+ %]
+ </tr>
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.version editable = 1 %]
+
+ [% PROCESS select selname => "version" %]
+ </tr>
+ [%############%]
+ [%# PLATFORM #%]
+ [%############%]
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.rep_platform, editable = 1, accesskey = "h" %]
+ <td class="field_value">
+ [% INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.rep_platform,
+ no_tds = 1, value = bug.rep_platform
+ editable = bug.check_can_change_field('rep_platform', 0, 1) %]
+ [%+ INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.op_sys,
+ no_tds = 1, value = bug.op_sys
+ editable = bug.check_can_change_field('op_sys', 0, 1) %]
+ </td>
+ </tr>
+
+
+
+[% END %]
+
+[%############################################################################%]
+[%# Block for the status section #%]
+[%############################################################################%]
+
+[% BLOCK section_status %]
+ <tr>
+ <th class="field_label">
+ <a href="page.cgi?id=fields.html#bug_status">Status</a>:
+ </th>
+ <td id="bz_field_status">
+ <span id="static_bug_status">
+ [% display_value("bug_status", bug.bug_status) FILTER html %]
+ [% IF bug.resolution %]
+ [%+ display_value("resolution", bug.resolution) FILTER html %]
+ [% IF bug.dup_id %]
+ of [% "${terms.bug} ${bug.dup_id}" FILTER bug_link(bug.dup_id) FILTER none %]
+ [% END %]
+ [% END %]
+ [% IF bug.user.canedit || bug.user.isreporter %]
+ (<a href="#add_comment"
+ onclick="window.setTimeout(function() { document.getElementById('bug_status').focus(); }, 10)">edit</a>)
+ [% END %]
+ </span>
+ </td>
+ </tr>
+[% END %]
+
+[%############################################################################%]
+[%# Block for the second table in the "Details" section #%]
+[%############################################################################%]
+
+[% BLOCK section_details2 %]
+
+ [%###############################################################%]
+ [%# Importance (priority and severity) #%]
+ [%###############################################################%]
+ <tr>
+ <th class="field_label">
+ <label for="priority" accesskey="i">
+ <a href="page.cgi?id=fields.html#importance"><u>I</u>mportance</a></label>:
+ </th>
+ <td>
+ [% INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.priority,
+ no_tds = 1, value = bug.priority
+ editable = bug.check_can_change_field('priority', 0, 1) %]
+ [%+ INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.bug_severity,
+ no_tds = 1, value = bug.bug_severity
+ editable = bug.check_can_change_field('bug_severity', 0, 1) %]
+ [% Hook.process('after_importance', 'bug/edit.html.tmpl') %]
+ </td>
+ </tr>
+
+ [% IF Param("usetargetmilestone") && bug.target_milestone %]
+ <tr>
+ <th class="field_label">
+ <label for="target_milestone">
+ <a href="page.cgi?id=fields.html#target_milestone">
+ Target&nbsp;Milestone</a></label>:
+ </th>
+ [% PROCESS select selname = "target_milestone" %]
+ </tr>
+ [% END %]
+
+[% END %]
+
+[%############################################################################%]
+[%# Block for the table in the "People" section #%]
+[%############################################################################%]
+
+[% BLOCK section_people %]
+
+ <tr>
+ <th class="field_label">
+ <a href="page.cgi?id=fields.html#assigned_to">Assigned To</a>:
+ </th>
+ <td>
+ [% IF bug.check_can_change_field("assigned_to", 0, 1) %]
+ <div id="bz_assignee_edit_container" class="bz_default_hidden">
+ <span>
+ [% INCLUDE global/user.html.tmpl who = bug.assigned_to %]
+ (<a href="#" id="bz_assignee_edit_action">edit</a>)
+ [% IF bug.assigned_to.id != user.id %]
+ (<a title="Reassign to yourself"
+ href="#" id="bz_assignee_take_action">take</a>)
+ [% END %]
+ </span>
+ </div>
+ <div id="bz_assignee_input">
+ [% INCLUDE global/userselect.html.tmpl
+ id => "assigned_to"
+ name => "assigned_to"
+ value => bug.assigned_to.login
+ classes => ["bz_userfield"]
+ size => 30
+ %]
+ <br>
+ <input type="checkbox" id="set_default_assignee" name="set_default_assignee" value="1">
+ <label id="set_default_assignee_label" for="set_default_assignee">Reset Assignee to default</label>
+ </div>
+ <script type="text/javascript">
+ hideEditableField('bz_assignee_edit_container',
+ 'bz_assignee_input',
+ 'bz_assignee_edit_action',
+ 'assigned_to',
+ '[% bug.assigned_to.login FILTER js %]' );
+ hideEditableField('bz_assignee_edit_container',
+ 'bz_assignee_input',
+ 'bz_assignee_take_action',
+ 'assigned_to',
+ '[% bug.assigned_to.login FILTER js %]',
+ '[% user.login FILTER js %]' );
+ initDefaultCheckbox('assignee');
+ </script>
+ [% ELSE %]
+ [% INCLUDE global/user.html.tmpl who = bug.assigned_to %]
+ [% END %]
+ </td>
+ </tr>
+
+ [% IF Param('useqacontact') %]
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.qa_contact
+ editable = 1
+ accesskey = "q"
+ %]
+ <td>
+ [% IF bug.check_can_change_field("qa_contact", 0, 1) %]
+ <div id="bz_qa_contact_edit_container" class="bz_default_hidden">
+ <span>
+ [% INCLUDE global/user.html.tmpl who = bug.qa_contact %]
+ (<a href="#" id="bz_qa_contact_edit_action">edit</a>)
+ [% IF bug.qa_contact.id != user.id %]
+ (<a title="Change QA contact to yourself"
+ href="#" id="bz_qa_contact_take_action">take</a>)
+ [% END %]
+ </span>
+ </div>
+ <div id="bz_qa_contact_input">
+ [% INCLUDE global/userselect.html.tmpl
+ id => "qa_contact"
+ name => "qa_contact"
+ value => bug.qa_contact.login
+ size => 30
+ classes => ["bz_userfield"]
+ emptyok => 1
+ %]
+ <br>
+ <input type="checkbox" id="set_default_qa_contact" name="set_default_qa_contact" value="1">
+ <label for="set_default_qa_contact" id="set_default_qa_contact_label">Reset QA Contact to default</label>
+ </div>
+ <script type="text/javascript">
+ hideEditableField('bz_qa_contact_edit_container',
+ 'bz_qa_contact_input',
+ 'bz_qa_contact_edit_action',
+ 'qa_contact',
+ '[% bug.qa_contact.login FILTER js %]');
+ hideEditableField('bz_qa_contact_edit_container',
+ 'bz_qa_contact_input',
+ 'bz_qa_contact_take_action',
+ 'qa_contact',
+ '[% bug.qa_contact.login FILTER js %]',
+ '[% user.login FILTER js %]');
+ initDefaultCheckbox('qa_contact');
+ </script>
+ [% ELSE %]
+ [% INCLUDE global/user.html.tmpl who = bug.qa_contact %]
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+ <script type="text/javascript">
+ assignToDefaultOnChange(['product', 'component'],
+ '[% bug.component_obj.default_assignee.login FILTER js %]',
+ '[% bug.component_obj.default_qa_contact.login FILTER js %]');
+ </script>
+[% END %]
+
+[%############################################################################%]
+[%# Block for URL Keyword and Whiteboard #%]
+[%############################################################################%]
+[% BLOCK section_url_keyword_whiteboard %]
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.bug_file_loc
+ editable = 1
+ accesskey = "u"
+ %]
+ <td>
+ [% IF bug.check_can_change_field("bug_file_loc", 0, 1) %]
+ <span id="bz_url_edit_container" class="bz_default_hidden">
+ [% IF is_safe_url(bug.bug_file_loc) %]
+ <a href="[% bug.bug_file_loc FILTER html %]" target="_blank"
+ title="[% bug.bug_file_loc FILTER html %]">
+ [% bug.bug_file_loc FILTER truncate(40) FILTER html %]</a>
+ [% ELSE %]
+ [% bug.bug_file_loc FILTER html %]
+ [% END %]
+ (<a href="#" id="bz_url_edit_action">edit</a>)</span>
+ [% END %]
+ <span id="bz_url_input_area">
+ [% url_output = PROCESS input no_td=1 inputname => "bug_file_loc" size => "40" colspan => 2 %]
+ [% IF NOT bug.check_can_change_field("bug_file_loc", 0, 1)
+ AND is_safe_url(bug.bug_file_loc) %]
+ <a href="[% bug.bug_file_loc FILTER html %]">[% url_output FILTER none %]</a>
+ [% ELSE %]
+ [% url_output FILTER none %]
+ [% END %]
+ </span>
+ [% IF bug.check_can_change_field("bug_file_loc", 0, 1) %]
+ <script type="text/javascript">
+ hideEditableField('bz_url_edit_container',
+ 'bz_url_input_area',
+ 'bz_url_edit_action',
+ 'bug_file_loc',
+ "[% bug.bug_file_loc FILTER js %]");
+ </script>
+ [% END %]
+ </td>
+ </tr>
+
+ [% IF Param('usestatuswhiteboard') %]
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.status_whiteboard
+ editable = 1
+ accesskey = "w"
+ %]
+ [% PROCESS input inputname => "status_whiteboard" size => "40" colspan => 2 %]
+ </tr>
+ [% END %]
+
+ [% IF use_keywords %]
+ <tr>
+ <th class="field_label">
+ <label for="keywords" accesskey="k">
+ <a href="describekeywords.cgi"><u>K</u>eywords</a></label>:
+ </th>
+ <td class="field_value" colspan="2">
+ [% INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.keywords, value = bug.keywords
+ editable = bug.check_can_change_field("keywords", 0, 1),
+ no_tds = 1, possible_values = all_keywords
+ %]
+ </td>
+ </tr>
+ [% END %]
+
+ [% IF user.id %]
+ <tr>
+ [% INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.tag, value = bug.tags.join(", "),
+ editable = 1, possible_values = user.tags.keys
+ %]
+ </tr>
+ [% END %]
+[% END %]
+
+[%############################################################################%]
+[%# Block for Duplicates #%]
+[%############################################################################%]
+
+[% BLOCK section_duplicates %]
+ [% RETURN UNLESS bug.duplicates.size %]
+ <tr>
+ <th class="field_label">
+ <label for="duplicates">Duplicates</label>:
+ </th>
+ <td class="field_value" colspan="2">
+ <span id="duplicates">
+ [% FOREACH dupe = bug.duplicates %]
+ [% dupe.id FILTER bug_link(dupe, use_alias => 1) FILTER none %][% " " %]
+ [% END %]
+ </span>
+ (<a href="buglist.cgi?bug_id=[% bug.duplicate_ids.join(",") FILTER html %]">
+ [%-%]view as [% terms.bug %] list</a>)
+ </td>
+ </tr>
+[% END %]
+
+[%############################################################################%]
+[%# Block for Depends On / Blocks #%]
+[%############################################################################%]
+
+[% BLOCK section_dependson_blocks %]
+ <tr>
+ [% INCLUDE dependencies
+ field = bug_fields.dependson deps = bug.depends_on_obj %]
+ </tr>
+
+ <tr>
+ [% INCLUDE dependencies
+ field = bug_fields.blocked deps = bug.blocks_obj %]
+ </tr>
+
+ <tr>
+ <th>&nbsp;</th>
+
+ <td colspan="2" align="left" id="show_dependency_tree_or_graph">
+ Show dependency <a href="showdependencytree.cgi?id=[% bug.bug_id %]&amp;hide_resolved=1">tree</a>
+
+ [% IF Param('webdotbase') %]
+ /&nbsp;<a href="showdependencygraph.cgi?id=[% bug.bug_id %]">graph</a>
+ [% END %]
+ </td>
+ </tr>
+[% END %]
+
+
+[%############################################################################%]
+[%# Block for Restricting Visibility #%]
+[%############################################################################%]
+
+[% BLOCK section_restrict_visibility %]
+ [% RETURN UNLESS bug.groups.size %]
+
+ <div class="bz_group_visibility_section">
+ [% inallgroups = 1 %]
+ [% inagroup = 0 %]
+ [% emitted_description = 0 %]
+
+ [% FOREACH group = bug.groups %]
+ [% SET inallgroups = 0 IF NOT group.ingroup %]
+ [% SET inagroup = 1 IF group.ison %]
+
+ [% NEXT IF group.mandatory %]
+
+ [% IF NOT emitted_description %]
+ [% emitted_description = 1 %]
+ <div id="bz_restrict_group_visibility_help">
+ <b>Only users in all of the selected groups can view this
+ [%+ terms.bug %]:</b>
+ <p class="instructions">
+ Unchecking all boxes makes this a more public [% terms.bug %].
+ </p>
+ </div>
+ [% END %]
+
+ [% IF group.ingroup %]
+ <input type="hidden" name="defined_groups"
+ value="[% group.name FILTER html %]">
+ [% END %]
+
+ <input type="checkbox" value="[% group.name FILTER html %]"
+ name="groups" id="group_[% group.bit %]"
+ [% ' checked="checked"' IF group.ison %]
+ [% ' disabled="disabled"' IF NOT group.ingroup %]>
+ <label for="group_[% group.bit %]">
+ [%- group.description FILTER html_light %]</label>
+ <br>
+ [% END %]
+
+ [% IF emitted_description %]
+ [% IF NOT inallgroups %]
+ <p class="instructions">Only members of a group can change the
+ visibility of [% terms.abug %] for that group.</p>
+ [% END %]
+ [% END %]
+
+ [% IF inagroup %]
+ <div id="bz_enable_role_visibility_help">
+ <b>Users in the roles selected below can always view
+ this [% terms.bug %]:</b>
+ </div>
+ <div id="bz_enable_role_visibility">
+ <div>
+ [% user_can_edit_accessible =
+ bug.check_can_change_field("reporter_accessible", 0, 1)
+ %]
+ [% IF user_can_edit_accessible %]
+ <input type="hidden" name="defined_reporter_accessible" value="1">
+ [% END %]
+ <input type="checkbox" value="1"
+ name="reporter_accessible" id="reporter_accessible"
+ [% " checked" IF bug.reporter_accessible %]
+ [% " disabled=\"disabled\"" UNLESS user_can_edit_accessible %]>
+ <label for="reporter_accessible">Reporter</label>
+ </div>
+ <div>
+ [% user_can_edit_accessible =
+ bug.check_can_change_field("cclist_accessible", 0, 1)
+ %]
+ [% IF user_can_edit_accessible %]
+ <input type="hidden" name="defined_cclist_accessible" value="1">
+ [% END %]
+ <input type="checkbox" value="1"
+ name="cclist_accessible" id="cclist_accessible"
+ [% " checked" IF bug.cclist_accessible %]
+ [% " disabled=\"disabled\"" UNLESS user_can_edit_accessible %]>
+ <label for="cclist_accessible">CC List</label>
+ </div>
+ <p class="instructions">
+ The assignee
+ [% IF (Param('useqacontact')) %]
+ and QA contact
+ [% END %]
+ can always see [% terms.abug %], and this section does not
+ take effect unless the [% terms.bug %] is restricted to at
+ least one group.
+ </p>
+ </div>
+ [% END %]
+ </div> [%# bz_group_visibility_section %]
+[% END %]
+
+[%############################################################################%]
+[%# Block for Dates #%]
+[%############################################################################%]
+
+[% BLOCK section_dates %]
+ <tr>
+ <th class="field_label">
+ Reported:
+ </th>
+ <td>
+ [% bug.creation_ts FILTER time %] by [% INCLUDE global/user.html.tmpl who = bug.reporter %]
+ </td>
+ </tr>
+
+ <tr>
+ <th class="field_label">
+ Modified:
+ </th>
+ <td>
+ [% bug.delta_ts FILTER time FILTER replace(':\d\d$', '') FILTER replace(':\d\d ', ' ')%]
+ (<a href="show_activity.cgi?id=[% bug.bug_id %]">[%# terms.Bug %]History</a>)
+ </td>
+
+ </tr>
+[% END %]
+
+[%############################################################################%]
+[%# Block for CC LIST #%]
+[%############################################################################%]
+[% BLOCK section_cclist %]
+ <tr>
+ <th class="field_label">
+ <label for="newcc" accesskey="a">CC List:</label>
+ </th>
+ <td>
+ [% IF user.id %]
+ [% IF NOT bug.cc.contains(user.login) %]
+ <input type="checkbox" id="addselfcc" name="addselfcc"
+ [% " checked=\"checked\""
+ IF user.settings.state_addselfcc.value == 'always'
+ || (!bug.user.has_any_role
+ && user.settings.state_addselfcc.value == 'cc_unless_role') %]>
+ <label for="addselfcc">Add me to CC list</label>
+ <br>
+ [% END %]
+ [% END %]
+ [% bug.cc.size FILTER html %]
+ [% IF bug.cc.size == 1 %]
+ user
+ [% ELSE %]
+ users
+ [% END %]
+ [% IF user.id %]
+ [% IF bug.cc.contains( user.email ) %]
+ including you
+ [% END %]
+ [% END %]
+ [% IF user.id || bug.cc.size %]
+ <span id="cc_edit_area_showhide_container" class="bz_default_hidden">
+ (<a href="#" id="cc_edit_area_showhide">[% IF user.id %]edit[% ELSE %]show[% END %]</a>)
+ </span>
+ [% END %]
+ <div id="cc_edit_area">
+ <br>
+ [% IF user.id %]
+ <div>
+ <div><label for="cc"><b>Add</b></label></div>
+ [% INCLUDE global/userselect.html.tmpl
+ id => "newcc"
+ name => "newcc"
+ value => ""
+ size => 30
+ classes => ["bz_userfield"]
+ multiple => 5
+ %]
+ </div>
+ [% END %]
+ [% IF bug.cc.size %]
+ <select id="cc" multiple="multiple" size="5"
+ [% IF bug.user.canedit %]name="cc"[% END %]>
+ [% FOREACH c = bug.cc %]
+ <option value="[% c FILTER email FILTER html %]">
+ [% c FILTER email FILTER html %]</option>
+ [% END %]
+ </select>
+ [% IF user.id && !bug.user.canedit %]
+ <input type="hidden" name="cc" value="[% user.login FILTER email FILTER html %]">
+ [% END %]
+ [% IF user.id AND (bug.user.canedit OR bug.cc.contains(user.login)) %]
+ <br>
+ <input type="checkbox" id="removecc" name="removecc">
+ <label for="removecc">
+ [% IF bug.user.canedit %]
+ Remove selected CCs
+ [% ELSE %]
+ Remove me from the CC list
+ [% END %]
+ </label>
+ <br>
+ [% END %]
+ [% END %]
+ </div>
+ [% IF user.id || bug.cc.size %]
+ <script type="text/javascript">
+ hideEditableField( 'cc_edit_area_showhide_container',
+ 'cc_edit_area',
+ 'cc_edit_area_showhide',
+ '',
+ '');
+ </script>
+ [% END %]
+ </td>
+ </tr>
+[% END %]
+
+[%############################################################################%]
+[%# Block for See Also #%]
+[%############################################################################%]
+[% BLOCK section_see_also %]
+ [% IF Param('use_see_also') || bug.see_also.size %]
+ <tr>
+ [% INCLUDE bug/field.html.tmpl
+ field = bug_fields.see_also
+ value = bug.see_also
+ editable = bug.check_can_change_field('see_also', 0, 1)
+ %]
+ </tr>
+ [% END %]
+[% END %]
+
+[%############################################################################%]
+[%# Block for FLAGS #%]
+[%############################################################################%]
+
+[% BLOCK section_flags %]
+ [%# *** Flags *** %]
+ [% show_bug_flags = 0 %]
+ [% bug_flags_set = 0 %]
+ [% show_more_flags = 0 %]
+ [% FOREACH type = bug.flag_types %]
+ [% IF type.flags.size || (user.id && type.is_active && user.can_request_flag(type)) %]
+ [% show_bug_flags = 1 %]
+ [% END %]
+ [% IF user.id && type.is_active && (!type.flags.size || type.is_multiplicable) %]
+ [% show_more_flags = 1 %]
+ [% END %]
+ [% IF type.flags.size %]
+ [% bug_flags_set = 1 %]
+ [% END %]
+ [% LAST IF show_bug_flags && show_more_flags && bug_flags_set %]
+ [% END %]
+ [% IF show_bug_flags %]
+ <tr>
+ <th class="field_label">
+ <label>Flags:</label>
+ </th>
+ <td>
+ [% IF bug.flag_types.size %]
+ [% PROCESS "flag/list.html.tmpl" flag_no_header = 1
+ flag_types = bug.flag_types
+ any_flags_requesteeble = bug.any_flags_requesteeble %]
+ [% END %]
+ [% IF show_more_flags %]
+ <span id="bz_flags_more_container" class="bz_default_hidden">
+ [% IF !bug_flags_set %]<em>None yet set</em>[% END %]
+ (<a href="#" id="bz_flags_more_action">[% IF !bug_flags_set %]set[% ELSE %]more[% END %] flags</a>)
+ </span>
+ <script type="text/javascript">
+ YAHOO.util.Dom.removeClass('bz_flags_more_container', 'bz_default_hidden');
+ var table = YAHOO.util.Dom.get("flags");
+ var rows = YAHOO.util.Dom.getElementsByClassName('bz_flag_type', 'tbody', table);
+ for (var i = 0; i < rows.length; i++) {
+ YAHOO.util.Dom.addClass(rows[i], 'bz_default_hidden');
+ }
+ YAHOO.util.Event.addListener('bz_flags_more_action', 'click', function (e) {
+ YAHOO.util.Dom.addClass('bz_flags_more_container', 'bz_default_hidden');
+ for (var i = 0; i < rows.length; i++) {
+ YAHOO.util.Dom.removeClass(rows[i], 'bz_default_hidden');
+ }
+ YAHOO.util.Event.preventDefault(e);
+ });
+ </script>
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+[% END %]
+
+[%############################################################################%]
+[%# Block for Custom Fields #%]
+[%############################################################################%]
+
+[% BLOCK section_customfields %]
+[%# *** Custom Fields *** %]
+ [% USE Bugzilla %]
+ [% FOREACH field = Bugzilla.active_custom_fields %]
+ <tr>
+ [% PROCESS bug/field.html.tmpl value = bug.${field.name}
+ editable = bug.check_can_change_field(field.name, 0, 1)
+ value_span = 2 %]
+ </tr>
+ [% IF extra_field_item %]
+ <tr>
+ <th class="field_label">[% extra_field_item.header FILTER none %]</th>
+ <td>[% extra_field_item.data FILTER none %]</td>
+ </tr>
+ [% END %]
+ [% END %]
+[% END %]
+
+[%############################################################################%]
+[%# Block for Section Spacer #%]
+[%############################################################################%]
+
+[% BLOCK section_spacer %]
+ <tr>
+ <td colspan="2" class="bz_section_spacer"></td>
+ </tr>
+[% END %]
+
+
+
+
+[%############################################################################%]
+[%# Block for dependencies #%]
+[%############################################################################%]
+
+[% BLOCK dependencies %]
+
+ [% INCLUDE "bug/field-label.html.tmpl" %]
+
+ <td>
+ <span id="[% field.name FILTER html %]_input_area">
+ [% IF bug.check_can_change_field(field.name, 0, 1) %]
+ <input name="[% field.name FILTER html %]"
+ id="[% field.name FILTER html %]" class="text_input"
+ value="[% bug.${field.name}.join(', ') FILTER html %]">
+ [% END %]
+ </span>
+
+ [% FOREACH dep_bug = deps %]
+ [% dep_bug.id FILTER bug_link(dep_bug, use_alias => 1)
+ FILTER none %][% " " %]
+ [% END %]
+ [% IF bug.check_can_change_field(field.name, 0, 1) %]
+ <span id="[% field.name FILTER html %]_edit_container"
+ class="edit_me bz_default_hidden">
+ (<a href="#" id="[% field.name FILTER html %]_edit_action">edit</a>)
+ </span>
+ <script type="text/javascript">
+ hideEditableField('[% field.name FILTER js %]_edit_container',
+ '[% field.name FILTER js %]_input_area',
+ '[% field.name FILTER js %]_edit_action',
+ '[% field.name FILTER js %]',
+ '[% bug.${field.name}.join(', ') FILTER js %]');
+ </script>
+ [% END %]
+ </td>
+
+[% END %]
+
+[%############################################################################%]
+[%# Block for Time Tracking Group #%]
+[%############################################################################%]
+
+[% BLOCK section_timetracking %]
+ <table class="bz_time_tracking_table">
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.estimated_time, editable = 1
+ %]
+ <th>
+ Current Est.:
+ </th>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.work_time, editable = 1
+ %]
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.remaining_time, editable = 1
+ %]
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.percentage_complete, editable = 1
+ %]
+ <th>
+ Gain:
+ </th>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.deadline, editable = 1
+ %]
+ </tr>
+ <tr>
+ <td>
+ <input name="estimated_time" id="estimated_time"
+ value="[% PROCESS formattimeunit
+ time_unit=bug.estimated_time %]"
+ size="6" maxlength="6">
+ </td>
+ <td>
+ [% PROCESS formattimeunit
+ time_unit=(bug.actual_time + bug.remaining_time) %]
+ </td>
+ <td>
+ [% PROCESS formattimeunit time_unit=bug.actual_time %] +
+ <input name="work_time" id="work_time"
+ value="0" size="3" maxlength="6"
+ onchange="adjustRemainingTime();">
+ </td>
+ <td>
+ <input name="remaining_time" id="remaining_time"
+ value="[% PROCESS formattimeunit
+ time_unit=bug.remaining_time %]"
+ size="6" maxlength="6" onchange="updateRemainingTime();">
+ </td>
+ <td>
+ [% PROCESS calculatepercentage act=bug.actual_time
+ rem=bug.remaining_time %]
+ </td>
+ <td>
+ [% PROCESS formattimeunit time_unit=bug.estimated_time - (bug.actual_time + bug.remaining_time) %]
+ </td>
+ <td>
+ [% INCLUDE bug/field.html.tmpl
+ field = bug_fields.deadline, value = bug.deadline, no_tds = 1
+ editable = bug.check_can_change_field('deadline', 0, 1) %]
+ </td>
+ </tr>
+ <tr>
+ <td colspan="7" class="bz_summarize_time">
+ <a href="summarize_time.cgi?id=[% bug.bug_id %]&amp;do_depends=1">
+ Summarize time (including time for [% terms.bugs %]
+ blocking this [% terms.bug %])</a>
+ </td>
+ </tr>
+ </table>
+[% END %]
+
+[%############################################################################%]
+[%# Block for the Additional Comments box #%]
+[%############################################################################%]
+
+[% BLOCK comment_box %]
+ <div id="add_comment" class="bz_section_additional_comments">
+ [% IF user.id %]
+ <label for="comment" accesskey="c"><b>Additional
+ <u>C</u>omments</b></label>:
+
+ [% IF user.is_insider && bug.check_can_change_field('longdesc', 0, 1) %]
+ <input type="checkbox" name="comment_is_private" value="1"
+ id="newcommentprivacy"
+ onClick="updateCommentTagControl(this, 'comment')">
+ <label for="newcommentprivacy">
+ Make comment private (visible only to members of the
+ <strong>[% Param('insidergroup') FILTER html %]</strong> group)
+ </label>
+ [% END %]
+
+ <!-- This table keeps the submit button aligned with the box. -->
+ <table><tr><td>
+ [% IF bug.check_can_change_field('longdesc', 0, 1) %]
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'comment'
+ id = 'comment'
+ minrows = 10
+ maxrows = 25
+ cols = constants.COMMENT_COLS
+ %]
+ [% IF user.is_insider %]
+ <script>
+ updateCommentTagControl(document.getElementById('newcommentprivacy'), 'comment');
+ </script>
+ [% END %]
+ [% Hook.process("after_comment_textarea", 'bug/edit.html.tmpl') %]
+ [% ELSE %]
+ You are not allowed to make an additional comment on this [% terms.bug %].
+ [% END %]
+ <br>
+ [% PROCESS commit_button id=""%]
+
+ <table id="bug_status_bottom"
+ class="status" cellspacing="0" cellpadding="0">
+ <tr>
+ <th class="field_label">
+ <a href="page.cgi?id=fields.html#bug_status">Status</a>:
+ </th>
+ <td>
+ [% PROCESS bug/knob.html.tmpl %]
+ </td>
+ </tr>
+ </table>
+ </td></tr></table>
+
+ [%# For logged-out users %]
+ [% ELSE %]
+ <table>
+ <tr>
+ <td>
+ <fieldset>
+ <legend>Note</legend>
+ You need to
+ <a href="show_bug.cgi?id=
+ [%- bug.bug_id %]&amp;GoAheadAndLogIn=1">log in</a>
+ before you can comment on or make changes to this [% terms.bug %].
+ </fieldset>
+ </td>
+ </tr>
+ </table>
+ [% END %]
+ </div>
+[% END %]
+
+[%############################################################################%]
+[%# Block for SELECT fields #%]
+[%############################################################################%]
+
+[% BLOCK select %]
+ <td>
+ [% IF bug.check_can_change_field(selname, 0, 1)
+ AND bug.choices.${selname}.size > 1 %]
+ <input type="hidden" id="[% selname %]_dirty">
+ <select id="[% selname %]" name="[% selname %]">
+ [% FOREACH x = bug.choices.${selname} %]
+ [% NEXT IF NOT x.is_active AND x.name != bug.${selname} %]
+ <option value="[% x.name FILTER html %]"
+ [% " selected" IF x.name == bug.${selname} %]>
+ [%- x.name FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ [% ELSE %]
+ [% bug.${selname} FILTER html %]
+ [% END %]
+ </td>
+[% END %]
+
+[%############################################################################%]
+[%# Block for INPUT fields #%]
+[%############################################################################%]
+
+[% BLOCK input %]
+ [% IF no_td != 1 %]
+ <td[% " colspan=\"$colspan\"" IF colspan %]>
+ [% END %]
+ [% val = value ? value : bug.$inputname %]
+ [% IF bug.check_can_change_field(inputname, 0, 1) %]
+ <input id="[% inputname %]" name="[% inputname %]" class="text_input"
+ value="[% val FILTER html %]"[% " size=\"$size\"" IF size %]
+ [% " maxlength=\"$maxlength\"" IF maxlength %]
+ [% " spellcheck=\"$spellcheck\"" IF spellcheck %]>
+ [% ELSE %]
+ [% IF size && val.length > size %]
+ <span title="[% val FILTER html %]">
+ [% val FILTER truncate(size) FILTER html %]
+ </span>
+ [% ELSE %]
+ [% val FILTER html %]
+ [% END %]
+ [% END %]
+ [% IF no_td != 1 %]
+ </td>
+ [% END %]
+ [% no_td = 0 %]
+ [% maxlength = 0 %]
+ [% colspan = 0 %]
+ [% size = 0 %]
+ [% value = undef %]
+ [% spellcheck = undef %]
+[% END %]
+[% BLOCK commit_button %]
+ [% IF user.id %]
+ <div class="knob-buttons">
+ <input type="submit" value="Save Changes"
+ id="commit[% id FILTER css_class_quote %]">
+ </div>
+ [% END %]
+[% END %]
diff --git a/template/en/default/bug/field-events.js.tmpl b/template/en/default/bug/field-events.js.tmpl
new file mode 100644
index 0000000..8ec51a4
--- /dev/null
+++ b/template/en/default/bug/field-events.js.tmpl
@@ -0,0 +1,59 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # field: a Bugzilla::Field object
+ # product: (optional) a Bugzilla::Product object. When specified,
+ # components are restricted to this product.
+ #%]
+
+[% FOREACH controlled_field = field.controls_visibility_of %]
+ [% vis_names = [] %]
+ [% FOREACH visibility_value = controlled_field.visibility_values %]
+ [%# Exclude non-enterable products and components outside the current product. %]
+ [% NEXT IF field.name == "product"
+ && visibility_value.id != product.id
+ && !user.can_enter_product(visibility_value) %]
+ [% NEXT IF field.name == "component" && visibility_value.product_id != product.id %]
+ [% vis_names.push(visibility_value.name) %]
+ [% END %]
+
+ [% NEXT UNLESS vis_names.size %]
+
+ showFieldWhen('[% controlled_field.name FILTER js %]',
+ '[% field.name FILTER js %]', [
+ [%~ FOREACH vis_name = vis_names ~%]
+ '[% vis_name FILTER js %]'[% "," UNLESS loop.last %]
+ [%~ END ~%]
+ ]);
+[% END %]
+
+[% legal_values = [] %]
+[% IF field.name == "component" AND product %]
+ [% legal_values = product.components %]
+[% ELSE %]
+ [% legal_values = field.legal_values %]
+[% END %]
+
+[% FOREACH legal_value = legal_values %]
+ [% FOREACH controlled_field = legal_value.controlled_values.keys %]
+ [% SET cont_ids = [] %]
+ [% FOREACH val = legal_value.controlled_values.$controlled_field %]
+ [% NEXT IF !val.is_active %]
+ [% cont_ids.push(val.id) %]
+ [% END %]
+ [% NEXT IF !cont_ids.size %]
+ showValueWhen('[% controlled_field FILTER js %]',
+ [[% cont_ids.join(',') FILTER js %]],
+ '[% field.name FILTER js %]',
+ [% legal_value.id FILTER js %]);
+ [% END %]
+[% END %]
+[% IF field.name == 'classification' %]
+ YAHOO.util.Event.on('product', 'change', setClassification);
+[% END %]
diff --git a/template/en/default/bug/field-help.none.tmpl b/template/en/default/bug/field-help.none.tmpl
new file mode 100644
index 0000000..c07ee57
--- /dev/null
+++ b/template/en/default/bug/field-help.none.tmpl
@@ -0,0 +1,243 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# This file describes both bug fields and search fields.
+ # As calling this template once per label is very expensive,
+ # it is called only by Template.pm. %]
+
+[% RETURN UNLESS in_template_var %]
+
+[% vars.help_html = {
+
+# Note that all these keys here are in alphabetical order, though
+# search-specific fields are at the bottom.
+
+##############
+# Bug Fields #
+##############
+
+alias =>
+ "A short, unique name assigned to $terms.abug in order to assist with
+ looking it up and referring to it in other places in ${terms.Bugzilla}.",
+
+assigned_to =>
+ "The person in charge of resolving the ${terms.bug}.",
+
+blocked =>
+ "This $terms.bug must be resolved before the $terms.bugs listed in this
+ field can be resolved.",
+
+bug_file_loc =>
+ "$terms.Bugs can have a URL associated with them - for example, a"
+ _ " pointer to a web site where the problem is seen.",
+
+bug_id =>
+ "The numeric id of $terms.abug, unique within this entire installation"
+ _ " of ${terms.Bugzilla}.",
+
+bug_severity =>
+ "How severe the $terms.bug is, or whether it's an enhancement.",
+
+bug_status =>
+ "$terms.Abug may be in any of a number of states.",
+
+cc =>
+ "Users who may not have a direct role to play on this $terms.bug, but who
+ are interested in its progress.",
+
+classification =>
+ "$terms.Bugs are categorised into Classifications, Products and"
+ _ " Components. classifications is the top-level categorisation.",
+
+component =>
+ "Components are second-level categories; each belongs to a"
+ _ " particular Product. Select a Product to narrow down this list.",
+
+creation_ts =>
+ "When the $terms.bug was filed.",
+
+deadline =>
+ "The date that this $terms.bug must be resolved by, entered in YYYY-MM-DD
+ format.",
+
+delta_ts =>
+ "When this $terms.bug was last updated.",
+
+dependson =>
+ "The $terms.bugs listed here must be resolved before this $terms.bug
+ can be resolved.",
+
+estimated_time =>
+ "The amount of time that has been estimated it will take to resolve
+ this ${terms.bug}.",
+
+importance =>
+ "The importance of $terms.abug is described as the combination of
+ its $vars.field_descs.priority and ${vars.field_descs.bug_severity}.",
+
+keywords =>
+ "You can add keywords from a defined list to $terms.bugs, in order"
+ _ " to easily identify and group them.",
+
+longdesc =>
+ "$terms.Bugs have comments added to them by $terms.Bugzilla users."
+ _ " You can search for some text in those comments.",
+
+op_sys =>
+ "The operating system the $terms.bug was observed on.",
+
+percentage_complete =>
+ "How close to 100% done this $terms.bug is, by comparing its
+ $vars.field_descs.work_time to its ${vars.field_descs.estimated_time}.",
+
+priority =>
+ "Engineers prioritize their $terms.bugs using this field.",
+
+# Note that this has extra text added below if useclassification is on.
+product =>
+ "$terms.Bugs are categorised into Products and Components.",
+
+qa_contact =>
+ "The person responsible for confirming this $terms.bug if it is"
+ _ " unconfirmed, and for verifying the fix once the $terms.bug"
+ _ " has been resolved.",
+
+remaining_time =>
+ "The number of hours of work left on this $terms.bug, calculated by
+ subtracting the $vars.field_descs.work_time from the
+ ${vars.field_descs.estimated_time}.",
+
+rep_platform =>
+ "The hardware platform the $terms.bug was observed on.",
+
+reporter =>
+ "The person who filed this ${terms.bug}.",
+
+resolution =>
+ "If $terms.abug is in a resolved state, then one of these reasons"
+ _ " will be given for its resolution.",
+
+see_also =>
+ "This allows you to refer to $terms.bugs in other installations.
+ You can enter a URL to $terms.abug in the 'Add $terms.Bug URLs'
+ field to note that that $terms.bug is related to this one. You can
+ enter multiple URLs at once by separating them with a comma.
+
+ <p>You should normally use this field to refer to $terms.bugs in
+ <em>other</em> installations. For $terms.bugs in this
+ installation, it is better to use the $vars.field_descs.dependson and
+ $vars.field_descs.blocked fields.</p>",
+
+short_desc =>
+ "The $terms.bug summary is a short sentence which succinctly"
+ _ " describes what the $terms.bug is about.",
+
+status_whiteboard =>
+ "Each $terms.bug has a free-form single line text entry box for"
+ _ " adding tags and status information.",
+
+tag =>
+ "Unlike ${vars.field_descs.keywords} which are global and visible by
+ all users, ${vars.field_descs.tag} are personal and can only be
+ viewed and edited by their author.
+ Editing them won't send any notification to other users. Use them
+ to tag and keep track of ${terms.bugs}.",
+
+target_milestone =>
+ "The $vars.field_descs.target_milestone field is used to define when the"
+ _ " engineer the $terms.bug is assigned to expects to fix it.",
+
+version =>
+ "The version field defines the version of the software the"
+ _ " $terms.bug was found in.",
+
+votes =>
+ "Some $terms.bugs can be voted for, and you can limit your search to"
+ _ " $terms.bugs with more than a certain number of votes.",
+
+work_time =>
+ "The total amount of time spent on this $terms.bug so far.",
+
+##########################
+# Search-specific fields #
+##########################
+
+chfield =>
+ "You can search for specific types of change - this field defines"
+ _" which field you are interested in changes for.",
+
+# Duplicated to chfieldto below, also.
+chfieldfrom =>
+ "Specify the start and end dates either in YYYY-MM-DD format
+ optionally followed by HH:mm, in 24 hour clock), or in relative
+ dates such as 1h, 2d, 3w, 4m, 5y, which respectively mean one hour,
+ two days, three weeks, four months, or five years ago. 0d is last
+ midnight, and 0h, 0w, 0m, 0y is the beginning of this hour, week,
+ month, or year.",
+
+chfieldvalue =>
+ "The value the field defined above changed to during that time.",
+
+content =>
+ "This is a field available in searches that does a Google-like
+ 'full-text' search on the $vars.field_descs.short_desc and
+ $vars.field_descs.longdesc fields.",
+
+# Duplicated to email2 below, also.
+email1 =>
+ "Every $terms.bug has people associated with it in different"
+ _ " roles. Here, you can search on what people are in what role.",
+
+} %]
+
+[% vars.help_html.email2 = vars.help_html.email1 %]
+[% vars.help_html.chfieldto = vars.help_html.chfieldfrom %]
+[% vars.help_html.deadlinefrom = vars.help_html.deadline %]
+[% vars.help_html.deadlineto = vars.help_html.deadline %]
+
+[% help_all_note = BLOCK %]
+ <strong>Note:</strong> When searching, selecting the option "All"
+ only finds [% terms.bugs %] whose value for this field is literally
+ the word "All".
+[% END %]
+[% FOREACH all_field = ['op_sys', 'rep_platform'] %]
+ [% vars.help_html.$all_field = vars.help_html.$all_field _ ' ' _ help_all_note %]
+[% END %]
+
+[% IF Param('useclassification') %]
+ [% vars.help_html.product = vars.help_html.product
+ _ " Select a Classification to narrow down this list." %]
+[% END %]
+
+[% FOREACH help_field = bug_fields.keys %]
+
+ [%# Add help for custom fields. %]
+ [% IF !vars.help_html.${help_field}.defined %]
+ [% IF bug_fields.${help_field}.long_desc %]
+ [% vars.help_html.${help_field} = bug_fields.${help_field}.long_desc %]
+ [% ELSE %]
+ [% SET field_type = bug_fields.${help_field}.type %]
+ [% field_type_desc = BLOCK -%]
+ [% field_types.$field_type FILTER html %]
+ [%- END %]
+ [% vars.help_html.${help_field} =
+ "A custom $field_type_desc field in this installation"
+ _ " of ${terms.Bugzilla}." %]
+ [% END %]
+ [% END %]
+
+ [%# Add help for the search types, for query.cgi. %]
+ [% type_desc = BLOCK %]
+ The type of [% vars.field_descs.${help_field} FILTER html %] search you
+ would like.
+ [% END %]
+ [% SET type_name = help_field _ '_type' %]
+ [% vars.help_html.$type_name = type_desc %]
+[% END %]
+
+[% Hook.process("end") %]
diff --git a/template/en/default/bug/field-label.html.tmpl b/template/en/default/bug/field-label.html.tmpl
new file mode 100644
index 0000000..95ac28a
--- /dev/null
+++ b/template/en/default/bug/field-label.html.tmpl
@@ -0,0 +1,41 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # field: a Bugzilla::Field object
+ # desc_url: An alternate link to help for the field.
+ # hidden: True if the field label should start hidden.
+ # rowspan: a "rowspan" value for the label's <th>.
+ # tag_name: the tag to use to surround the label
+ # accesskey: access key for the label
+ #%]
+
+[% DEFAULT tag_name = "th" %]
+<[% tag_name FILTER html %] class="field_label [% ' bz_hidden_field' IF hidden %]
+ [%- ' required' IF field.is_mandatory && NOT bug.id %]"
+ id="field_label_[% field.name FILTER html %]"
+ [% IF rowspan %] rowspan="[% rowspan FILTER html %]"[% END %]>
+
+ [% IF editable %]
+ <label for="[% field.name FILTER html %]"[% IF accesskey %] accesskey="[% accesskey FILTER html %]"[% END %]>
+ [% END %]
+
+ <a
+ [% IF help_html.${field.name}.defined %]
+ title="[% help_html.${field.name} FILTER txt FILTER collapse FILTER html %]"
+ class="field_help_link"
+ [% END %]
+ [% IF desc_url %]
+ href="[% desc_url FILTER html %]"
+ [% ELSE %]
+ href="page.cgi?id=fields.html#[% field.name FILTER uri %]"
+ [% END %]
+ >[%- field_descs.${field.name} FILTER html %]:</a>
+
+ [% '</label>' IF editable %]
+</[% tag_name FILTER html %]>
diff --git a/template/en/default/bug/field.html.tmpl b/template/en/default/bug/field.html.tmpl
new file mode 100644
index 0000000..e05bced
--- /dev/null
+++ b/template/en/default/bug/field.html.tmpl
@@ -0,0 +1,242 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # field: a Bugzilla::Field object
+ # value: The value of the field for this bug.
+ # override_legal_values (optional): The list of legal values, for select fields.
+ # editable: Whether the field should be displayed as an editable
+ # <input> or as just the plain text of its value.
+ # allow_dont_change: display the --do_not_change-- option for select fields.
+ # value_span: A colspan for the table cell containing
+ # the field value.
+ # no_tds: boolean; if true, don't display the label <th> or the
+ # wrapping <td> for the field.
+ # bug (optional): The current Bugzilla::Bug being displayed, or a hash
+ # with default field values being displayed on a page.
+ #%]
+
+[% IF NOT no_tds %]
+ [% field_hidden = 0 %]
+ [% IF bug AND !field.is_visible_on_bug(bug) %]
+ [% field_hidden = 1 %]
+ [% END %]
+
+ [% INCLUDE "bug/field-label.html.tmpl" hidden = field_hidden %]
+ <td class="field_value [% ' bz_hidden_field' IF field_hidden %]"
+ id="field_container_[% field.name FILTER html %]"
+ [% " colspan=\"$value_span\"" FILTER none IF value_span %]>
+[% END %]
+[% Hook.process('start_field_column') %]
+[% IF editable %]
+ [% SWITCH field.type %]
+ [% CASE constants.FIELD_TYPE_FREETEXT %]
+ <input id="[% field.name FILTER html %]" class="text_input"
+ name="[% field.name FILTER html %]"
+ value="[% value FILTER html %]" size="40"
+ maxlength="[% constants.MAX_FREETEXT_LENGTH FILTER none %]"
+ [% ' aria-required="true"' IF field.is_mandatory %]>
+ [% CASE constants.FIELD_TYPE_DATETIME %]
+ <input name="[% field.name FILTER html %]" size="20"
+ id="[% field.name FILTER html %]"
+ value="[% value FILTER html %]"
+ [% ' aria-required="true"' IF field.is_mandatory %]
+ onchange="updateCalendarFromField(this)">
+ <button type="button" class="calendar_button"
+ id="button_calendar_[% field.name FILTER html %]"
+ onclick="showCalendar('[% field.name FILTER js %]')">
+ <span>Calendar</span>
+ </button>
+
+ <div id="con_calendar_[% field.name FILTER html %]"></div>
+
+ <script type="text/javascript">
+ <!--
+ [%+ PROCESS "global/calendar.js.tmpl" id = field.name %]
+ //--></script>
+ [% CASE constants.FIELD_TYPE_BUG_ID %]
+ <span id="[% field.name FILTER html %]_input_area">
+ <input name="[% field.name FILTER html %]" id="[% field.name FILTER html %]"
+ value="[% value FILTER html %]" size="7"
+ [% ' aria-required="true"' IF field.is_mandatory %]>
+
+ </span>
+
+ [% IF value %]
+ [% value FILTER bug_link(value, use_alias => 1) FILTER none %]
+ [% END %]
+ <span id="[% field.name FILTER html %]_edit_container" class="edit_me bz_default_hidden">
+ (<a href="#" id="[% field.name FILTER html %]_edit_action">edit</a>)
+ </span>
+ <script type="text/javascript">
+ hideEditableField('[% field.name FILTER js %]_edit_container',
+ '[% field.name FILTER js %]_input_area',
+ '[% field.name FILTER js %]_edit_action',
+ '[% field.name FILTER js %]',
+ "[% value FILTER js %]");
+ </script>
+ [% CASE [ constants.FIELD_TYPE_SINGLE_SELECT
+ constants.FIELD_TYPE_MULTI_SELECT ] %]
+ <input type="hidden" id="[% field.name FILTER html %]_dirty">
+ <select id="[% field.name FILTER html %]"
+ name="[% field.name FILTER html %]"
+ [% IF field.type == constants.FIELD_TYPE_MULTI_SELECT %]
+ [% SET field_size = 5 %]
+ [% IF field.legal_values.size < 5 %]
+ [% SET field_size = field.legal_values.size %]
+ [% END %]
+ size="[% field_size FILTER html %]" multiple="multiple"
+ [% ' aria-required="true"' IF field.is_mandatory %]
+ [% END %]
+ >
+ [% IF allow_dont_change %]
+ <option value="[% dontchange FILTER html %]"
+ [% ' selected="selected"' IF value == dontchange %]>
+ [% dontchange FILTER html %]
+ </option>
+ [% END %]
+ [% IF override_legal_values %]
+ [% legal_values = override_legal_values %]
+ [% ELSE %]
+ [% legal_values = field.legal_values %]
+ [% END %]
+ [% FOREACH legal_value = legal_values %]
+ [% NEXT IF NOT legal_value.is_active AND NOT value.contains(legal_value.name).size %]
+ <option value="[% legal_value.name FILTER html %]"
+ id="v[% legal_value.id FILTER html %]_
+ [%- field.name FILTER html %]"
+ [%# We always show selected values, even if they should be
+ # hidden %]
+ [% IF value.contains(legal_value.name).size %]
+ selected="selected"
+ [% ELSIF bug AND !legal_value.is_visible_on_bug(bug) %]
+ class="bz_hidden_option" disabled="disabled"
+ [% END %]>
+ [%- display_value(field.name, legal_value.name) FILTER html ~%]
+ </option>
+ [% END %]
+ </select>
+ [%# When you pass an empty multi-select in the web interface,
+ # it doesn't appear at all in the CGI object. Instead of
+ # forcing all users of process_bug to always specify every
+ # multi-select, we have this field defined if the multi-select
+ # field is defined, and then if this is passed but the multi-select
+ # isn't, we know that the multi-select was emptied.
+ %]
+ [% IF field.type == constants.FIELD_TYPE_MULTI_SELECT %]
+ <input type="hidden" name="defined_[% field.name FILTER html %]">
+ [% END %]
+
+ <script type="text/javascript">
+ <!--
+ initHidingOptionsForIE('[% field.name FILTER js %]');
+ [%+ INCLUDE "bug/field-events.js.tmpl"
+ field = field, product = bug.product_obj %]
+ //-->
+ </script>
+
+ [% CASE constants.FIELD_TYPE_TEXTAREA %]
+ [% INCLUDE global/textarea.html.tmpl
+ id = field.name name = field.name minrows = 4 maxrows = 8
+ cols = 60 defaultcontent = value mandatory = field.is_mandatory %]
+ [% CASE constants.FIELD_TYPE_BUG_URLS %]
+ [% '<ul class="bug_urls">' IF value.size %]
+ [% FOREACH bug_url = value %]
+ <li>
+ [% PROCESS bug_url_link bug_url = bug_url %]
+ <label><input type="checkbox" value="[% bug_url.name FILTER html %]"
+ name="remove_[% field.name FILTER html %]">
+ Remove</label>
+ </li>
+ [% END %]
+ [% '</ul>' IF value.size %]
+
+ [% IF Param('use_see_also') %]
+ <span id="container_showhide_[% field.name FILTER html %]"
+ class="bz_default_hidden">
+ (<a href="#" id="showhide_[% field.name FILTER html %]">add</a>)
+ </span>
+ <div id="container_[% field.name FILTER html %]">
+ <label for="[% field.name FILTER html %]">
+ <strong>Add [% terms.Bug %] URLs:</strong>
+ </label><br>
+ <input type="text" id="[% field.name FILTER html %]" size="40"
+ class="text_input" name="[% field.name FILTER html %]">
+ </div>
+ <script type="text/javascript">
+ setupEditLink('[% field.name FILTER js %]');
+ </script>
+ [% END %]
+ [% CASE constants.FIELD_TYPE_KEYWORDS %]
+ <div id="[% field.name FILTER html %]_container">
+ <input type="text" id="[% field.name FILTER html %]" size="40"
+ class="text_input" name="[% field.name FILTER html %]"
+ value="[% value FILTER html %]">
+ <div id="[% field.name FILTER html %]_autocomplete"></div>
+ </div>
+ <script type="text/javascript" defer="defer">
+ if (typeof YAHOO.bugzilla.field_array === "undefined")
+ YAHOO.bugzilla.field_array = [];
+ YAHOO.bugzilla.field_array["[% field.name FILTER js %]"] = [
+ [%- FOREACH val = possible_values %]
+ [%-# %]"[% val FILTER js %]"
+ [%- "," IF NOT loop.last %][% END %]];
+ YAHOO.bugzilla.fieldAutocomplete.init('[% field.name FILTER js %]',
+ '[% field.name FILTER js %]_autocomplete');
+ </script>
+ [% END %]
+[% ELSE %]
+ [% SWITCH field.type %]
+ [% CASE constants.FIELD_TYPE_TEXTAREA %]
+ <div class="uneditable_textarea">[% value FILTER html %]</div>
+ [% CASE constants.FIELD_TYPE_BUG_ID %]
+ [% IF value %]
+ [% value FILTER bug_link(value, use_alias => 1) FILTER none %]
+ [% END %]
+ [% CASE [ constants.FIELD_TYPE_SINGLE_SELECT
+ constants.FIELD_TYPE_MULTI_SELECT ] %]
+ [% FOREACH val = value %]
+ [% display_value(field.name, val) FILTER html %]
+ [% ', ' UNLESS loop.last() %]
+ [% END %]
+ [% CASE constants.FIELD_TYPE_BUG_URLS %]
+ [% '<ul class="bug_urls">' IF value.size %]
+ [% FOREACH bug_url = value %]
+ <li>
+ [% PROCESS bug_url_link bug_url = bug_url %]
+ </li>
+ [% END %]
+ [% '</ul>' IF value.size %]
+ [% CASE %]
+ [% value.join(', ') FILTER html %]
+ [% END %]
+[% END %]
+[% Hook.process('end_field_column') %]
+[% '</td>' IF NOT no_tds %]
+
+[%# for reverse relationships, we show this pseudo-field after the main field %]
+[% IF bug.id && field.is_relationship %]
+ [% extra_field_item = {} %]
+ [% extra_field_item.header = field.reverse_desc _ ":" FILTER html %]
+ [% extra_field_item.data = BLOCK %]
+ [% FOREACH depbug = bug.related_bugs(field) %]
+ [% depbug.id FILTER bug_link(depbug, use_alias => 1) FILTER none %][% " " %]
+ [% END %]
+ [% END %]
+[% ELSE %]
+ [% extra_field_item = '' %]
+[% END %]
+
+[% BLOCK bug_url_link %]
+ [% IF bug_url.isa('Bugzilla::BugUrl::Bugzilla::Local') %]
+ [% bug_url.target_bug_id FILTER bug_link(bug_url.target_bug_id, use_alias => 1) FILTER none %]
+ [% ELSE %]
+ <a href="[% bug_url.name FILTER html %]">
+ [% bug_url.name FILTER html %]</a>
+ [% END %]
+[% END %]
diff --git a/template/en/default/bug/format_comment.txt.tmpl b/template/en/default/bug/format_comment.txt.tmpl
new file mode 100644
index 0000000..b8d6742
--- /dev/null
+++ b/template/en/default/bug/format_comment.txt.tmpl
@@ -0,0 +1,48 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# NOTE: Everywhere you use this template, you must call
+ # "FILTER remove('^X')" on the result. This is unfortunately the only way
+ # to preserve leading whitespace in comments.
+ #%]
+
+[%# INTERFACE:
+ # comment: A Bugzilla::Comment object.
+ # is_bugmail: boolean; True if this comment is going into a plain-text
+ # bugmail.
+ #%]
+
+[%# Please don't use field-descs here. It can slow down Bugzilla. %]
+
+[% SET comment_body = comment.body %]
+
+[% IF comment.type == constants.CMT_DUPE_OF %]
+X[% comment_body %]
+
+*** This [% terms.bug %] has been marked as a duplicate of [% terms.bug %] [%+ comment.extra_data %] ***
+[% ELSIF comment.type == constants.CMT_HAS_DUPE %]
+*** [% terms.Bug %] [%+ comment.extra_data %] has been marked as a duplicate of this [% terms.bug %]. ***
+[% ELSIF comment.type == constants.CMT_ATTACHMENT_CREATED %]
+Created attachment [% comment.extra_data %]
+[% IF is_bugmail %]
+ --> [% urlbase _ "attachment.cgi?id=" _ comment.extra_data _ "&action=edit" %]
+[% END %]
+[%+ comment.attachment.description %]
+
+[%+ comment.body %]
+[% ELSIF comment.type == constants.CMT_ATTACHMENT_UPDATED %]
+Comment on attachment [% comment.extra_data %]
+[% IF is_bugmail %]
+ --> [% urlbase _ "attachment.cgi?id=" _ comment.extra_data %]
+[% END %]
+[%+ comment.attachment.description %]
+
+[%+ comment.body %]
+[% ELSE %]
+X[% Hook.process('type') %]
+[% END %]
diff --git a/template/en/default/bug/knob.html.tmpl b/template/en/default/bug/knob.html.tmpl
new file mode 100644
index 0000000..7046472
--- /dev/null
+++ b/template/en/default/bug/knob.html.tmpl
@@ -0,0 +1,84 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+<div id="status">
+ [% PROCESS bug/field.html.tmpl
+ no_tds = 1
+ field = bug_fields.bug_status
+ value = bug.bug_status
+ override_legal_values = bug.choices.bug_status
+ editable = bug.choices.bug_status.size > 1
+ %]
+
+ [% IF bug.resolution
+ OR bug.check_can_change_field('resolution', bug.resolution, 1)
+ %]
+ <noscript><br>resolved&nbsp;as&nbsp;</noscript>
+ [% END %]
+
+ <span id="resolution_settings">
+ [% PROCESS bug/field.html.tmpl
+ no_tds = 1
+ field = bug_fields.resolution
+ value = bug.resolution
+ override_legal_values = bug.choices.resolution
+ editable = bug.check_can_change_field('resolution', bug.resolution, 1)
+ %]
+ </span>
+
+ [% IF bug.check_can_change_field('dup_id', 0, 1) %]
+ <noscript><br> duplicate</noscript>
+ <span id="duplicate_settings">of
+ <span id="dup_id_container" class="bz_default_hidden">
+ [% "${terms.bug} ${bug.dup_id}" FILTER bug_link(bug.dup_id) FILTER none %]
+ (<a href="#" id="dup_id_edit_action">edit</a>)
+ </span
+ ><input id="dup_id" name="dup_id" size="6"
+ value="[% bug.dup_id FILTER html %]">
+ </span>
+ [% IF bug.dup_id %]
+ <noscript>[% bug.dup_id FILTER bug_link(bug.dup_id) FILTER none %]</noscript>
+ [% END %]
+ <div id="dup_id_discoverable" class="bz_default_hidden">
+ <a href="#" id="dup_id_discoverable_action">Mark as Duplicate</a>
+ </div>
+ [% ELSIF bug.dup_id %]
+ <noscript><br> duplicate</noscript>
+ <span id="duplicate_display">of
+ [% "${terms.bug} ${bug.dup_id}" FILTER bug_link(bug.dup_id) FILTER none %]</span>
+ [% END %]
+</div>
+
+<script type="text/javascript">
+ var close_status_array = [
+ [% FOREACH status = bug.choices.bug_status %]
+ [% NEXT IF status.is_open %]
+ '[% status.name FILTER js %]'[% ',' UNLESS loop.last %]
+ [% END %]
+ ];
+ YAHOO.util.Dom.removeClass('dup_id_discoverable', 'bz_default_hidden');
+ hideEditableField( "dup_id_container", "dup_id", 'dup_id_edit_action',
+ 'dup_id', '[% bug.dup_id FILTER js %]' )
+ showHideStatusItems( "", ['[% "is_duplicate" IF bug.dup_id %]',
+ '[% bug.bug_status FILTER js %]']);
+ YAHOO.util.Event.addListener( 'bug_status', "change", showHideStatusItems,
+ ['[% "is_duplicate" IF bug.dup_id %]',
+ '[% bug.bug_status FILTER js %]']);
+ YAHOO.util.Event.addListener( 'resolution', "change", showDuplicateItem);
+ YAHOO.util.Event.addListener( 'dup_id_discoverable_action',
+ 'click',
+ setResolutionToDuplicate,
+ '[% Param('duplicate_or_move_bug_status')
+ FILTER js %]');
+ YAHOO.util.Event.addListener( window, 'load', showHideStatusItems,
+ ['[% "is_duplicate" IF bug.dup_id %]',
+ '[% bug.bug_status FILTER js %]'] );
+
+ [% INCLUDE "bug/field-events.js.tmpl" field = select_fields.bug_status %]
+ [% INCLUDE "bug/field-events.js.tmpl" field = select_fields.resolution %]
+</script>
diff --git a/template/en/default/bug/link.html.tmpl b/template/en/default/bug/link.html.tmpl
new file mode 100644
index 0000000..40031e1
--- /dev/null
+++ b/template/en/default/bug/link.html.tmpl
@@ -0,0 +1,51 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # bug: a Bugzilla::Bug object
+ # link_text: the text that we're highlighting.
+ # use_alias: boolean; If true, we display the bug's alias as the link
+ # text instead of link_text.
+ # comment_num: If defined, make this a link to that comment on the bug.
+ # full_url: boolean; If true, generate links that include the full
+ # urlbase. (This is for emails, mostly.)
+ #%]
+
+[% IF !bug %]
+ &lt;missing&gt;
+ [% RETURN %]
+[% END %]
+
+[%# We use "FILTER none" here because link_title is filtered down below. %]
+[% link_title = BLOCK %]
+ [% display_value('bug_status', bug.bug_status) FILTER none %]
+ [% IF bug.resolution %]
+ [%+ display_value('resolution', bug.resolution) FILTER none %]
+ [% END %]
+[% END %]
+
+[% IF user.can_see_bug(bug) %]
+ [% link_title = link_title _ ' - ' _ bug.short_desc %]
+
+ [% IF use_alias && bug.alias %]
+ [% link_text = bug.alias %]
+ [% END %]
+[% END %]
+
+[% SET anchor = '' %]
+[% IF comment_num.defined %]
+ [% anchor = "#c$comment_num" %]
+[% END %]
+
+<a class="bz_bug_link
+ bz_status_[% bug.bug_status FILTER css_class_quote %]
+ [% ' bz_closed' IF !bug.isopened %]"
+ title="[% link_title FILTER collapse FILTER html %]"
+ href="[% urlbase FILTER html IF full_url %]show_bug.cgi?id=
+ [%~ bug.id FILTER uri %][% anchor FILTER html %]">
+ [%~ link_text FILTER html %]</a>
diff --git a/template/en/default/bug/navigate.html.tmpl b/template/en/default/bug/navigate.html.tmpl
new file mode 100644
index 0000000..22d8c47
--- /dev/null
+++ b/template/en/default/bug/navigate.html.tmpl
@@ -0,0 +1,73 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% RETURN IF !bug %]
+
+[% IF bottom_navigator == 1 %]
+ <ul class="related_actions">
+ <li><a href="show_bug.cgi?format=multiple&amp;id=
+ [% bug.bug_id FILTER uri %]">Format For Printing</a></li>
+ <li>&nbsp;-&nbsp;<a href="show_bug.cgi?ctype=xml&amp;id=
+ [% bug.bug_id FILTER uri %]">XML</a></li>
+ <li>&nbsp;-&nbsp;<a href="enter_bug.cgi?cloned_bug_id=
+ [% bug.bug_id FILTER uri %]">Clone This
+ [% terms.Bug %]</a></li>
+ [%# Links to more things users can do with this bug. %]
+ [% Hook.process("links") %]
+ <li>&nbsp;-&nbsp;<a href="#">Top of page </a></li>
+ </ul>
+[% END %]
+
+
+<div class="navigation">
+[% SET my_search = user.recent_search_for(bug) %]
+[% IF my_search %]
+ [% SET last_bug_list = my_search.bug_list %]
+ [% SET this_bug_idx = lsearch(last_bug_list, bug.id) %]
+ <b>[% terms.Bug %] List:</b>
+
+ ([% this_bug_idx + 1 %] of [% last_bug_list.size %])
+
+ <a href="show_bug.cgi?id=
+ [%- last_bug_list.first FILTER uri %]&amp;list_id=
+ [%- my_search.id FILTER uri %]">First</a>
+ <a href="show_bug.cgi?id=
+ [%- last_bug_list.last FILTER uri %]&amp;list_id=
+ [%- my_search.id FILTER uri %]">Last</a>
+
+ [% IF this_bug_idx > 0 %]
+ [% prev_bug = this_bug_idx - 1 %]
+ <a href="show_bug.cgi?id=
+ [%- last_bug_list.$prev_bug FILTER uri %]&amp;list_id=
+ [%- my_search.id FILTER uri %]">Prev</a>
+ [% ELSE %]
+ <i><font color="#777777">Prev</font></i>
+ [% END %]
+
+ [% IF this_bug_idx + 1 < last_bug_list.size %]
+ [% next_bug = this_bug_idx + 1 %]
+ <a href="show_bug.cgi?id=
+ [%- last_bug_list.$next_bug FILTER uri %]&amp;list_id=
+ [%- my_search.id FILTER uri %]">Next</a>
+ [% ELSE %]
+ <i><font color="#777777">Next</font></i>
+ [% END %]
+
+ &nbsp;&nbsp;<a href="buglist.cgi?regetlastlist=
+ [%- my_search.id FILTER uri %]">Show last search results</a>
+[% ELSE %]
+ [%# With no list, don't show link to search results %]
+ <i><font color="#777777">First</font></i>
+ <i><font color="#777777">Last</font></i>
+ <i><font color="#777777">Prev</font></i>
+ <i><font color="#777777">Next</font></i>
+ &nbsp;&nbsp;
+ <i><font color="#777777">This [% terms.bug %] is not in your last
+ search results.</font></i>
+[% END %]
+</div>
diff --git a/template/en/default/bug/process/bugmail.html.tmpl b/template/en/default/bug/process/bugmail.html.tmpl
new file mode 100644
index 0000000..b1c38da
--- /dev/null
+++ b/template/en/default/bug/process/bugmail.html.tmpl
@@ -0,0 +1,45 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # mailing_bugid: The bug ID that email is being sent for.
+ # sent_bugmail: The results of Bugzilla::BugMail::Send().
+ #%]
+
+<dl>
+[% PROCESS emails
+ description = "Email sent to"
+ names = sent_bugmail.sent
+%]
+
+[% PROCESS emails
+ description = "Excluding"
+ names = sent_bugmail.excluded
+%]
+</dl>
+
+[%############################################################################%]
+[%# Block for a set of email addresses #%]
+[%############################################################################%]
+
+[% BLOCK emails %]
+ <dt>[% description FILTER html %]:</dt>
+ <dd>
+ [% IF user.can_see_bug(mailing_bugid) %]
+ [% IF names.size > 0 %]
+ [%+ FOREACH name = names %]
+ <code>[% name FILTER html %]</code>[% ", " UNLESS loop.last() %]
+ [% END %]
+ [% ELSE %]
+ no one
+ [% END %]
+ [% ELSE %]
+ (list of e-mails not available)
+ [% END %]
+ </dd>
+[% END %]
diff --git a/template/en/default/bug/process/confirm-duplicate.html.tmpl b/template/en/default/bug/process/confirm-duplicate.html.tmpl
new file mode 100644
index 0000000..da1580e
--- /dev/null
+++ b/template/en/default/bug/process/confirm-duplicate.html.tmpl
@@ -0,0 +1,62 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # original_bug_id: number; the bug number for the bug
+ # against which a bug is being duped
+ # duplicate_bug_id: number; the bug number for the bug
+ # being duped
+ # cclist_accessible: boolean; whether or not users on the cc: list
+ # of the original bug can access that bug.
+ #%]
+
+[% PROCESS global/header.html.tmpl title="Duplicate Warning" %]
+[% orig_bug = "$terms.bug $original_bug_id"
+ FILTER bug_link(original_bug_id) %]
+
+<p>
+ When marking [% terms.abug %] as a duplicate, the reporter of the duplicate
+ is normally added to the CC list of the original. The permissions
+ on [% orig_bug FILTER none %] (the original) are currently set
+ such that the reporter would not normally be able to see it.
+</p>
+
+<p>
+ <b>Adding the reporter to the CC list of [% orig_bug FILTER none %]
+ [% IF cclist_accessible %]
+ will immediately
+ [% ELSE %]
+ might, in the future,
+ [% END %]
+ allow him/her access to view this [% terms.bug %].</b>
+ Do you wish to do this?
+</p>
+
+<form method="post" action="process_bug.cgi">
+
+[% PROCESS "global/hidden-fields.html.tmpl" exclude="^Bugzilla_(login|password)$" %]
+
+<p>
+ <input type="radio" name="confirm_add_duplicate" value="1">
+ Yes, add the reporter to CC list on [% orig_bug FILTER none %]
+</p>
+<p>
+ <input type="radio" name="confirm_add_duplicate" value="0" checked="checked">
+ No, do not add the reporter to CC list on [% orig_bug FILTER none %]
+</p>
+<p>
+ [% "Throw away my changes, and revisit $terms.bug $duplicate_bug_id"
+ FILTER bug_link(duplicate_bug_id) FILTER none %]
+</p>
+<p>
+ <input type="submit" id="process" value="Submit">
+</p>
+
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/bug/process/header.html.tmpl b/template/en/default/bug/process/header.html.tmpl
new file mode 100644
index 0000000..f7f61a7
--- /dev/null
+++ b/template/en/default/bug/process/header.html.tmpl
@@ -0,0 +1,32 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # As global/header.html.tmpl.
+ #%]
+
+[% USE Bugzilla %]
+
+[% PROCESS "bug/show-header.html.tmpl" %]
+
+[% IF title_tag == "bug_processed" %]
+ [% title = BLOCK %]
+ [% IF Bugzilla.cgi.param('id') %]
+ [% terms.Bug %] [%+ id FILTER html %]
+ [% ELSE %]
+ [% terms.Bugs %]
+ [% END %]
+ processed
+ [% END %]
+[% ELSIF title_tag == "mid_air" %]
+ [% title = "Mid-air collision!" %]
+[% END %]
+
+[% Hook.process('title') %]
+
+[% PROCESS global/header.html.tmpl %]
diff --git a/template/en/default/bug/process/midair.html.tmpl b/template/en/default/bug/process/midair.html.tmpl
new file mode 100644
index 0000000..684b996
--- /dev/null
+++ b/template/en/default/bug/process/midair.html.tmpl
@@ -0,0 +1,97 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # operations: array; bug activity since the user last displayed the bug form,
+ # used by bug/activity/table.html.tmpl to display recent changes that will
+ # be overwritten if the user submits these changes. See that template
+ # for further documentation.
+ # start_at: number; the comment at which show/comments.tmpl should begin
+ # displaying comments, either the index of the last comment (if the user
+ # entered a comment along with their change) or a number less than that
+ # (if they didn't), in which case no comments are displayed.
+ # comments: array; all the comments on the bug.
+ # bug: Bugzilla::Bug; the bug being changed.
+ #%]
+
+[%# The global Bugzilla->cgi object is used to obtain form variable values. %]
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+[% UNLESS header_done %]
+ [% PROCESS bug/process/header.html.tmpl %]
+[% END %]
+
+<h1>Mid-air collision detected!</h1>
+
+<p>
+ Someone else has made changes to
+ [%+ "$terms.bug $bug.id" FILTER bug_link(bug) FILTER none %]
+ at the same time you were trying to.
+ The changes made were:
+</p>
+
+<p>
+ [% PROCESS "bug/activity/table.html.tmpl" incomplete_data=0 %]
+</p>
+
+[% IF comments.size > start_at %]
+<p>
+ Added the comment(s):
+ <blockquote>
+ [% PROCESS "bug/comments.html.tmpl" %]
+ </blockquote>
+</p>
+[% END %]
+
+[% IF cgi.param("comment") %]
+<p>
+ Your comment was:<br>
+ <blockquote><pre class="bz_comment_text">
+ [% cgi.param("comment") FILTER html %]
+ </pre></blockquote>
+</p>
+[% END %]
+
+<p>
+You have the following choices:
+</p>
+
+<ul>
+ <li>
+ <form method="post" action="process_bug.cgi">
+ <input type="hidden" name="delta_ts"
+ value="[% bug.delta_ts FILTER html %]">
+ [% PROCESS "global/hidden-fields.html.tmpl"
+ exclude="^Bugzilla_login|Bugzilla_password|delta_ts$" %]
+ <input type="submit" id="process" value="Submit my changes anyway">
+ This will cause all of the above changes to be overwritten
+ [% ", except for the added comment(s)" IF comments.size > start_at %].
+ </form>
+ </li>
+ [% IF cgi.param("comment") %]
+ <li>
+ <form method="post" action="process_bug.cgi">
+ <input type="hidden" name="id" value="[% cgi.param("id") FILTER html %]">
+ <input type="hidden" name="delta_ts" value="[% bug.delta_ts FILTER html %]">
+ <input type="hidden" name="comment" value="[% cgi.param("comment") FILTER html %]">
+ <input type="hidden" name="comment_is_private"
+ value="[% cgi.param("comment_is_private") FILTER html %]">
+ <input type="hidden" name="longdesclength" value="[% bug.comments.size %]">
+ <input type="hidden" name="token" value="[% cgi.param("token") FILTER html %]">
+ <input type="submit" id="process_comment" value="Submit only my new comment">
+ </form>
+ </li>
+ [% END %]
+ <li>
+ Throw away my changes, and
+ [%+ "revisit $terms.bug $bug.id" FILTER bug_link(bug) FILTER none %]
+ </li>
+</ul>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/bug/process/results.html.tmpl b/template/en/default/bug/process/results.html.tmpl
new file mode 100644
index 0000000..cdebfed
--- /dev/null
+++ b/template/en/default/bug/process/results.html.tmpl
@@ -0,0 +1,45 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # id: number; the ID of the bug that was changed/checked.
+ #
+ # type: string; the type of change/check that was made: "bug" when a bug
+ # is changed, "dupe" when a duplication notation is added to a bug,
+ # and "dep" when a bug is checked for changes to its dependencies.
+ #%]
+
+[% UNLESS header_done %]
+ [% PROCESS bug/process/header.html.tmpl %]
+[% END %]
+
+[% DEFAULT type="bug" %]
+
+[% Link = BLOCK %][% "$terms.Bug $id" FILTER bug_link(id) %][% END %]
+[% link = BLOCK %][% "$terms.bug $id" FILTER bug_link(id) %][% END %]
+
+[%
+ title = {
+ 'bug' => "Changes submitted for $link" ,
+ 'dupe' => "Duplicate notation added to $link" ,
+ 'dep' => "Checking for dependency changes on $link" ,
+ 'created' => "$Link has been added to the database" ,
+ 'move' => "$Link has been moved to another database" ,
+ }
+%]
+
+[% Hook.process('title') %]
+
+<dl>
+ <dt>[% title.$type %]</dt>
+ <dd>
+ [% PROCESS "bug/process/bugmail.html.tmpl" mailing_bugid = id %]
+ [%# Links to more information about the changed bug. %]
+ [% Hook.process("links") %]
+ </dd>
+</dl>
diff --git a/template/en/default/bug/process/verify-new-product.html.tmpl b/template/en/default/bug/process/verify-new-product.html.tmpl
new file mode 100644
index 0000000..a1a9539
--- /dev/null
+++ b/template/en/default/bug/process/verify-new-product.html.tmpl
@@ -0,0 +1,232 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: object; the new product.
+ # versions: array; versions for the new product.
+ # components: array; components for the new product.
+ # milestones: array; milestones for the new product.
+ # defaults: hash; keys are names of fields, values are defaults for
+ # those fields
+ #
+ # verify_bug_groups: If groups need to be confirmed in addition to fields.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = 'Verify New Product Details...' %]
+
+<form action="process_bug.cgi" method="post">
+
+[% SET exclude_items = ['version', 'component', 'target_milestone'] %]
+[% IF verify_bug_groups %]
+ [% exclude_items.push('groups', 'defined_groups') %]
+[% END %]
+[% Hook.process('exclude') %]
+
+[% PROCESS "global/hidden-fields.html.tmpl"
+ exclude = '^' _ exclude_items.join('|') _ '$' %]
+
+<input type="hidden" name="confirm_product_change" value="1">
+
+[%# Verify the version, component, and target milestone fields. %]
+<h3>Verify Version, Component
+ [%- ", Target Milestone"
+ IF Param("usetargetmilestone")
+ && bug.check_can_change_field('target_milestone', 0, 1) %]</h3>
+
+<p>
+[% IF Param("usetargetmilestone")
+ && bug.check_can_change_field('target_milestone', 0, 1)
+%]
+ You are moving the [% terms.bug %](s) to the product
+ <b>[% product.name FILTER html %]</b>,
+ and the version, component, and/or target milestone fields are no longer
+ correct. Please set the correct version, component, and target milestone now:
+[% ELSE %]
+ You are moving the [% terms.bug %](s) to the product
+ <b>[% product.name FILTER html %]</b>,
+ and the version and component fields are no longer correct.
+ Please set the correct version and component now:
+[% END %]
+</p>
+
+<table>
+ <tr>
+ <td>
+ <b>Version:</b><br>
+ [% IF versions.size == 1 %]
+ [% SET default_version = versions.0 %]
+ [% ELSE %]
+ [% SET default_version = defaults.version %]
+ [% END %]
+ [% PROCESS "global/select-menu.html.tmpl"
+ name="version"
+ options=versions
+ default=default_version
+ size=10 %]
+ </td>
+ <td>
+ <b>Component:</b><br>
+ [% IF components.size == 1 %]
+ [% SET default_component = components.0 %]
+ [% ELSE %]
+ [% SET default_component = defaults.component %]
+ [% END %]
+ [% PROCESS "global/select-menu.html.tmpl"
+ name="component"
+ options=components
+ default=default_component
+ size=10 %]
+ </td>
+ [% IF Param("usetargetmilestone")
+ && bug.check_can_change_field('target_milestone', 0, 1)
+ %]
+ <td>
+ <b>Target Milestone:</b><br>
+ [% PROCESS "global/select-menu.html.tmpl"
+ name="target_milestone"
+ options=milestones
+ default=defaults.milestone
+ size=10 %]
+ </td>
+ [% END %]
+ [% Hook.process('field') %]
+ </tr>
+</table>
+
+[% IF verify_bug_groups %]
+ [% mandatory_groups = [] %]
+ [% optional_groups = [] %]
+
+ [% FOREACH gid = product.group_controls.keys %]
+ [% group = product.group_controls.$gid %]
+ [% NEXT UNLESS group.group.is_active %]
+
+ [% IF group.membercontrol == constants.CONTROLMAPMANDATORY
+ || (group.othercontrol == constants.CONTROLMAPMANDATORY && !user.in_group(group.group.name)) %]
+ [% mandatory_groups.push(group) %]
+ [% ELSIF (group.membercontrol != constants.CONTROLMAPNA && user.in_group(group.group.name))
+ || group.othercontrol != constants.CONTROLMAPNA %]
+ [% optional_groups.push(group) %]
+ [% END %]
+ [% END %]
+
+ [% IF old_groups.size || optional_groups.size || mandatory_groups.size %]
+ <h3>Verify [% terms.Bug %] Group</h3>
+ [% END %]
+
+ [% IF old_groups.size %]
+ <p>These groups are not legal for the '[% product.name FILTER html %]'
+ product or you are not allowed to restrict [% terms.bugs %] to these groups.
+ [%+ terms.Bugs %] will no longer be restricted to these groups and may become
+ public if no other group applies:<br>
+ [% FOREACH group = old_groups %]
+ <input type="checkbox" id="group_[% group.id FILTER html %]"
+ name="groups" disabled="disabled" value="[% group.name FILTER html %]">
+ <label for="group_[% group.id FILTER html %]">
+ [% group.name FILTER html %]: [% group.description FILTER html %]
+ </label>
+ <br>
+ [% END %]
+ </p>
+ [% END %]
+
+
+ [% IF optional_groups.size %]
+ <p>These groups are optional. You can decide to restrict [% terms.bugs %] to
+ one or more of the following groups:<br>
+ [% IF multiple_bugs %]
+ <script type="text/javascript">
+ function turn_off(myself, id) {
+ var other_checkbox = document.getElementById(id);
+ if (myself.checked && other_checkbox) {
+ other_checkbox.checked = false;
+ }
+ }
+ </script>
+
+ <table border="1">
+ <tr>
+ <th>Remove<br>[% terms.bugs %]<br>from this<br>group</th>
+ <th>Add<br>[% terms.bugs %]<br>to this<br>group</th>
+ <th>Group Name:</th>
+ </tr>
+
+ [% FOREACH group = optional_groups %]
+ <tr>
+ <td align="center">
+ <input type="checkbox" name="defined_groups"
+ id="defined_group_[% group.group.id FILTER html %]"
+ value="[% group.group.name FILTER html %]"
+ [% IF cgi.param("defined_groups").contains(group.group.name) %] checked="checked"[% END %]
+ onchange="turn_off(this, 'group_[% group.group.id FILTER html %]')">
+ </td>
+ <td align="center">
+ <input type="checkbox" name="groups"
+ id="group_[% group.group.id FILTER html %]"
+ value="[% group.group.name FILTER html %]"
+ [% IF cgi.param("groups").contains(group.group.name) %] checked="checked"[% END %]
+ onchange="turn_off(this, 'defined_group_[% group.group.id FILTER html %]')">
+ </td>
+ <td>
+ [% group.group.description FILTER html %]
+ </td>
+ </tr>
+ [% END %]
+ </table>
+ [% ELSE %]
+ [% FOREACH group = optional_groups %]
+ <input type="hidden" name="defined_groups"
+ value="[% group.group.name FILTER html %]">
+ <input type="checkbox" id="group_[% group.group.id FILTER html %]"
+ name="groups"
+ [% ' checked="checked"' IF ((group.membercontrol == constants.CONTROLMAPDEFAULT && user.in_group(group.group.name))
+ || (group.othercontrol == constants.CONTROLMAPDEFAULT && !user.in_group(group.group.name))
+ || cgi.param("groups").contains(group.group.name)) %]
+ value="[% group.group.name FILTER html %]">
+ <label for="group_[% group.group.id FILTER html %]">
+ [% group.group.name FILTER html %]: [% group.group.description FILTER html %]
+ </label>
+ <br>
+ [% END %]
+ [% END %]
+ </p>
+ [% END %]
+
+ [% IF mandatory_groups.size %]
+ <p>These groups are mandatory and [% terms.bugs %] will be automatically
+ restricted to these groups:<br>
+ [% FOREACH group = mandatory_groups %]
+ <input type="checkbox" id="group_[% group.group.id FILTER html %]"
+ checked="checked" disabled="disabled"
+ name="groups" value="[% group.group.name FILTER html %]">
+ <label for="group_[% group.group.id FILTER html %]">
+ [% group.group.name FILTER html %]: [% group.group.description FILTER html %]
+ </label>
+ <br>
+ [% END %]
+ </p>
+ [% END %]
+[% END %]
+
+<input type="submit" id="change_product" value="Commit">
+
+</form>
+<hr>
+
+[%# If 'id' is defined, then we are editing a single bug.
+ # Else we are editing several bugs at once. %]
+
+[% IF cgi.param('id') AND cgi.param('id').match('^\d+$') %]
+ [% id = cgi.param('id') %]
+ Cancel and Return to [% "$terms.bug $id" FILTER bug_link(id) FILTER none %]
+[% ELSE %]
+ Cancel and Return to <a href="buglist.cgi?regetlastlist=1">the last search results</a>
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/bug/show-header.html.tmpl b/template/en/default/bug/show-header.html.tmpl
new file mode 100644
index 0000000..a1eebe0
--- /dev/null
+++ b/template/en/default/bug/show-header.html.tmpl
@@ -0,0 +1,58 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# This template should be called with PROCESS before processing
+ # "global/header.html.tmpl" in any template that is going to load the
+ # bug form. It expects only a "bug" object, and can even manage to get
+ # along without that. Some of these variables are just defaults that will
+ # be overridden by the calling templates.
+ #%]
+
+[% filtered_desc = bug.short_desc FILTER html %]
+[% subheader = filtered_desc %]
+[% filtered_timestamp = bug.delta_ts FILTER time %]
+[% title = "$terms.Bug $bug.bug_id &ndash; $filtered_desc" %]
+[% yui = ['autocomplete', 'calendar'] %]
+[% javascript_urls = [ "js/util.js", "js/field.js" ] %]
+[% IF bug.defined %]
+ [% header = "$terms.Bug&nbsp;$bug.bug_id" %]
+ [% header_addl_info = "Last modified: $filtered_timestamp" %]
+ [% unfiltered_title = "$terms.Bug $bug.bug_id – $bug.short_desc" %]
+ [% javascript = BLOCK %]
+ if (history && history.replaceState) {
+ if(!document.location.href.match(/show_bug\.cgi/)) {
+ history.replaceState( null,
+ "[% unfiltered_title FILTER js %]",
+ "show_bug.cgi?id=[% bug.bug_id FILTER js %]" );
+ document.title = "[% unfiltered_title FILTER js %]";
+ }
+ if (document.location.href.match(/show_bug\.cgi\?.*list_id=/)) {
+ var href = document.location.href;
+ href = href.replace(/[\?&]+list_id=(\d+|cookie)/, '');
+ history.replaceState(null, "[% unfiltered_title FILTER js %]", href);
+ }
+ }
+ YAHOO.util.Event.onDOMReady(function() {
+ initDirtyFieldTracking();
+ });
+ [% javascript FILTER none %]
+ [% END %]
+[% END %]
+[% style_urls = [ "skins/standard/show_bug.css" ] %]
+[% doc_section = "bug_page.html" %]
+[% bodyclasses = ['bz_bug',
+ "bz_status_$bug.bug_status",
+ "bz_product_$bug.product",
+ "bz_component_$bug.component",
+ "bz_bug_$bug.bug_id",
+ ] %]
+[% FOREACH group = bug.groups_in %]
+ [% bodyclasses.push("bz_group_$group.name") %]
+[% END %]
+
+[% Hook.process('end') %]
diff --git a/template/en/default/bug/show-multiple.html.tmpl b/template/en/default/bug/show-multiple.html.tmpl
new file mode 100644
index 0000000..fb11bf0
--- /dev/null
+++ b/template/en/default/bug/show-multiple.html.tmpl
@@ -0,0 +1,366 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Full Text $terms.Bug Listing"
+ h1 = ""
+ style_urls = ["skins/standard/show_multiple.css",
+ "skins/standard/buglist.css"]
+ doc_section = "bug_page.html"
+%]
+[% PROCESS bug/time.html.tmpl %]
+[% IF bugs.first %]
+ [% ids = [] %]
+ [% FOREACH bug = bugs %]
+ [% PROCESS bug_display %]
+ [% ids.push(bug.bug_id) UNLESS bug.error %]
+ [% END %]
+ [% IF ids.size > 1 %]
+ <div class="bz_query_buttons">
+ <form method="post" action="buglist.cgi">
+ <input type="hidden" name="bug_id" value="[% ids.join(",") FILTER html %]">
+ <input type="submit" id="short_format" value="Short Format">
+ </form>
+ </div>
+ [% END %]
+[% ELSE %]
+ <p>
+ You'd have more luck if you gave me some [% terms.bug %] numbers.
+ </p>
+[% END %]
+
+
+[% PROCESS global/footer.html.tmpl %]
+
+
+[%###########################################################################%]
+[%# Block for an individual bug #%]
+[%###########################################################################%]
+
+[% BLOCK bug_display %]
+ <h1>
+ [% terms.Bug %]
+ <a href="show_bug.cgi?id=[% bug.bug_id FILTER html %]">[% bug.bug_id FILTER html %]</a>
+ [% IF bug.alias AND NOT bug.error %]
+ (<a href="show_bug.cgi?id=[% bug.alias FILTER uri %]">
+ [% bug.alias FILTER html %]</a>)
+ [% END %]
+ </h1>
+
+ <table class="bugfields">
+ [% IF bug.error %]
+ <tr>
+ <td class="error">
+ [% IF bug.error == "InvalidBugId" %]
+ '[%+ bug.bug_id FILTER html %]' is not a valid [% terms.bug %] number
+ nor a known [% terms.bug %] alias.
+ [% ELSIF bug.error == "NotPermitted" %]
+ You are not allowed to view this [% terms.bug %].
+ [% ELSIF bug.error == "NotFound" %]
+ This [% terms.bug %] cannot be found.
+ [% ELSE %]
+ [%+ bug.error FILTER html %]
+ [% END %]
+ </td>
+ </tr>
+ [% ELSE %]
+ [%# The rightcell block (also called by the row block) automatically shows
+ # the fields from rightcells %]
+ [% rightcells = ['reporter', 'assigned_to'] %]
+ [% IF Param('useqacontact') %]
+ [% rightcells.push('qa_contact') %]
+ [% END %]
+ [% rightcells.push('') %]
+ [% IF bug.cc.size %]
+ [% rightcells.push('cc') %]
+ [% END %]
+ [% IF bug.keywords %]
+ [% rightcells.push('keywords') %]
+ [% END %]
+
+ [%# Determine if the bug has a flag %]
+ [% FOREACH type = bug.flag_types %]
+ [% IF type.flags.size %]
+ [% rightcells.push('flags') %]
+ [% LAST %]
+ [% END %]
+ [% END %]
+
+ [% PROCESS row cell = "short_desc" fullrow = 1 %]
+
+ <tr>
+ <th>[% field_descs.product FILTER html %]:</th>
+ <td>
+ [% IF Param("useclassification") && bug.classification_id != 1 %]
+ [[% bug.classification FILTER html %]]&nbsp;
+ [% END %]
+ [% bug.product FILTER html %]
+ </td>
+
+ [% PROCESS rightcell %]
+ </tr>
+
+ [% PROCESS row cell = "component" %]
+
+ <tr>
+ <th>[% field_descs.bug_status FILTER html %]:</th>
+ <td>
+ [% display_value("bug_status", bug.bug_status) FILTER html %]
+ [%+ display_value("resolution", bug.resolution) FILTER html %]
+ </td>
+
+ [% PROCESS rightcell %]
+ </tr>
+
+ <tr>
+ <th>[% field_descs.bug_severity FILTER html %]:</th>
+ <td class="bz_[% bug.bug_severity FILTER css_class_quote -%]">
+ [% display_value("bug_severity", bug.bug_severity) FILTER html %]
+ </td>
+
+ [% PROCESS rightcell %]
+ </tr>
+
+ <tr>
+ <th>[% field_descs.priority FILTER html %]:</th>
+ <td class="bz_[% bug.priority FILTER css_class_quote -%]">
+ [% bug.priority FILTER html %]
+ </td>
+
+ [% PROCESS rightcell %]
+ </tr>
+
+ [% PROCESS row cell = "version" %]
+ [% PROCESS row cell = "target_milestone" IF Param('usetargetmilestone') %]
+ [% PROCESS row cell = "rep_platform" %]
+ [% PROCESS row cell = "op_sys" %]
+
+ [% IF bug.bug_file_loc %]
+ <tr>
+ <th>[% field_descs.bug_file_loc FILTER html %]:</th>
+ <td colspan="3">
+ [% IF is_safe_url(bug.bug_file_loc) %]
+ <a href="[% bug.bug_file_loc FILTER html %]">
+ [% bug.bug_file_loc FILTER html %]</a>
+ [% ELSE %]
+ [% bug.bug_file_loc FILTER html %]
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+
+ [% IF bug.see_also.size %]
+ <tr>
+ <th>[% field_descs.see_also FILTER html %]:</th>
+ <td colspan="3">
+ [% FOREACH see_also = bug.see_also %]
+ <a href="[% see_also.name FILTER html %]">[% see_also.name FILTER html %]</a>
+ [% "<br>" IF not loop.last() %]
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+
+ [% IF Param("usestatuswhiteboard") %]
+ [% PROCESS row cell = "status_whiteboard" fullrow = 1 %]
+ [% END %]
+
+ [% USE Bugzilla %]
+ [% field_counter = 0 %]
+ [% FOREACH field = Bugzilla.active_custom_fields %]
+ [% field_counter = field_counter + 1 %]
+ [%# Odd-numbered fields get an opening <tr> %]
+ [% '<tr>' IF field_counter % 2 %]
+ [% PROCESS bug/field.html.tmpl value=bug.${field.name} editable=0 %]
+ [%# Even-numbered fields get a closing <tr> %]
+ [% '</tr>' IF !(field_counter % 2) %]
+ [% IF extra_field_item %]
+ [% field_counter = field_counter + 1 %]
+ [% '<tr>' IF field_counter % 2 %]
+ <th>[% extra_field_item.header FILTER none %]</th>
+ <td>[% extra_field_item.data FILTER none %]</td>
+ [% '</tr>' IF !(field_counter % 2) %]
+ [% END %]
+ [% END %]
+ [%# And we have to finish the row if we ended on an odd number. %]
+ [% '<th></th><td></td></tr>' IF field_counter % 2 %]
+
+ [% IF (bug.dependson.size || bug.blocked.size) %]
+ [% PROCESS dependencies name = "dependson" %]
+ [% PROCESS dependencies name = "blocked" %]
+ [% END %]
+
+ [% IF user.is_timetracker %]
+ <tr>
+ <th>Time tracking:</th>
+ <td colspan="3">
+ <table class="timetracking">
+ <tr>
+ <th>[% field_descs.estimated_time FILTER html %]</th>
+ <th>[% field_descs.actual_time FILTER html %]</th>
+ <th>[% field_descs.work_time FILTER html %]</th>
+ <th>[% field_descs.remaining_time FILTER html %]</th>
+ <th>[% field_descs.percentage_complete FILTER html %]</th>
+ <th>Gain</th>
+ </tr>
+ <tr>
+ <td>
+ [% PROCESS formattimeunit time_unit = bug.estimated_time %]
+ </td>
+ <td>
+ [% PROCESS formattimeunit
+ time_unit=(bug.remaining_time + bug.actual_time) %]
+ </td>
+ <td>[% PROCESS formattimeunit time_unit = bug.actual_time %]</td>
+ <td>
+ [% PROCESS formattimeunit time_unit = bug.remaining_time %]
+ </td>
+ <td>
+ [% PROCESS calculatepercentage act = bug.actual_time
+ rem = bug.remaining_time %]
+ </td>
+ <td>
+ [% PROCESS formattimeunit
+ time_unit=bug.estimated_time -
+ (bug.actual_time + bug.remaining_time) %]
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ [% PROCESS row cell="deadline" %]
+ [% END %]
+
+ [% IF bug.attachments.size %]
+ <tr>
+ <th>Attachments:</th>
+ <td colspan="3">
+ [% IF bug.show_attachment_flags %]
+ <table>
+ <tr>
+ <th>Description</th>
+ <th>Flags</th>
+ </tr>
+ [% FOREACH attachment = bug.attachments %]
+ <tr>
+ <td>
+ <a href="attachment.cgi?id=[% attachment.id %]">
+ [% attachment.description FILTER html %]
+ </a>[% "<br>" IF not loop.last() %]
+ </td>
+ <td>
+ [% IF attachment.flags.size == 0 %]
+ <i>none</i>
+ [% ELSE %]
+ [% FOREACH flag = attachment.flags %]
+ [% flag.setter.nick FILTER html %]:
+ [%+ flag.type.name FILTER html FILTER no_break %][% flag.status %]
+ [% IF flag.status == "?" && flag.requestee %]
+ ([% flag.requestee.nick FILTER html %])
+ [% END %][% ", " IF not loop.last() %]
+ [% END %]
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+ </table>
+ [% ELSE %]
+ [% FOREACH attachment = bug.attachments %]
+ <a href="attachment.cgi?id=[% attachment.id %]">
+ [% attachment.description FILTER html %]
+ </a>[% "<br>" IF not loop.last() %]
+ [% END %]
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+ [% END %]
+
+ [% Hook.process("last_row", "bug/show-multiple.html.tmpl") %]
+
+ </table>
+
+
+ <br>
+
+ [% PROCESS bug/comments.html.tmpl
+ comments = bug.comments %]
+
+[% END %]
+
+
+[%###########################################################################%]
+[%# Block for standard table rows #%]
+[%###########################################################################%]
+
+[% BLOCK row %]
+ <tr>
+ <th>[% field_descs.${cell} FILTER html %]:</th>
+ <td[% " colspan=3" IF fullrow %]>[% display_value(cell, bug.${cell}) FILTER html %]</td>
+ [% PROCESS rightcell IF !fullrow %]
+ </tr>
+ [% fullrow = 0 %]
+[% END %]
+
+
+[%############################################################################%]
+[%# Block for dependencies #%]
+[%############################################################################%]
+
+[% BLOCK dependencies %]
+ <tr>
+ <th>[% terms.Bug %] [%+ field_descs.${name} FILTER html %]:</th>
+ <td>
+ [% FOREACH depbug = bug.${name} %]
+ [% depbug FILTER bug_link(depbug) FILTER none %][% ", " IF not loop.last() %]
+ [% END %]
+ </td>
+
+ [% PROCESS rightcell %]
+ </tr>
+[% END %]
+
+[%############################################################################%]
+[%# Block for cells shown right of the table #%]
+[%############################################################################%]
+
+[% BLOCK rightcell %]
+ [% IF rightcells %]
+ [% name = rightcells.shift %]
+ [% IF name == "cc" %]
+ <th class="rightcell">[% field_descs.cc FILTER html %]:</th>
+ <td>
+ [% FOREACH c = bug.cc %]
+ [% c FILTER email FILTER html %][% ", " IF not loop.last() %]
+ [% END %]
+ [% ELSIF name == "reporter" || name == "assigned_to"
+ || name == "qa_contact" %]
+ <th class="rightcell">[% field_descs.${name} FILTER html %]:</th>
+ <td>[% bug.${name}.identity FILTER email FILTER html %]</td>
+ [% ELSIF name == "flags" %]
+ <th class="rightcell">Flags:</th>
+ <td>
+ [% FOREACH type = bug.flag_types %]
+ [% FOREACH flag = type.flags %]
+ [% flag.setter.nick FILTER html %]:
+ [%+ flag.type.name FILTER html FILTER no_break %][% flag.status %]
+ [%+ IF flag.status == "?" && flag.requestee %]
+ ([% flag.requestee.nick FILTER html %])
+ [% END %]<br>
+ [% END %]
+ [% END %]
+ </td>
+ [% ELSIF name != "" %]
+ <th class="rightcell">[% field_descs.${name} FILTER html %]:</th>
+ <td>[% display_value(name, bug.${name}) FILTER html %]</td>
+ [% ELSE %]
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ [% END %]
+ [% END %]
+[% END %]
diff --git a/template/en/default/bug/show.html.tmpl b/template/en/default/bug/show.html.tmpl
new file mode 100644
index 0000000..b890511
--- /dev/null
+++ b/template/en/default/bug/show.html.tmpl
@@ -0,0 +1,36 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# This script/template only handles one bug #%]
+[% bug = bugs.0 %]
+
+[% IF !header_done %]
+ [% PROCESS "bug/show-header.html.tmpl" %]
+ [% PROCESS global/header.html.tmpl %]
+[% END %]
+
+[% IF nextbug %]
+ <hr>
+ <p>
+ The next [% terms.bug %] in your list is [% terms.bug %]
+ <a href="show_bug.cgi?id=[% bug.bug_id %]">[% bug.bug_id %]</a>:
+ </p>
+ <hr>
+[% END %]
+
+[% PROCESS bug/navigate.html.tmpl %]
+
+[% PROCESS bug/edit.html.tmpl %]
+
+<hr>
+
+[% PROCESS bug/navigate.html.tmpl bottom_navigator => 1%]
+
+<br>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/bug/show.xml.tmpl b/template/en/default/bug/show.xml.tmpl
new file mode 100644
index 0000000..1d376f8
--- /dev/null
+++ b/template/en/default/bug/show.xml.tmpl
@@ -0,0 +1,161 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[% PROCESS bug/time.html.tmpl %]
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+<?xml version="1.0" [% IF Param('utf8') %]encoding="UTF-8" [% END %]standalone="yes" ?>
+<!DOCTYPE bugzilla [% IF cgi.param('dtd') %][[% PROCESS pages/bugzilla.dtd.tmpl %]][% ELSE %]SYSTEM "[% urlbase FILTER xml %]page.cgi?id=bugzilla.dtd"[% END %]>
+
+<bugzilla version="[% constants.BUGZILLA_VERSION %]"
+ urlbase="[% urlbase FILTER xml %]"
+ [%# Note that the maintainer's email is not filtered,
+ # intentionally. Even logged-out users should be able
+ # to see that, since it will be in error messages anyway.
+ %]
+ maintainer="[% Param('maintainer') FILTER xml %]"
+[% IF user.id %]
+ exporter="[% user.email FILTER email FILTER xml %]"
+[% END %]
+>
+
+[% FOREACH bug = bugs %]
+ [% IF bug.error %]
+ <bug error="[% bug.error FILTER xml %]">
+ <bug_id>[% bug.bug_id FILTER xml %]</bug_id>
+ </bug>
+ [% ELSE %]
+ <bug>
+ [% FOREACH field = bug.fields %]
+ [% IF displayfields.$field %]
+ [%+ PROCESS bug_field %]
+ [% END %]
+ [% END %]
+
+ [%# This is here so automated clients can still use process_bug.cgi %]
+ [% IF displayfields.token && user.id %]
+ <token>[% issue_hash_token([bug.id, bug.delta_ts]) FILTER xml %]</token>
+ [% END %]
+
+ [%# Now handle 'special' fields #%]
+ [% IF displayfields.group %]
+ [% FOREACH g = bug.groups %]
+ [% NEXT UNLESS g.ison %]
+ <group id="[% g.bit FILTER xml %]">[% g.name FILTER xml %]</group>
+ [% END %]
+ [% END %]
+
+ [%# Bug Flags %]
+ [% PROCESS section_flags obj => bug %]
+
+ [% IF displayfields.long_desc %]
+ [% sort_order = user.settings.comment_sort_order.value %]
+ <comment_sort_order>[% sort_order FILTER xml %]</comment_sort_order>
+
+ [% FOREACH c = bug.comments %]
+ [% PROCESS a_comment %]
+ [% END %]
+ [% END %]
+
+ [% IF displayfields.attachment %]
+ [% FOREACH a = bug.attachments %]
+ [% NEXT IF a.isprivate && !user.is_insider %]
+ <attachment
+ isobsolete="[% a.isobsolete FILTER xml %]"
+ ispatch="[% a.ispatch FILTER xml %]"
+ isprivate="[% a.isprivate FILTER xml %]"
+ >
+ <attachid>[% a.id %]</attachid>
+ <date>[% a.attached FILTER time("%Y-%m-%d %T %z") FILTER xml %]</date>
+ <delta_ts>[% a.modification_time FILTER time("%Y-%m-%d %T %z") FILTER xml %]</delta_ts>
+ <desc>[% a.description FILTER xml %]</desc>
+ <filename>[% a.filename FILTER xml %]</filename>
+ <type>[% a.contenttype FILTER xml %]</type>
+ <size>[% a.datasize FILTER xml %]</size>
+ <attacher[% IF a.attacher.name != '' %] name="[% a.attacher.name FILTER xml %]"[% END -%]>
+ [% a.attacher.email FILTER email FILTER xml %]</attacher>
+ [%# This is here so automated clients can still use attachment.cgi %]
+ [% IF displayfields.token && user.id %]
+ <token>[% issue_hash_token([a.id, a.modification_time]) FILTER xml %]</token>
+ [% END %]
+ [% IF displayfields.attachmentdata %]
+ <data encoding="base64">[% a.data FILTER base64 %]</data>
+ [% END %]
+
+ [% PROCESS section_flags obj => a %]
+ </attachment>
+ [% END %]
+ [% END %]
+
+ [% Hook.process("bug_end") %]
+
+ </bug>
+ [% END %]
+[% END %]
+
+</bugzilla>
+
+[% BLOCK bug_field %]
+ [% field_values = bug.$field %]
+ [%# Work around TT bug https://rt.cpan.org/Public/Bug/Display.html?id=9802 %]
+ [% IF bug.$field.size == 1 %]
+ [% field_values = [bug.$field.first] %]
+ [% END %]
+
+ [% FOREACH val = field_values %]
+ [%# We need to handle some fields differently. This should become
+ # nicer once we have custfields, and a type attribute for the fields
+ #%]
+ [% name = '' %]
+ [% IF field == 'reporter' OR field == 'assigned_to' OR
+ field == 'qa_contact' %]
+ [% name = val.name %]
+ [% val = val.email FILTER email %]
+ [% ELSIF field == 'cc' %]
+ [% val = val FILTER email %]
+ [% ELSIF field == 'creation_ts' OR field == 'delta_ts' %]
+ [% val = val FILTER time("%Y-%m-%d %T %z") %]
+ [% ELSIF field == "see_also" %]
+ [% val = val.name %]
+ [% END %]
+ <[% field %][% IF name != '' %] name="[% name FILTER xml %]"[% END -%]>
+ [%- val FILTER xml %]</[% field %]>
+ [% END %]
+[% END %]
+
+[% BLOCK section_flags %]
+ [% RETURN UNLESS displayfields.flag %]
+
+ [% FOREACH flag = obj.flags %]
+ <flag name="[% flag.type.name FILTER xml %]"
+ id="[% flag.id FILTER xml %]"
+ type_id="[% flag.type_id FILTER xml %]"
+ status="[% flag.status FILTER xml %]"
+ setter="[% flag.setter.email FILTER email FILTER xml %]"
+ [% IF flag.status == "?" && flag.requestee %]
+ requestee="[% flag.requestee.email FILTER email FILTER xml %]"
+ [% END %]
+ />
+ [% END %]
+[% END %]
+
+[% BLOCK a_comment %]
+ [% RETURN IF c.is_private && !user.is_insider %]
+ <long_desc isprivate="[% c.is_private FILTER xml %]" >
+ <commentid>[% c.id FILTER xml %]</commentid>
+ <comment_count>[% c.count FILTER xml %]</comment_count>
+ [% IF c.is_about_attachment %]
+ <attachid>[% c.extra_data FILTER xml %]</attachid>
+ [% END %]
+ <who name="[% c.author.name FILTER xml %]">[% c.author.email FILTER email FILTER xml %]</who>
+ <bug_when>[% c.creation_ts FILTER time("%Y-%m-%d %T %z") FILTER xml %]</bug_when>
+ [% IF user.is_timetracker && (c.work_time - 0 != 0) %]
+ <work_time>[% PROCESS formattimeunit time_unit = c.work_time FILTER xml %]</work_time>
+ [% END %]
+ <thetext>[% c.body_full FILTER xml %]</thetext>
+ </long_desc>
+[% END %]
diff --git a/template/en/default/bug/summarize-time.html.tmpl b/template/en/default/bug/summarize-time.html.tmpl
new file mode 100644
index 0000000..932a6e3
--- /dev/null
+++ b/template/en/default/bug/summarize-time.html.tmpl
@@ -0,0 +1,341 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% title = "Time Summary " %]
+[% IF do_depends %]
+ [% title = title _ "for " %]
+ [% header = "$terms.Bug $ids.0" FILTER bug_link(ids.0) FILTER none %]
+ [% header = title _ header _ " (and $terms.bugs blocking it)" %]
+ [% title = title _ "$terms.Bug $ids.0" %]
+[% ELSE %]
+ [% title = title _ "($ids.size $terms.bugs selected)" %]
+ [% header = title %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ header = header
+ style_urls = ["skins/standard/summarize-time.css"]
+ doc_section = "timetracking.html"
+ yui = ['calendar']
+ javascript_urls = [ "js/util.js", "js/field.js" ]
+ %]
+
+[% INCLUDE query_form %]
+
+[% IF do_report %]
+
+ [% global.grand_total = 0 global.estimated = 0 global.remaining = 0 %]
+
+ [% FOREACH workdata = part_list %]
+ [%# parts contains date ranges (from, to). %]
+ [% part = parts.shift %]
+ <div align="right">
+ <h4 style="padding-right: 2em; margin: 0;">
+ [% IF part.0 or part.1 %]
+ [% part.0 OR "Up" FILTER html %] to [% part.1 OR "now" FILTER html %]
+ [% ELSE %]
+ Full summary (no period specified)
+ [% END %]
+ </h4>
+ </div>
+ [% IF group_by == "number" %]
+ [% INCLUDE number_report %]
+ [% ELSE %]
+ [% INCLUDE owner_report %]
+ [% END %]
+ [% END %]
+
+ [% IF detailed %]
+ <h4 style="margin: 0">
+ Total of [% global.remaining FILTER format("%.2f") %]h remains from
+ original estimate of [% global.estimated FILTER format("%.2f") %]h
+ [% IF global.deadline %]
+ (deadline [% global.deadline FILTER html %])
+ [% END %]
+ </h4>
+ [% END %]
+
+ [% IF monthly %]
+ <h4 style="margin: 0">Total of [% global.grand_total FILTER format("%.2f") %] hours worked</h4>
+ <hr noshade size="1">
+ [% END %]
+
+ [% IF null.size > 0 %]
+ [% INCLUDE inactive_report %]
+ <h4 style="margin: 0">Total of [% null.size %] inactive [% terms.bugs %]</h4>
+ [% END %]
+
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
+
+[%#
+ #
+ # Developer reporting
+ #
+ #%]
+
+[% BLOCK owner_report %]
+ [% global.total = 0 global.bug_count = {} global.owner_count = {} %]
+ <table cellpadding="4" cellspacing="0" width="90%" class="realitems owner">
+ [% FOREACH owner = workdata.keys.sort %]
+ [% INCLUDE do_one_owner owner=owner ownerdata=workdata.$owner
+ detailed=detailed %]
+ [% END %]
+
+ [% additional = "$global.owner_count.size developers @
+ $global.bug_count.size $terms.bugs" %]
+ [% INCLUDE section_total colspan=3 additional=additional %]
+ </table>
+[% END %]
+
+[% BLOCK do_one_owner %]
+ [% global.owner_count.$owner = 1 %]
+ <tr><td colspan="5" class="owner_header">
+ <b>[% owner FILTER html %]</b>
+ </td></tr>
+ [% col = 0 subtotal = 0%]
+ [% FOREACH bugdata=ownerdata.nsort("bug_id") %]
+ [% bug_id = bugdata.bug_id %]
+ [% INCLUDE calc_bug_total id=bug_id %]
+ [% global.bug_count.$bug_id = 1 %]
+ [% IF detailed %]
+ [% INCLUDE bug_header cid=col id=bug_id bugdata=bugdata extra=1 %]
+ [% col = col + 1 %]
+ [% END %]
+ [% subtotal = subtotal + bugdata.total_time %]
+ [% END %]
+ <tr>
+ <td colspan="4" align="right"><b>Total</b>:</td>
+ <td align="right" class="subtotal" width="100">
+ <b>[% subtotal FILTER format("%.2f") %]</b></td>
+ [% global.total = global.total + subtotal %]
+ </tr>
+[% END %]
+
+[%#
+ #
+ # Bug Number reporting
+ #
+ #%]
+
+[% BLOCK number_report %]
+ [% global.total = 0 global.owner_count = {} global.bug_count = {} %]
+
+ <table cellpadding="4" cellspacing="0" width="90%" class="realitems number">
+ [% FOREACH bug = workdata.keys.nsort %]
+ [% INCLUDE do_one_bug id=bug bugdata=workdata.$bug
+ detailed=detailed %]
+ [% END %]
+
+ [% additional = "$global.bug_count.size $terms.bugs &
+ $global.owner_count.size developers" %]
+ [% INCLUDE section_total additional=additional colspan=2 %]
+ </table>
+[% END %]
+
+[% BLOCK do_one_bug %]
+ [% subtotal = 0.00 cid = 0 %]
+ [% INCLUDE calc_bug_total id=id %]
+ [% global.bug_count.$id = 1 %]
+ [% INCLUDE bug_header id=id %]
+
+ [% FOREACH owner = bugdata.sort("login_name") %]
+ [% work_time = owner.total_time %]
+ [% subtotal = subtotal + work_time %]
+ [% login_name = owner.login_name %]
+ [% global.owner_count.$login_name = 1 %]
+ [% IF detailed %]
+ [% cid = cid + 1 %]
+ <tr class="owner_header[% 2 FILTER none IF cid % 2 %]">
+ <td>&nbsp;</td>
+ <td colspan="2"><b>[% login_name FILTER html %]</b></td>
+ <td align="right">
+ [% work_time FILTER format("%.2f") %]</td>
+ </tr>
+ [% END %]
+ [% END %]
+ <tr>
+ <td colspan="2">&nbsp;</td>
+ <td align="right">
+ <b>Total</b>:
+ </td>
+ <td align="right" class="subtotal" width="100">
+ <b>[% subtotal FILTER format("%.2f") %]</b>
+ </td>
+ </tr>
+ [% global.total = global.total + subtotal %]
+[% END %]
+
+[% BLOCK bug_header %]
+ <tr class="bug_header[% '2' IF cid % 2 %]">
+ <td width="80" valign="top">
+ <b>[% "$terms.Bug $id" FILTER bug_link(id) FILTER none %]</b>
+ </td>
+ <td width="100"><b>[% display_value("bug_status", bugs.$id.bug_status) FILTER html %]</b></td>
+ <td colspan="2">[% bugs.$id.short_desc FILTER html %]</td>
+ [% IF extra %]
+ <td align="right" valign="top">[% bugdata.total_time FILTER html %]</td>
+ [% END %]
+ </tr>
+ [% IF detailed %]
+ <tr class="bug_header[% '2' IF cid % 2 %]">
+ <td>&nbsp;</td>
+ <td colspan="3">
+ <table width="100%" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="33%">
+ Estimated: [% bugs.$id.estimated_time FILTER format("%.2f") %]h
+ </td>
+ <td width="33%">
+ Remaining: [% bugs.$id.remaining_time FILTER format("%.2f") %]h
+ </td>
+ <td width="33%">
+ Deadline: [% bugs.$id.deadline || "<b>Not set</b>" %]
+ </td>
+ </tr>
+ </table>
+ </td>
+ [% IF extra %]
+ <td>&nbsp;</td>
+ [% END %]
+ </tr>
+ [% END %]
+[% END %]
+
+[% BLOCK calc_bug_total %]
+ [% IF !global.bug_count.$id %]
+ [% global.estimated = global.estimated + bugs.$id.estimated_time %]
+ [% global.remaining = global.remaining + bugs.$id.remaining_time %]
+ [% IF !global.deadline || bugs.$id.deadline &&
+ global.deadline.replace("-", "") < bugs.$id.deadline.replace("-", "") %]
+ [% SET global.deadline = bugs.$id.deadline %]
+ [% END %]
+ [% END %]
+[% END %]
+
+[% BLOCK inactive_report %]
+ <h3>Inactive [% terms.bugs %]</h3>
+ <table cellpadding="4" cellspacing="0" width="90%" class="zeroitems">
+ [% cid = 0 %]
+ [% FOREACH bug_id = null.nsort %]
+ [% INCLUDE bug_header id=bug_id cid=cid %]
+ [% cid = cid + 1 %]
+ [% END %]
+ </table>
+[% END %]
+
+
+[% BLOCK section_total %]
+ [% IF global.total > 0 %]
+ <tr class="section_total">
+ <td><b>Totals</b></td>
+ <td colspan="[% colspan FILTER html %]" align="right"><b>[% additional FILTER html %]</b></td>
+ <td align="right"><b>[% global.total FILTER format("%.2f") %]</b></td>
+ </tr>
+ [% ELSE %]
+ <tr>
+ <td>No time allocated during the specified period.</td>
+ </tr>
+ [% END %]
+ [% global.grand_total = global.grand_total + global.total %]
+[% END %]
+
+[%#
+ #
+ # The query form
+ #
+ #%]
+
+[% BLOCK query_form %]
+<hr noshade size=1>
+<form method="post" name="summary" style="display: inline" action="summarize_time.cgi">
+<input type="hidden" name="do_depends" value="[% do_depends FILTER html %]">
+<input type="hidden" name="id" value="[% ids.join(",") FILTER html %]">
+<input type="hidden" name="do_report" value="1">
+
+[% IF warn_swap_dates %]
+ <h4 style="border: 1px solid red; margin: 1em; padding: 0.5em">The
+ end date specified occurs before the start date, which doesn't
+ make sense; the dates below have therefore been swapped.</h4>
+[% END %]
+
+<table>
+<tr>
+<td align="right">
+ <b><label accesskey="s"
+ for="start_date">Period <u>s</u>tarting</label></b>:
+</td><td colspan="3">
+ <input type="text" id="start_date" name="start_date" size="11"
+ align="right" value="[% start_date FILTER html %]" maxlength="10"
+ onchange="updateCalendarFromField(this)">
+ <button type="button" class="calendar_button"
+ id="button_calendar_start_date"
+ onclick="showCalendar('start_date')"><span>Calendar</span>
+ </button>
+ <div id="con_calendar_start_date"></div>
+ &nbsp;
+ <b>and <label accesskey="e" for="end_date"><u>e</u>nding</label></b>:
+ <input type="text" name="end_date" size="11" id="end_date"
+ align="right" value ="[% end_date FILTER html %]" maxlength="10"
+ onchange="updateCalendarFromField(this)">
+ <button type="button" class="calendar_button"
+ id="button_calendar_end_date"
+ onclick="showCalendar('end_date')"><span>Calendar</span>
+ </button>
+ <div id="con_calendar_end_date"></div>
+</td><td align="right">
+ <input type="submit" id="summarize" value="Summarize">
+</td></tr>
+<tr>
+<td>&nbsp;</td><td colspan="4">
+ <small>(Dates are optional, and in YYYY-MM-DD format)</small>
+</td>
+<tr><td align="right">
+ <b>Group by</b>:
+</td><td colspan="2">
+ <input type="radio" name="group_by" id="number" value="number" [%+
+ 'checked="checked"' IF group_by == "number"
+ %]><label
+ for="number" accesskey="n">[% terms.Bug %] <u>N</u>umber</label>
+ <input type="radio" name="group_by" id="owner" value="owner" [%+
+ 'checked="checked"' IF group_by == "owner"
+ %]><label
+ for="owner" accesskey="d"><u>D</u>eveloper</label>
+</td><td colspan="2">
+ <label for="ctype"><b>Format</b></label>: <select name="ctype" id="ctype">
+ <option value="html">HTML Report</option>
+ </select>
+</td></tr><tr>
+<td>&nbsp;</td><td colspan="4">
+ <input type="checkbox" name="monthly" [% 'checked="checked"' IF
+ monthly %] id="monthly">
+ <label for="monthly" accesskey="m">Split by <u>m</u>onth</label>
+ [%# XXX: allow splitting by other intervals %]
+ &nbsp;
+ <input type="checkbox" name="detailed" [% 'checked="checked"' IF
+ detailed %] id="detailed">
+ <label for="detailed" accesskey="t">De<u>t</u>ailed summaries</label>
+ &nbsp;
+ <input type="checkbox" name="inactive" [% 'checked="checked"' IF
+ inactive %] id="inactive">
+ <label for="inactive" accesskey="i">Also show <u>i</u>nactive
+ [%+ terms.bugs %]</label>
+</td>
+</tr></table>
+
+</form>
+<script type="text/javascript">
+ <!--
+ [%+ PROCESS "global/calendar.js.tmpl" id = 'start_date' %]
+ [% PROCESS "global/calendar.js.tmpl" id = 'end_date' %]
+ document.forms['summary'].start_date.focus();
+ //--></script>
+<hr noshade size=1>
+[% END %]
diff --git a/template/en/default/bug/time.html.tmpl b/template/en/default/bug/time.html.tmpl
new file mode 100644
index 0000000..370aad6
--- /dev/null
+++ b/template/en/default/bug/time.html.tmpl
@@ -0,0 +1,34 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% BLOCK formattimeunit %]
+ [%# INTERFACE:
+ # time_unit: the number converting, converts to 2 decimal places
+ # unless the last character is a 0, then it truncates to
+ # 1 decimal place
+ #%]
+ [% time_unit = time_unit FILTER format('%.2f') %]
+ [% IF time_unit.match('0\Z') %]
+ [% time_unit FILTER format('%.1f') %]
+ [% ELSE %]
+ [% time_unit FILTER format('%.2f') %]
+ [% END %]
+[% END %]
+
+[% BLOCK calculatepercentage %]
+ [%# INTERFACE:
+ # act: actual time
+ # rem: remaining time
+ # %]
+ [% IF (act + rem) > 0 %]
+ [% (act / (act + rem)) * 100
+ FILTER format("%d") %]
+ [% ELSE %]
+ 0
+ [% END %]
+[% END %]
diff --git a/template/en/default/config.js.tmpl b/template/en/default/config.js.tmpl
new file mode 100644
index 0000000..0399f8b
--- /dev/null
+++ b/template/en/default/config.js.tmpl
@@ -0,0 +1,137 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+//
+// This file contains installation specific values for third-party clients.
+//
+// Note: this interface is experimental and under development.
+// We may and probably will make breaking changes to it in the future.
+
+// the global bugzilla url
+var installation = {
+ base_url : '[% urlbase FILTER js %]',
+ install_version : '[% constants.BUGZILLA_VERSION FILTER js %]',
+ maintainer : '[% Param('maintainer') FILTER js %]'
+};
+
+
+// Status and Resolution
+// =====================
+var status = [ [% FOREACH x = status %]'[% x FILTER js %]', [% END %] ];
+var status_open = [ [% FOREACH x = open_status %]'[% x FILTER js %]', [% END %] ];
+var status_closed = [ [% FOREACH x = closed_status %]'[% x FILTER js %]', [% END %] ];
+var resolution = [ [% FOREACH x = resolution %]'[% x FILTER js %]', [% END %] ];
+
+
+// Keywords
+// ========
+
+var keyword = [ [% FOREACH k = keywords %]'[% k.name FILTER js %]', [% END %] ];
+var keyword_descs = [
+[% FOREACH k = keywords %]
+ {
+ name: '[% k.name FILTER js %]',
+ description: '[% k.description FILTER js %]',
+ },
+[% END %]
+];
+
+// Platforms
+// =========
+
+var platform = [ [% FOREACH x = platform %]'[% x FILTER js %]', [% END %] ];
+
+
+// Severities
+// ==========
+
+var severity = [ [% FOREACH x = severity %]'[% x FILTER js %]', [% END %] ];
+
+
+// Custom Fields
+// =============
+
+[% FOREACH cf = custom_fields %]
+var [% cf.name FILTER js %] = [ [% FOREACH x = cf.legal_values %]'[% x.name FILTER js %]', [% END %] ];
+[% END %]
+
+
+// Products and Components
+// =======================
+//
+// It is not necessary to list all products and components here.
+// Instead, you can define a "blacklist" for some commonly used words
+// or word fragments that occur in a product or component name
+// but should _not_ trigger product/component search.
+
+
+// A list of all products and their components, versions, and target milestones:
+
+var component = new Object();
+var version = new Object();
+var target_milestone = new Object();
+
+[% FOREACH p = products %]
+ component['[% p.name FILTER js %]'] = [ [% FOREACH x = p.components %]'[% x.name FILTER js %]', [% END %] ];
+ version['[% p.name FILTER js %]'] = [ [% FOREACH x = p.versions %]'[% x.name FILTER js %]', [% END %] ];
+ target_milestone['[% p.name FILTER js %]'] = [ [% FOREACH x = p.milestones %]'[% x.name FILTER js %]', [% END %] ];
+[% END %]
+
+// Product and Component Exceptions
+// ================================
+//
+// A blacklist for some commonly used words or word fragments
+// that occur in a product or component name but should *not*
+// trigger product/component search in QuickSearch.
+
+var product_exceptions = new Array(
+ // Example:
+ //"row" // [Browser]
+ // // ^^^
+ //,"new" // [MailNews]
+ // // ^^^
+);
+
+var component_exceptions = new Array(
+ // Example:
+ //"hang" // [mozilla.org] Bugzilla: Component/Keyword Changes
+ // // ^^^^
+);
+
+// Queryable Fields
+// ================
+[% PROCESS "global/field-descs.none.tmpl" %]
+var field = [
+[% FOREACH x = field %]
+ { name: '[% x.name FILTER js %]',
+ description: '[% (field_descs.${x.name} OR x.description) FILTER js %]',
+ [%-# These values are meaningful for custom fields only. %]
+ [% IF x.custom %]
+ type: '[% x.type FILTER js %]',
+ type_desc: '[% field_types.${x.type} FILTER js %]',
+ enter_bug: '[% x.enter_bug FILTER js %]',
+ [% END %]
+ },
+[% END %]
+];
+
+// Deprecated Variables
+// ====================
+//
+// Other names for various variables. These are deprecated
+// and could go away at any time. Use them at your own risk!
+
+var bugzilla = installation.base_url;
+var statuses = status;
+var statuses_resolved = status_closed;
+var resolutions = resolution;
+var keywords = keyword;
+var platforms = platform;
+var severities = severity;
+var cpts = component;
+var vers = version;
+var tms = target_milestone;
diff --git a/template/en/default/config.rdf.tmpl b/template/en/default/config.rdf.tmpl
new file mode 100644
index 0000000..b14d0d0
--- /dev/null
+++ b/template/en/default/config.rdf.tmpl
@@ -0,0 +1,288 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# The url to the installation is going to be displayed many times.
+ # So we cache it here for better performance.
+ %]
+[% escaped_urlbase = BLOCK %][% urlbase FILTER xml %][% END %]
+<?xml version="1.0"[% IF Param('utf8') %] encoding="UTF-8"[% END %]?>
+<!-- Note: this interface is experimental and under development.
+ - We may and probably will make breaking changes to it in the future. -->
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:bz="http://www.bugzilla.org/rdf#">
+
+<bz:installation rdf:about="[% escaped_urlbase %]">
+ <bz:install_version>[% constants.BUGZILLA_VERSION FILTER html %]</bz:install_version>
+ <bz:maintainer>[% Param('maintainer') FILTER html %]</bz:maintainer>
+
+ <bz:status>
+ <Seq>
+ [% FOREACH item = status %]
+ <li>[% item FILTER html %]</li>
+ [% END %]
+ </Seq>
+ </bz:status>
+
+ <bz:status_open>
+ <Seq>
+ [% FOREACH item = open_status %]
+ <li>[% item FILTER html %]</li>
+ [% END %]
+ </Seq>
+ </bz:status_open>
+
+ <bz:status_closed>
+ <Seq>
+ [% FOREACH item = closed_status %]
+ <li>[% item FILTER html %]</li>
+ [% END %]
+ </Seq>
+ </bz:status_closed>
+
+ <bz:resolution>
+ <Seq>
+ [% FOREACH item = resolution %]
+ <li>[% item FILTER html %]</li>
+ [% END %]
+ </Seq>
+ </bz:resolution>
+
+ <bz:keywords>
+ <Seq>
+ [% FOREACH keyword = keywords %]
+ <li>
+ <bz:keyword rdf:about="[% escaped_urlbase %]keyword.cgi?name=[% keyword.name FILTER uri %]">
+ <bz:name>[% keyword.name FILTER html %]</bz:name>
+ <bz:description>[% keyword.description FILTER html %]</bz:description>
+ </bz:keyword>
+ </li>
+ [% END %]
+ </Seq>
+ </bz:keywords>
+
+ <bz:platform>
+ <Seq>
+ [% FOREACH item = platform %]
+ <li>[% item FILTER html %]</li>
+ [% END %]
+ </Seq>
+ </bz:platform>
+
+ <bz:op_sys>
+ <Seq>
+ [% FOREACH item = op_sys %]
+ <li>[% item FILTER html %]</li>
+ [% END %]
+ </Seq>
+ </bz:op_sys>
+
+ <bz:priority>
+ <Seq>
+ [% FOREACH item = priority %]
+ <li>[% item FILTER html %]</li>
+ [% END %]
+ </Seq>
+ </bz:priority>
+
+ <bz:severity>
+ <Seq>
+ [% FOREACH item = severity %]
+ <li>[% item FILTER html %]</li>
+ [% END %]
+ </Seq>
+ </bz:severity>
+
+[% FOREACH cf = custom_fields %]
+ <bz:[% cf.name FILTER html %]>
+ <Seq>
+ [% FOREACH item = cf.legal_values %]
+ <li>[% item.name FILTER html %]</li>
+ [% END %]
+ </Seq>
+ </bz:[% cf.name FILTER html %]>
+
+[% END %]
+
+[% IF Param('useclassification') %]
+ <bz:classifications>
+ <Seq>
+ [% FOREACH classification = classifications %]
+ <li>
+ <bz:classification rdf:about="[% escaped_urlbase %]classification.cgi?name=
+ [% classification.name FILTER uri %]">
+ <bz:name>[% classification.name FILTER html %]</bz:name>
+ <bz:description>[% classification.description FILTER html %]</bz:description>
+ <bz:sortkey>[% classification.sortkey FILTER html %]</bz:sortkey>
+ </bz:classification>
+ </li>
+ [% END %]
+ </Seq>
+ </bz:classifications>
+[% END %]
+
+ <bz:products>
+ <Seq>
+ [% FOREACH product = products %]
+ <li>
+ <bz:product rdf:about="[% escaped_urlbase %]product.cgi?name=[% product.name FILTER uri %]">
+ <bz:name>[% product.name FILTER html %]</bz:name>
+ <bz:allows_unconfirmed>[% product.allows_unconfirmed FILTER html %]</bz:allows_unconfirmed>
+ [% IF Param('useclassification') %]
+ <bz:classification>[% class_names.${product.classification_id}.name FILTER html %]</bz:classification>
+ [% END %]
+ <bz:components>
+ <Seq>
+ [% FOREACH component = product.components %]
+ <li resource="[% escaped_urlbase %]component.cgi?name=[% component.name FILTER uri
+ %]&amp;product=[% product.name FILTER uri %]"/>
+ [% END %]
+ </Seq>
+ </bz:components>
+
+ <bz:versions>
+ <Seq>
+ [% FOREACH version = product.versions %]
+ <li resource="[% escaped_urlbase %]version.cgi?name=[% version.name FILTER uri
+ %]&amp;product=[% product.name FILTER uri %]"/>
+ [% END %]
+ </Seq>
+ </bz:versions>
+
+ [% IF Param('usetargetmilestone') %]
+ <bz:target_milestones>
+ <Seq>
+ [% FOREACH milestone = product.milestones %]
+ <li resource="[% escaped_urlbase %]milestone.cgi?name=[% milestone.name FILTER uri
+ %]&amp;product=[% product.name FILTER uri %]"/>
+ [% END %]
+ </Seq>
+ </bz:target_milestones>
+ [% END %]
+
+ </bz:product>
+ </li>
+ [% END %]
+ </Seq>
+ </bz:products>
+
+ [% all_visible_flag_types = {} %]
+ <bz:components>
+ <Seq>
+ [% FOREACH product = products %]
+ [% FOREACH component = product.components %]
+ <li>
+ <bz:component rdf:about="[% escaped_urlbase %]component.cgi?name=[% component.name FILTER uri
+ %]&amp;product=[% product.name FILTER uri %]">
+ <bz:name>[% component.name FILTER html %]</bz:name>
+ <bz:is_active>[% component.is_active FILTER html %]</bz:is_active>
+ [% IF show_flags %]
+ <bz:flag_types>
+ <Seq>
+ [% flag_types = component.flag_types.bug.merge(component.flag_types.attachment) %]
+ [% FOREACH flag_type = flag_types %]
+ [% NEXT UNLESS flag_type.is_active %]
+ [% all_visible_flag_types.${flag_type.id} = flag_type %]
+ <li resource="[% escaped_urlbase %]flag.cgi?id=[% flag_type.id FILTER uri
+ %]&amp;name=[% flag_type.name FILTER uri %]" />
+ [% END %]
+ </Seq>
+ </bz:flag_types>
+ [% END %]
+ </bz:component>
+ </li>
+ [% END %]
+ [% END %]
+ </Seq>
+ </bz:components>
+
+ <bz:versions>
+ <Seq>
+ [% FOREACH product = products %]
+ [% FOREACH version = product.versions %]
+ <li>
+ <bz:version rdf:about="[% escaped_urlbase %]version.cgi?name=[% version.name FILTER uri
+ %]&amp;product=[% product.name FILTER uri %]">
+ <bz:name>[% version.name FILTER html %]</bz:name>
+ <bz:is_active>[% version.is_active FILTER html %]</bz:is_active>
+ </bz:version>
+ </li>
+ [% END %]
+ [% END %]
+ </Seq>
+ </bz:versions>
+
+ [% IF Param('usetargetmilestone') %]
+ <bz:target_milestones>
+ <Seq>
+ [% FOREACH product = products %]
+ [% FOREACH milestone = product.milestones %]
+ <li>
+ <bz:target_milestone rdf:about="[% escaped_urlbase %]milestone.cgi?name=[% milestone.name FILTER uri
+ %]&amp;product=[% product.name FILTER uri %]">
+ <bz:name>[% milestone.name FILTER html %]</bz:name>
+ <bz:is_active>[% milestone.is_active FILTER html %]</bz:is_active>
+ </bz:target_milestone>
+ </li>
+ [% END %]
+ [% END %]
+ </Seq>
+ </bz:target_milestones>
+ [% END %]
+
+ [% IF show_flags %]
+ <bz:flag_types>
+ <Seq>
+ [% FOREACH flag_type = all_visible_flag_types.values.sort('name') %]
+ <li>
+ <bz:flag_type rdf:about="[% escaped_urlbase %]flag.cgi?id=[% flag_type.id FILTER uri
+ %]&amp;name=[% flag_type.name FILTER uri %]">
+ <bz:id>[% flag_type.id FILTER html %]</bz:id>
+ <bz:name>[% flag_type.name FILTER html %]</bz:name>
+ <bz:description>[% flag_type.description FILTER html %]</bz:description>
+ <bz:type>[% flag_type.target_type FILTER html %]</bz:type>
+ <bz:requestable>[% flag_type.is_requestable FILTER html %]</bz:requestable>
+ <bz:specifically_requestable>[% flag_type.is_requesteeble FILTER html %]</bz:specifically_requestable>
+ <bz:multiplicable>[% flag_type.is_multiplicable FILTER html %]</bz:multiplicable>
+ [% IF user.in_group("editcomponents") %]
+ <bz:grant_group>[% flag_type.grant_group.name FILTER html %]</bz:grant_group>
+ <bz:request_group>[% flag_type.request_group.name FILTER html %]</bz:request_group>
+ [% END %]
+ </bz:flag_type>
+ </li>
+ [% END %]
+ </Seq>
+ </bz:flag_types>
+ [% END %]
+
+ <bz:fields>
+ <Seq>
+ [% PROCESS "global/field-descs.none.tmpl" %]
+ [% FOREACH item = field %]
+ <li>
+ <bz:field rdf:about="[% escaped_urlbase %]field.cgi?name=[% item.name FILTER uri %]">
+ <bz:name>[% item.name FILTER html %]</bz:name>
+ <bz:description>[% (field_descs.${item.name} OR item.description) FILTER html %]</bz:description>
+ [%-# These values are meaningful for custom fields only. %]
+ [% IF item.custom %]
+ <bz:type>[% item.type FILTER html %]</bz:type>
+ <bz:type_desc>[% field_types.${item.type} FILTER html %]</bz:type_desc>
+ <bz:enter_bug>[% item.enter_bug FILTER html %]</bz:enter_bug>
+ [% END %]
+ [% IF item.is_active.defined %]
+ <bz:is_active>[% item.is_active FILTER html %]</bz:is_active>
+ [% END %]
+ </bz:field>
+ </li>
+ [% END %]
+ </Seq>
+ </bz:fields>
+</bz:installation>
+
+</RDF>
diff --git a/template/en/default/email/bugmail-common.txt.tmpl b/template/en/default/email/bugmail-common.txt.tmpl
new file mode 100644
index 0000000..5d35359
--- /dev/null
+++ b/template/en/default/email/bugmail-common.txt.tmpl
@@ -0,0 +1,25 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% field_label = field_descs.${change.field_name} %]
+[% old_value = display_value(change.field_name, change.old) %]
+[% new_value = display_value(change.field_name, change.new) %]
+
+[% IF change.field_name == "estimated_time" || change.field_name == "remaining_time" %]
+ [% old_value = old_value FILTER format('%.2f') %]
+ [% new_value = new_value FILTER format('%.2f') %]
+[% END %]
+
+[% IF change.attach_id %]
+ [% field_label = field_label.replace('^(Attachment )?', "Attachment #${change.attach_id} ") %]
+[% END %]
+
+[% IF change.field_name == 'longdescs.isprivate' %]
+ [% field_label = field_label.replace('^(Comment )?', "Comment #${change.num} ") %]
+[% END %]
+
diff --git a/template/en/default/email/bugmail-header.txt.tmpl b/template/en/default/email/bugmail-header.txt.tmpl
new file mode 100644
index 0000000..c754f6a
--- /dev/null
+++ b/template/en/default/email/bugmail-header.txt.tmpl
@@ -0,0 +1,36 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS "global/reason-descs.none.tmpl" %]
+[% isnew = bug.lastdiffed ? 0 : 1 %]
+[% show_new = isnew
+ && (to_user.settings.bugmail_new_prefix.value == 'on') %]
+
+From: [% Param('mailfrom') %]
+To: [% to_user.email %]
+Subject: [[% terms.Bug %] [%+ bug.id %]] [% 'New: ' IF show_new %][%+ bug.short_desc %]
+Date: [% date %]
+X-Bugzilla-Reason: [% reasonsheader %]
+X-Bugzilla-Type: [% isnew ? 'new' : 'changed' %]
+X-Bugzilla-Watch-Reason: [% reasonswatchheader %]
+[% IF Param('useclassification') %]
+X-Bugzilla-Classification: [% bug.classification %]
+[% END %]
+X-Bugzilla-Product: [% bug.product %]
+X-Bugzilla-Component: [% bug.component %]
+X-Bugzilla-Version: [% bug.version %]
+X-Bugzilla-Keywords: [% bug.keywords %]
+X-Bugzilla-Severity: [% bug.bug_severity %]
+X-Bugzilla-Who: [% changer.login %]
+X-Bugzilla-Status: [% bug.bug_status %]
+X-Bugzilla-Priority: [% bug.priority %]
+X-Bugzilla-Assigned-To: [% bug.assigned_to.login %]
+X-Bugzilla-Target-Milestone: [% bug.target_milestone %]
+X-Bugzilla-Flags:[% FOREACH flag = bug.flags %] [%+ flag.name %][% flag.status %][% END %]
+X-Bugzilla-Changed-Fields: [% changedfields.join(" ") %]
+[%+ threadingmarker %]
diff --git a/template/en/default/email/bugmail.html.tmpl b/template/en/default/email/bugmail.html.tmpl
new file mode 100644
index 0000000..b361b08
--- /dev/null
+++ b/template/en/default/email/bugmail.html.tmpl
@@ -0,0 +1,119 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS "global/reason-descs.none.tmpl" %]
+
+[% isnew = bug.lastdiffed ? 0 : 1 %]
+<html>
+ <head>
+ <base href="[% urlbase FILTER html %]" />
+ </head>
+ <body>
+ [% Hook.process('start') %]
+ [% PROCESS generate_diffs %]
+ <p>
+ [% FOREACH comment = new_comments.reverse %]
+ <div>
+ [% IF comment.count %]
+ <b>[% "Comment # ${comment.count}" FILTER bug_link(bug,
+ {comment_num => comment.count, full_url => 1, user => to_user}) FILTER none %]
+ on [% "$terms.bug $bug.id" FILTER bug_link(bug, { full_url => 1, user => to_user }) FILTER none %]
+ from [% INCLUDE global/user.html.tmpl who = comment.author %]</b>
+ [% END %]
+ <pre>[% comment.body_full({ wrap => 1 }) FILTER quoteUrls(bug, comment, to_user) %]</pre>
+ </div>
+ [% END %]
+ </p>
+ <hr>
+ <span>You are receiving this mail because:</span>
+
+ <ul>
+ [% FOREACH reason = reasons %]
+ [% IF reason_descs.$reason %]
+ <li>[% reason_descs.$reason FILTER html %]</li>
+ [% END %]
+ [% END %]
+ [% FOREACH reason = reasons_watch %]
+ [% IF watch_reason_descs.$reason %]
+ <li>[% watch_reason_descs.$reason FILTER html %]</li>
+ [% END %]
+ [% END %]
+ </ul>
+ </body>
+</html>
+
+[% BLOCK generate_diffs %]
+ [% SET in_table = 0 %]
+ [% last_changer = 0 %]
+ [% FOREACH change = diffs %]
+ [% IF !isnew && change.who.id != last_changer %]
+ [% last_changer = change.who.id %]
+ [% IF in_table == 1 %]
+ </table>
+ [% SET in_table = 0 %]
+ [% END %]
+ [% IF change.blocker %]
+ [% "${terms.Bug} ${bug.id}" FILTER bug_link(bug, {full_url => 1, user => to_user}) FILTER none %]
+ depends on
+ [%+ "${terms.bug} ${change.blocker.id}"
+ FILTER bug_link(change.blocker, {full_url => 1, user => to_user}) FILTER none %],
+ which changed state.
+ [% ELSE %]
+ [% INCLUDE global/user.html.tmpl who = change.who %] changed
+ [%+ "${terms.bug} ${bug.id}" FILTER bug_link(bug, {full_url => 1, user => to_user}) FILTER none %]
+ [% END %]
+ <br>
+ [% IF in_table == 0 %]
+ <table border="1" cellspacing="0" cellpadding="8">
+ [% SET in_table = 1 %]
+ [% END %]
+ <tr>
+ <th>What</th>
+ <th>Removed</th>
+ <th>Added</th>
+ </tr>
+ [% END %]
+
+ [% PROCESS "email/bugmail-common.txt.tmpl" %]
+ [% IF in_table == 0 %]
+ <table border="1" cellspacing="0" cellpadding="8">
+ [% SET in_table = 1 %]
+ [% END %]
+ [% IF isnew %]
+ <tr>
+ <th>[% field_label FILTER html %]</th>
+ <td>
+ [% IF change.field_name == "bug_id" %]
+ [% new_value FILTER bug_link(bug, {full_url => 1, user => to_user}) FILTER none %]
+ [% ELSE %]
+ [% new_value FILTER html %]
+ [% END %]
+ </td>
+ </tr>
+ [% ELSE %]
+ <tr>
+ <td style="text-align:right;">[% field_label FILTER html %]</td>
+ <td>
+ [% IF old_value %]
+ [% old_value FILTER html %]
+ [% ELSE %]
+ &nbsp;
+ [% END%]
+ </td>
+ <td>
+ [% IF new_value %]
+ [% new_value FILTER html %]
+ [% ELSE %]
+ &nbsp;
+ [% END%]
+ </td>
+ </tr>
+ [% END %]
+ [% END %]
+ [% '</table>' IF in_table %]
+[% END %]
diff --git a/template/en/default/email/bugmail.txt.tmpl b/template/en/default/email/bugmail.txt.tmpl
new file mode 100644
index 0000000..b3c652f
--- /dev/null
+++ b/template/en/default/email/bugmail.txt.tmpl
@@ -0,0 +1,66 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS "global/reason-descs.none.tmpl" %]
+
+[% isnew = bug.lastdiffed ? 0 : 1 %]
+
+[% Hook.process('start') %]
+
+[%+ PROCESS generate_diffs -%]
+
+[% FOREACH comment = new_comments %]
+
+[%- IF comment.count %]
+--- Comment #[% comment.count %] from [% comment.author.identity %] ---
+[% END %]
+[%+ comment.body_full({ is_bugmail => 1, wrap => 1 }) FILTER strip_control_chars %]
+[% END %]
+
+-- [%# Protect the trailing space of the signature marker %]
+You are receiving this mail because:
+[% SET reason_lines = [] %]
+[% FOREACH reason = reasons %]
+ [% reason_lines.push(reason_descs.$reason) IF reason_descs.$reason %]
+[% END %]
+[% FOREACH reason = reasons_watch %]
+ [% reason_lines.push(watch_reason_descs.$reason)
+ IF watch_reason_descs.$reason %]
+[% END %]
+[%+ reason_lines.join("\n") %]
+
+[% BLOCK generate_diffs %]
+ [% urlbase %]show_bug.cgi?id=[% bug.id %]
+[%+ last_changer = 0 %]
+[% IF isnew %]
+[%+ +%]
+[% END %]
+ [% FOREACH change = diffs %]
+ [% IF !isnew && change.who.id != last_changer %]
+ [% last_changer = change.who.id %]
+ [% IF change.blocker %]
+ [% terms.Bug %] [%+ bug.id %] depends on [% terms.bug %] [%+ change.blocker.id %], which changed state.
+
+[%+ terms.Bug %] [%+ change.blocker.id %] Summary: [% change.blocker.short_desc %]
+[%+ urlbase %]show_bug.cgi?id=[% change.blocker.id %]
+ [% ELSE %]
+
+[% change.who.identity %] changed:
+ [% END %]
+
+ What |Removed |Added
+----------------------------------------------------------------------------
+[%+ END %][%# End of IF. This indentation is intentional! ~%]
+ [% PROCESS "email/bugmail-common.txt.tmpl"%]
+ [%~ IF isnew %]
+ [% format_columns(2, field_label _ ":", new_value) -%]
+ [% ELSE %]
+ [% format_columns(3, field_label, old_value, new_value) -%]
+ [% END %]
+ [% END -%]
+[% END %]
diff --git a/template/en/default/email/flagmail.txt.tmpl b/template/en/default/email/flagmail.txt.tmpl
new file mode 100644
index 0000000..169dfa8
--- /dev/null
+++ b/template/en/default/email/flagmail.txt.tmpl
@@ -0,0 +1,74 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% bugidsummary = bug.bug_id _ ': ' _ bug.short_desc %]
+[% attidsummary = attachment.id _ ': ' _ attachment.description %]
+[% flagtype_name = flag ? flag.type.name : old_flag.type.name %]
+[% statuses = { '+' => "granted" , '-' => 'denied' , 'X' => "canceled" ,
+ '?' => "asked" } %]
+
+[% to_identity = "" %]
+[% on_behalf_of = 0 %]
+[% action = flag.status || 'X' %]
+
+[% IF flag && flag.status == '?' %]
+ [% subject_status = "requested" %]
+ [% IF flag.setter_id == user.id %]
+ [% to_identity = flag.requestee.identity _ " for" %]
+ [% ELSE %]
+ [% on_behalf_of = 1 %]
+ [% IF flag.requestee %][% to_identity = " to " _ flag.requestee.identity %][% END %]
+ [% END %]
+[% ELSE %]
+ [% IF old_flag && old_flag.status == '?' %]
+ [% to_identity = old_flag.setter.identity _ "'s request for" %]
+ [% END %]
+ [% subject_status = statuses.$action %]
+[% END %]
+From: [% Param('mailfrom') %]
+To: [% to %]
+Subject: [% flagtype_name %] [%+ subject_status %]: [[% terms.Bug %] [%+ bug.bug_id %]] [% bug.short_desc %]
+[%- IF attachment %] :
+ [Attachment [% attachment.id %]] [% attachment.description FILTER clean_text %][% END %]
+Date: [% date %]
+X-Bugzilla-Type: request
+[%+ threadingmarker %]
+
+[%+ USE wrap -%]
+[%- FILTER bullet = wrap(80) -%]
+
+[% IF on_behalf_of %]
+[% user.identity %] has reassigned [% flag.setter.identity %]'s request for [% flagtype_name %]
+[% to_identity %]:
+[% ELSE %]
+[% user.identity %] has [% statuses.$action %] [%+ to_identity %] [%+ flagtype_name %]:
+[% END %]
+
+[% terms.Bug %] [%+ bugidsummary %]
+[% END %]
+[%+ urlbase %]show_bug.cgi?id=[% bug.bug_id %]
+[% IF attachment %]
+
+[% FILTER bullet = wrap(80) %]
+Attachment [% attidsummary %]
+[%- END %]
+[%+ urlbase %]attachment.cgi?id=[% attachment.id %]&action=edit
+[%- END %]
+
+[%- Hook.process('after_summary') -%]
+
+[%- FILTER bullet = wrap(80) %]
+
+[% USE Bugzilla %]
+[%-# .defined is necessary to avoid a taint issue in Perl < 5.10.1, see bug 509794. %]
+[% IF Bugzilla.cgi.param("comment").defined && Bugzilla.cgi.param("comment").length > 0 %]
+------- Additional Comments from [% user.identity %]
+[%+ Bugzilla.cgi.param("comment") FILTER strip_control_chars %]
+[% END %]
+
+[%- END %]
diff --git a/template/en/default/email/lockout.txt.tmpl b/template/en/default/email/lockout.txt.tmpl
new file mode 100644
index 0000000..51153ea
--- /dev/null
+++ b/template/en/default/email/lockout.txt.tmpl
@@ -0,0 +1,25 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+From: [% Param('mailfrom') %]
+To: [% Param('maintainer') %]
+Subject: [[% terms.Bugzilla %]] Account Lock-Out: [% locked_user.login %] ([% address %])
+X-Bugzilla-Type: admin
+
+The address [% address %] failed too many login attempts (
+[%- constants.MAX_LOGIN_ATTEMPTS +%]) for
+the account [% locked_user.login %].
+
+The login attempts occurred at these times:
+
+[% FOREACH login = attempts %]
+ [%+ login.login_time FILTER time %]
+[% END %]
+
+This IP will be able to log in again using this account at
+[%+ unlock_at FILTER time %].
diff --git a/template/en/default/email/sanitycheck.txt.tmpl b/template/en/default/email/sanitycheck.txt.tmpl
new file mode 100644
index 0000000..797e4f1
--- /dev/null
+++ b/template/en/default/email/sanitycheck.txt.tmpl
@@ -0,0 +1,23 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+From: [% Param('mailfrom') %]
+To: [% addressee %]
+Subject: [[% terms.Bugzilla %]] Sanity Check Results
+X-Bugzilla-Type: sanitycheck
+
+[%+ urlbase %]sanitycheck.cgi
+
+Below can you read the sanity check results.
+[% IF error_found %]
+Some errors have been found.
+[% ELSE %]
+No errors have been found.
+[% END %]
+
+[% output %]
diff --git a/template/en/default/email/sudo.txt.tmpl b/template/en/default/email/sudo.txt.tmpl
new file mode 100644
index 0000000..d0845e3
--- /dev/null
+++ b/template/en/default/email/sudo.txt.tmpl
@@ -0,0 +1,29 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+Content-Type: text/plain
+From: [% Param('mailfrom') %]
+To: [% user.email %]
+Subject: [[% terms.Bugzilla %]] Your account [% user.login -%]
+ is being impersonated
+X-Bugzilla-Type: admin
+
+ [%+ sudoer.identity %] has used the 'sudo' feature to access
+[%+ terms.Bugzilla %] using your account.
+
+[% IF reason %]
+ [%+ sudoer.identity %] provided the following reason for doing this:
+
+[% reason FILTER wrap_comment %]
+[% ELSE %]
+ [%+ sudoer.identity %] did not provide a reason for doing this.
+[% END %]
+
+ If you feel that this action was inappropriate, please contact
+[%+ Param("maintainer") %]. For more information on this feature,
+visit <[% urlbase %]page.cgi?id=sudo.html>.
diff --git a/template/en/default/email/whine.txt.tmpl b/template/en/default/email/whine.txt.tmpl
new file mode 100644
index 0000000..106a94a
--- /dev/null
+++ b/template/en/default/email/whine.txt.tmpl
@@ -0,0 +1,51 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+From: [% Param("mailfrom") %]
+To: [% email %][% Param("emailsuffix") %]
+Subject: Your [% terms.Bugzilla %] [%+ terms.bug %] list needs attention.
+X-Bugzilla-Type: whine
+
+[This e-mail has been automatically generated.]
+
+You have one or more [% terms.bugs %] assigned to you in the [% terms.Bugzilla %]
+[% terms.bug %] tracking system ([% urlbase %]) that require
+attention.
+
+All of these [% terms.bugs %] are in the [% display_value("bug_status", "CONFIRMED") %]
+state, and have not been touched in [% Param("whinedays") %] days or more.
+You need to take a look at them, and decide on an initial action.
+
+Generally, this means one of three things:
+
+(1) You decide this [% terms.bug %] is really quick to deal with (like, it's [% display_value("resolution", "INVALID") %]),
+ and so you get rid of it immediately.
+(2) You decide the [% terms.bug %] doesn't belong to you, and you reassign it to
+ someone else. (Hint: if you don't know who to reassign it to, make
+ sure that the Component field seems reasonable, and then use the
+ "Reset Assignee to default" option.)
+(3) You decide the [% terms.bug %] belongs to you, but you can't solve it this moment.
+ Accept the [% terms.bug %] by setting the status to [% display_value("bug_status", "IN_PROGRESS") %].
+
+To get a list of all [% display_value("bug_status", "CONFIRMED") %] [%+ terms.bugs %], you can use this URL (bookmark
+it if you like!):
+
+ [% urlbase %]buglist.cgi?bug_status=CONFIRMED&assigned_to=[% email %]
+
+Or, you can use the general query page, at
+[%+ urlbase %]query.cgi
+
+Appended below are the individual URLs to get to all of your [% display_value("bug_status", "CONFIRMED") %] [%+ terms.bugs %]
+that haven't been touched for [% Param("whinedays") %] days or more.
+
+You will get this message once a day until you've dealt with these [% terms.bugs %]!
+
+[% FOREACH bug = bugs %]
+ [%+ bug.summary %]
+ -> [% urlbase %]show_bug.cgi?id=[% bug.id %]
+[% END %]
diff --git a/template/en/default/extensions/config.pm.tmpl b/template/en/default/extensions/config.pm.tmpl
new file mode 100644
index 0000000..cb71957
--- /dev/null
+++ b/template/en/default/extensions/config.pm.tmpl
@@ -0,0 +1,26 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # name: string; The name of the extension.
+ #%]
+
+[% PROCESS extensions/license.txt.tmpl %]
+
+package B[% %]ugzilla::Extension::[% name %];
+use strict;
+
+use constant NAME => '[% name %]';
+
+use constant REQUIRED_MODULES => [
+];
+
+use constant OPTIONAL_MODULES => [
+];
+
+__PACKAGE__->NAME;
diff --git a/template/en/default/extensions/extension.pm.tmpl b/template/en/default/extensions/extension.pm.tmpl
new file mode 100644
index 0000000..206ea88
--- /dev/null
+++ b/template/en/default/extensions/extension.pm.tmpl
@@ -0,0 +1,31 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # name: string; The name of the extension.
+ #%]
+
+[% PROCESS extensions/license.txt.tmpl %]
+
+package B[% %]ugzilla::Extension::[% name %];
+use strict;
+use base qw(B[% %]ugzilla::Extension);
+
+# This code for this is in [% path %]/lib/Util.pm
+use B[% %]ugzilla::Extension::[% name %]::Util;
+
+our $VERSION = '0.01';
+
+# See the documentation of B[% %]ugzilla::Hook ("perldoc B[% %]ugzilla::Hook"
+# in the bugzilla directory) for a list of all available hooks.
+sub install_update_db {
+ my ($self, $args) = @_;
+
+}
+
+__PACKAGE__->NAME;
diff --git a/template/en/default/extensions/hook-readme.txt.tmpl b/template/en/default/extensions/hook-readme.txt.tmpl
new file mode 100644
index 0000000..63e09e4
--- /dev/null
+++ b/template/en/default/extensions/hook-readme.txt.tmpl
@@ -0,0 +1,13 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+Template hooks go in this directory. Template hooks are called in normal
+[%+ terms.Bugzilla %] templates like [[% '%' %] Hook.process('some-hook') %].
+More information about them can be found in the documentation of
+B[% %]ugzilla::Extension. (Do "perldoc B[% %]ugzilla::Extension" from the main
+[%+ terms.Bugzilla %] directory to see that documentation.)
diff --git a/template/en/default/extensions/license.txt.tmpl b/template/en/default/extensions/license.txt.tmpl
new file mode 100644
index 0000000..6acde01
--- /dev/null
+++ b/template/en/default/extensions/license.txt.tmpl
@@ -0,0 +1,18 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # name: string; The name of the extension.
+ #%]
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This Source Code Form is "Incompatible With Secondary Licenses", as
+# defined by the Mozilla Public License, v. 2.0.
diff --git a/template/en/default/extensions/name-readme.txt.tmpl b/template/en/default/extensions/name-readme.txt.tmpl
new file mode 100644
index 0000000..22fbad4
--- /dev/null
+++ b/template/en/default/extensions/name-readme.txt.tmpl
@@ -0,0 +1,24 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+Normal templates go in this directory. You can load them in your
+code like this:
+
+use B[% %]ugzilla::Error;
+my $template = B[% %]ugzilla->template;
+$template->process('[% name FILTER lower %]/some-template.html.tmpl')
+ or ThrowTemplateError($template->error());
+
+That would be how to load a file called <kbd>some-template.html.tmpl</kbd> that
+was in this directory.
+
+Note that you have to be careful that the full path of your template
+never conflicts with a template that exists in [% terms.Bugzilla %] or in
+another extension, or your template might override that template. That's why
+we created this directory called '[% name FILTER lower %]' for you, so you
+can put your templates in here to help avoid conflicts.
diff --git a/template/en/default/extensions/util.pm.tmpl b/template/en/default/extensions/util.pm.tmpl
new file mode 100644
index 0000000..6c9fe37
--- /dev/null
+++ b/template/en/default/extensions/util.pm.tmpl
@@ -0,0 +1,27 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # name: string; The name of the extension.
+ #%]
+
+[% PROCESS extensions/license.txt.tmpl %]
+
+package B[% %]ugzilla::Extension::[% name %]::Util;
+use strict;
+use base qw(Exporter);
+our @EXPORT = qw(
+
+);
+
+# This file can be loaded by your extension via
+# "use B[% %]ugzilla::Extension::[% name %]::Util". You can put functions
+# used by your extension in here. (Make sure you also list them in
+# @EXPORT.)
+
+1;
diff --git a/template/en/default/extensions/web-readme.txt.tmpl b/template/en/default/extensions/web-readme.txt.tmpl
new file mode 100644
index 0000000..41dcd8e
--- /dev/null
+++ b/template/en/default/extensions/web-readme.txt.tmpl
@@ -0,0 +1,15 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+Web-accessible files, like JavaScript, CSS, and images go in this
+directory. You can reference them directly in your HTML. For example,
+if you have a file called "style.css" and your extension is called
+"Foo", you would put it in "extensions/Foo/web/style.css", and then
+you could link to it in HTML like:
+
+<link href="extensions/Foo/web/style.css" rel="stylesheet" type="text/css">
diff --git a/template/en/default/filterexceptions.pl b/template/en/default/filterexceptions.pl
new file mode 100644
index 0000000..1898625
--- /dev/null
+++ b/template/en/default/filterexceptions.pl
@@ -0,0 +1,468 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This Source Code Form is "Incompatible With Secondary Licenses", as
+# defined by the Mozilla Public License, v. 2.0.
+
+# Important! The following classes of directives are excluded in the test,
+# and so do not need to be added here. Doing so will cause warnings.
+# See 008filter.t for more details.
+#
+# Comments - [%#...
+# Directives - [% IF|ELSE|UNLESS|FOREACH...
+# Assignments - [% foo = ...
+# Simple literals - [% " selected" ...
+# Values always used for numbers - [% (i|j|k|n|count) %]
+# Params - [% Param(...
+# Safe functions - [% (time2str)...
+# Safe vmethods - [% foo.size %] [% foo.length %]
+# [% foo.push() %]
+# TT loop variables - [% loop.count %]
+# Already-filtered stuff - [% wibble FILTER html %]
+# where the filter is one of html|csv|js|quoteUrls|time|uri|xml|none
+
+%::safe = (
+
+'whine/schedule.html.tmpl' => [
+ 'event.key',
+ 'query.id',
+ 'query.sort',
+ 'schedule.id',
+ 'option.0',
+ 'option.1',
+],
+
+'whine/mail.html.tmpl' => [
+ 'bug.bug_id',
+],
+
+'flag/list.html.tmpl' => [
+ 'flag.status',
+ 'type.id',
+],
+
+'search/form.html.tmpl' => [
+ 'qv.name',
+ 'qv.description',
+],
+
+'search/search-specific.html.tmpl' => [
+ 'status.name',
+],
+
+'search/tabs.html.tmpl' => [
+ 'content',
+],
+
+'request/queue.html.tmpl' => [
+ 'column_headers.$group_field',
+ 'column_headers.$column',
+ 'request.status',
+ 'request.bug_id',
+ 'request.attach_id',
+],
+
+'reports/keywords.html.tmpl' => [
+ 'keyword.bug_count',
+],
+
+'reports/report-table.csv.tmpl' => [
+ 'data.$tbl.$col.$row',
+ 'colsepchar',
+],
+
+'reports/report-table.html.tmpl' => [
+ '"&amp;$col_vals" IF col_vals',
+ '"&amp;$row_vals" IF row_vals',
+ 'classes.$row_idx.$col_idx',
+ 'urlbase',
+ 'data.$tbl.$col.$row',
+ 'row_total',
+ 'col_totals.$col',
+ 'grand_total',
+],
+
+'reports/report.html.tmpl' => [
+ 'width',
+ 'height',
+ 'imageurl',
+ 'formaturl',
+ 'other_format.name',
+ 'switchbase',
+ 'cumulate',
+],
+
+'reports/chart.html.tmpl' => [
+ 'width',
+ 'height',
+ 'imageurl',
+ 'sizeurl',
+ 'height + 100',
+ 'height - 100',
+ 'width + 100',
+ 'width - 100',
+],
+
+'reports/series-common.html.tmpl' => [
+ 'sel.name',
+ '"onchange=\"$sel.onchange\"" IF sel.onchange',
+],
+
+'reports/chart.csv.tmpl' => [
+ 'data.$j.$i',
+ 'colsepchar',
+],
+
+'reports/create-chart.html.tmpl' => [
+ 'series.series_id',
+ 'newidx',
+],
+
+'reports/edit-series.html.tmpl' => [
+ 'default.series_id',
+],
+
+'list/edit-multiple.html.tmpl' => [
+ 'group.id',
+ 'menuname',
+],
+
+'list/list.rdf.tmpl' => [
+ 'template_version',
+ 'bug.bug_id',
+ 'column',
+],
+
+'list/table.html.tmpl' => [
+ 'tableheader',
+ 'bug.bug_id',
+],
+
+'list/list.csv.tmpl' => [
+ 'bug.bug_id',
+ 'colsepchar',
+],
+
+'list/list.js.tmpl' => [
+ 'bug.bug_id',
+],
+
+'global/choose-product.html.tmpl' => [
+ 'target',
+],
+
+# You are not permitted to add any values here. Everything in this file should
+# be filtered unless there's an extremely good reason why not, in which case,
+# use the "none" dummy filter.
+'global/code-error.html.tmpl' => [
+],
+
+'global/header.html.tmpl' => [
+ 'javascript',
+ 'style',
+ 'onload',
+ 'title',
+ '" &ndash; $header" IF header',
+ 'subheader',
+ 'header_addl_info',
+ 'message',
+],
+
+'global/messages.html.tmpl' => [
+ 'message_tag',
+ 'series.frequency * 2',
+],
+
+'global/select-menu.html.tmpl' => [
+ 'options',
+ 'size',
+],
+
+'global/tabs.html.tmpl' => [
+ 'content',
+],
+
+# You are not permitted to add any values here. Everything in this file should
+# be filtered unless there's an extremely good reason why not, in which case,
+# use the "none" dummy filter.
+'global/user-error.html.tmpl' => [
+],
+
+'global/confirm-user-match.html.tmpl' => [
+ 'script',
+],
+
+'global/site-navigation.html.tmpl' => [
+ 'bug.bug_id',
+],
+
+'bug/comments.html.tmpl' => [
+ 'comment.id',
+ 'comment.count',
+ 'bug.bug_id',
+],
+
+'bug/dependency-graph.html.tmpl' => [
+ 'image_map', # We need to continue to make sure this is safe in the CGI
+ 'image_url',
+ 'map_url',
+ 'bug_id',
+],
+
+'bug/dependency-tree.html.tmpl' => [
+ 'bugid',
+ 'maxdepth',
+ 'hide_resolved',
+ 'ids.join(",")',
+ 'maxdepth + 1',
+ 'maxdepth > 0 && maxdepth <= realdepth ? maxdepth : ""',
+ 'maxdepth == 1 ? 1
+ : ( maxdepth ? maxdepth - 1 : realdepth - 1 )',
+],
+
+'bug/edit.html.tmpl' => [
+ 'bug.remaining_time',
+ 'bug.delta_ts',
+ 'bug.bug_id',
+ 'group.bit',
+ 'selname',
+ 'inputname',
+ '" colspan=\"$colspan\"" IF colspan',
+ '" size=\"$size\"" IF size',
+ '" maxlength=\"$maxlength\"" IF maxlength',
+ '" spellcheck=\"$spellcheck\"" IF spellcheck',
+],
+
+'bug/show-multiple.html.tmpl' => [
+ 'attachment.id',
+ 'flag.status',
+],
+
+'bug/show.html.tmpl' => [
+ 'bug.bug_id',
+],
+
+'bug/show.xml.tmpl' => [
+ 'constants.BUGZILLA_VERSION',
+ 'a.id',
+ 'field',
+],
+
+'bug/summarize-time.html.tmpl' => [
+ 'global.grand_total FILTER format("%.2f")',
+ 'subtotal FILTER format("%.2f")',
+ 'work_time FILTER format("%.2f")',
+ 'global.total FILTER format("%.2f")',
+ 'global.remaining FILTER format("%.2f")',
+ 'global.estimated FILTER format("%.2f")',
+ 'bugs.$id.remaining_time FILTER format("%.2f")',
+ 'bugs.$id.estimated_time FILTER format("%.2f")',
+],
+
+
+'bug/time.html.tmpl' => [
+ 'time_unit FILTER format(\'%.1f\')',
+ 'time_unit FILTER format(\'%.2f\')',
+ '(act / (act + rem)) * 100
+ FILTER format("%d")',
+],
+
+'bug/process/results.html.tmpl' => [
+ 'title.$type',
+ '"$terms.Bug $id" FILTER bug_link(id)',
+ '"$terms.bug $id" FILTER bug_link(id)',
+],
+
+'bug/create/create.html.tmpl' => [
+ 'cloned_bug_id',
+],
+
+'bug/create/create-guided.html.tmpl' => [
+ 'tablecolour',
+ 'sel',
+ 'productstring',
+],
+
+'bug/activity/table.html.tmpl' => [
+ 'change.attachid',
+],
+
+'attachment/create.html.tmpl' => [
+ 'bug.bug_id',
+ 'attachment.id',
+],
+
+'attachment/created.html.tmpl' => [
+ 'attachment.id',
+ 'attachment.bug_id',
+],
+
+'attachment/edit.html.tmpl' => [
+ 'attachment.id',
+ 'attachment.bug_id',
+ 'editable_or_hide',
+],
+
+'attachment/list.html.tmpl' => [
+ 'attachment.id',
+ 'flag.status',
+ 'bugid',
+ 'obsolete_attachments',
+],
+
+'attachment/midair.html.tmpl' => [
+ 'attachment.id',
+],
+
+'attachment/show-multiple.html.tmpl' => [
+ 'a.id',
+ 'flag.status'
+],
+
+'attachment/updated.html.tmpl' => [
+ 'attachment.id',
+],
+
+'attachment/diff-header.html.tmpl' => [
+ 'attachid',
+ 'id',
+ 'bugid',
+ 'oldid',
+ 'newid',
+ 'patch.id',
+],
+
+'attachment/diff-file.html.tmpl' => [
+ 'lxr_prefix',
+ 'file.minus_lines',
+ 'file.plus_lines',
+ 'bonsai_prefix',
+ 'section.old_start',
+ 'section_num',
+ 'current_line_old',
+ 'current_line_new',
+],
+
+'admin/admin.html.tmpl' => [
+ 'class'
+],
+
+'admin/table.html.tmpl' => [
+ 'contentlink'
+],
+
+'admin/custom_fields/cf-js.js.tmpl' => [
+ 'constants.FIELD_TYPE_SINGLE_SELECT',
+ 'constants.FIELD_TYPE_MULTI_SELECT',
+ 'constants.FIELD_TYPE_BUG_ID',
+],
+
+'admin/params/common.html.tmpl' => [
+ 'sortlist_separator',
+],
+
+'admin/products/groupcontrol/confirm-edit.html.tmpl' => [
+ 'group.count',
+],
+
+'admin/products/groupcontrol/edit.html.tmpl' => [
+ 'group.id',
+ 'constants.CONTROLMAPNA',
+ 'constants.CONTROLMAPSHOWN',
+ 'constants.CONTROLMAPDEFAULT',
+ 'constants.CONTROLMAPMANDATORY',
+],
+
+'admin/products/list.html.tmpl' => [
+ 'classification_url_part',
+],
+
+'admin/products/footer.html.tmpl' => [
+ 'classification_url_part',
+ 'classification_text',
+],
+
+'admin/flag-type/confirm-delete.html.tmpl' => [
+ 'flag_type.flag_count',
+ 'flag_type.id',
+],
+
+'admin/flag-type/edit.html.tmpl' => [
+ 'selname',
+],
+
+'admin/flag-type/list.html.tmpl' => [
+ 'type.id',
+],
+
+
+'admin/components/confirm-delete.html.tmpl' => [
+ 'comp.bug_count'
+],
+
+'admin/groups/delete.html.tmpl' => [
+ 'shared_queries'
+],
+
+'admin/users/confirm-delete.html.tmpl' => [
+ 'attachments',
+ 'reporter',
+ 'assignee_or_qa',
+ 'cc',
+ 'component_cc',
+ 'flags.requestee',
+ 'flags.setter',
+ 'longdescs',
+ 'quips',
+ 'series',
+ 'watch.watched',
+ 'watch.watcher',
+ 'whine_events',
+ 'whine_schedules',
+ 'otheruser.id'
+],
+
+'admin/users/edit.html.tmpl' => [
+ 'otheruser.id',
+ 'group.id',
+],
+
+'admin/components/edit.html.tmpl' => [
+ 'comp.bug_count'
+],
+
+'admin/workflow/edit.html.tmpl' => [
+ 'status.id',
+ 'new_status.id',
+],
+
+'admin/workflow/comment.html.tmpl' => [
+ 'status.id',
+ 'new_status.id',
+],
+
+'account/auth/login-small.html.tmpl' => [
+ 'qs_suffix',
+],
+
+'account/prefs/email.html.tmpl' => [
+ 'relationship.id',
+ 'event.id',
+ 'prefname',
+],
+
+'account/prefs/prefs.html.tmpl' => [
+ 'current_tab.label',
+ 'current_tab.name',
+],
+
+'account/prefs/saved-searches.html.tmpl' => [
+ 'group.id',
+],
+
+'config.rdf.tmpl' => [
+ 'escaped_urlbase',
+],
+
+);
diff --git a/template/en/default/flag/list.html.tmpl b/template/en/default/flag/list.html.tmpl
new file mode 100644
index 0000000..4d7eefb
--- /dev/null
+++ b/template/en/default/flag/list.html.tmpl
@@ -0,0 +1,167 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% IF user.id && !read_only_flags && (!bug || bug.check_can_change_field('flagtypes.name', 0, 1)) %]
+
+[%# We list flags by looping twice over the flag types relevant for the bug.
+ # In the first loop, we display existing flags and then, for active types,
+ # we display UI for adding new flags. In the second loop, we display UI
+ # for adding additional new flags for those types for which a flag already
+ # exists but which are multiplicable (can have multiple flags of the type
+ # on a single bug/attachment).
+ #%]
+
+[% DEFAULT flag_table_id = "flags" %]
+
+<script src="[% 'js/flag.js' FILTER mtime %]" type="text/javascript"></script>
+
+<table id="[% flag_table_id FILTER html %]">
+ [% UNLESS flag_no_header %]
+ <tr>
+ <th colspan="3">
+ Flags:
+ </th>
+ [% IF any_flags_requesteeble %]
+ <th>
+ Requestee:
+ </th>
+ [% END %]
+ </tr>
+ [% END %]
+
+ [%# Step 1: Display every flag type (except inactive types with no flags). %]
+ [% FOREACH type = flag_types -%]
+
+ [%-# Step 1a: Display existing flag(s). %]
+ [% FOREACH flag = type.flags %]
+ [% PROCESS flag_row flag = flag type = type %]
+ [% END -%]
+ [% SET flag = "" %]
+
+ [%-# Step 1b: Display UI for setting flag. %]
+ [% IF (!type.flags || type.flags.size == 0) && type.is_active %]
+ [% PROCESS flag_row type = type %]
+ [% END %]
+ [% END %]
+
+ [%# Step 2: Display flag type again (if type is multiplicable). %]
+ [% FOREACH type = flag_types %]
+ [% NEXT UNLESS type.flags && type.flags.size > 0 && type.is_multiplicable && type.is_active %]
+ [% IF !separator_displayed %]
+ <tbody class="bz_flag_type">
+ <tr><td colspan="3"><hr></td></tr>
+ </tbody>
+ [% separator_displayed = 1 %]
+ [% END %]
+ [% PROCESS flag_row type = type addl_text = "addl." %]
+ [% END %]
+</table>
+
+[% ELSE %]
+ [%# The user is logged out. Display flags as read-only. %]
+ [% header_displayed = 0 %]
+ [% FOREACH type = flag_types %]
+ [% FOREACH flag = type.flags %]
+ [% IF !flag_no_header AND !header_displayed %]
+ <p><b>Flags:</b></p>
+ [% header_displayed = 1 %]
+ [% END %]
+ [% IF flag.setter.name %]
+ <span title="[% flag.setter.name FILTER html %]">[% flag.setter.nick FILTER html %]</span>:
+ [% ELSE %]
+ [% flag.setter.nick FILTER html %]:
+ [% END %]
+ [%+ type.name FILTER html FILTER no_break %][% flag.status %]
+ [% IF flag.requestee %]
+ [% IF flag.requestee.name %]
+ (<span title="[% flag.requestee.name FILTER html %]">[% flag.requestee.nick FILTER html %]</span>)
+ [% ELSE %]
+ ([% flag.requestee.nick FILTER html %])
+ [% END %]
+ [% END %]<br>
+ [% END %]
+ [% END %]
+[% END %]
+
+[%# Display a table row for flags %]
+
+[% BLOCK flag_row %]
+ [% RETURN IF !flag && !((type.is_requestable && user.can_request_flag(type)) || user.can_set_flag(type)) %]
+ [% SET fid = flag ? "flag-$flag.id" : "flag_type-$type.id" %]
+ <tbody[% ' class="bz_flag_type"' IF !flag %]>
+ <tr>
+ <td>
+ [% IF flag %]
+ <span title="[% flag.setter.identity FILTER html %]">[% flag.setter.nick FILTER html %]</span>:
+ [% ELSE %]
+ [% addl_text FILTER html %]
+ [% END %]
+ </td>
+ <td>
+ <label title="[% type.description FILTER html %]" for="[% fid FILTER html %]">
+ [%- type.name FILTER html FILTER no_break -%]</label>
+ </td>
+ <td>
+ <input type="hidden" id="[% fid FILTER html %]_dirty">
+ <select id="[% fid FILTER html %]" name="[% fid FILTER html %]"
+ title="[% type.description FILTER html %]"
+ onchange="toggleRequesteeField(this);"
+ class="flag_select flag_type-[% type.id %]">
+ [%# Only display statuses the user is allowed to set. %]
+ [% IF !flag || user.can_request_flag(type) || flag.setter_id == user.id %]
+ <option value="X"></option>
+ [% END %]
+ [% IF type.is_active %]
+ [% IF (type.is_requestable && user.can_request_flag(type)) || (flag && flag.status == "?") %]
+ <option value="?" [% "selected" IF flag && flag.status == "?" %]>?</option>
+ [% END %]
+ [% IF user.can_set_flag(type) || (flag && flag.status == "+") %]
+ <option value="+" [% "selected" IF flag && flag.status == "+" %]>+</option>
+ [% END %]
+ [% IF user.can_set_flag(type) || (flag && flag.status == "-") %]
+ <option value="-" [% "selected" IF flag && flag.status == "-" %]>-</option>
+ [% END %]
+ [% ELSE %]
+ <option value="[% flag.status %]" selected="selected">[% flag.status %]</option>
+ [% END %]
+ </select>
+ </td>
+ [% IF any_flags_requesteeble %]
+ <td>
+ [% IF (type.is_active && type.is_requestable && type.is_requesteeble) || (flag && flag.requestee) %]
+ <span style="white-space: nowrap;">
+ [% SET grant_list = [] %]
+ [% IF Param('usemenuforusers') %]
+ [% grant_list = type.grant_list %]
+ [% IF flag && !(type.is_active && type.is_requestable && type.is_requesteeble) %]
+ [%# We are here only because there was already a requestee. In this case,
+ the only valid action is to remove the requestee or leave it alone;
+ nothing else. %]
+ [% grant_list = [flag.requestee] %]
+ [% END %]
+ [% END %]
+ [% SET flag_name = flag ? "requestee-$flag.id" : "requestee_type-$type.id" %]
+ [% SET flag_requestee = (flag && flag.requestee) ? flag.requestee.login : '' %]
+ [% SET flag_multiple = flag ? 0 : type.is_multiplicable * 3 %]
+ [% SET flag_empty_ok = flag ? 1 : !type.is_multiplicable %]
+ [% INCLUDE global/userselect.html.tmpl
+ name => flag_name
+ id => flag_name
+ value => flag_requestee
+ multiple => flag_multiple
+ emptyok => flag_empty_ok
+ classes => ["requestee"]
+ custom_userlist => grant_list
+ %]
+ </span>
+ [% END %]
+ </td>
+ [% END %]
+ </tr>
+ </tbody>
+[% END %]
diff --git a/template/en/default/global/banner.html.tmpl b/template/en/default/global/banner.html.tmpl
new file mode 100644
index 0000000..37ec8c0
--- /dev/null
+++ b/template/en/default/global/banner.html.tmpl
@@ -0,0 +1,12 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# Migration note: this file corresponds to the old Param 'bannerhtml' %]
+
+ <div id="banner">
+ </div>
diff --git a/template/en/default/global/calendar.js.tmpl b/template/en/default/global/calendar.js.tmpl
new file mode 100644
index 0000000..26f3fa0
--- /dev/null
+++ b/template/en/default/global/calendar.js.tmpl
@@ -0,0 +1,33 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # id: The id of the input field the calendar widget is to be assigned to.
+ #%]
+
+[%# This template exists because createCalendar accepts additional parameters
+ # which allow for localization. Please see the YUI documentation at
+ # http://developer.yahoo.com/yui/calendar/#internationalization for details.
+ # As an example, here's what you'd specify as additional parameters to
+ # localize for German calendars; replace the ellipsis ("...") by the original
+ # parameter (we cannot put it into the example because it'd break this
+ # template comment):
+ #
+ # createCalendar(...
+ # /* The weekday the week begins on; 0 is Sunday,
+ # * 1 is Monday and so on: */
+ # 1,
+ # /* Months, full names; first must be January: */
+ # ['Januar', 'Februar', 'März', 'April',
+ # 'Mai', 'Juni', 'Juli', 'August',
+ # 'September', 'Oktober', 'November', 'Dezember'],
+ # /* Weekdays, two-letter abbreviations; first must be
+ # * Sunday: */
+ # ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa']);
+ #%]
+createCalendar('[% id FILTER js %]');
diff --git a/template/en/default/global/choose-classification.html.tmpl b/template/en/default/global/choose-classification.html.tmpl
new file mode 100644
index 0000000..76789a2
--- /dev/null
+++ b/template/en/default/global/choose-classification.html.tmpl
@@ -0,0 +1,54 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # classifications: an array of classification objects containing
+ # at least one product accessible by the user.
+ #%]
+
+[% IF target == "enter_bug.cgi" %]
+ [% title = "Select Classification" %]
+ [% subheader = "Please select the classification." %]
+[% END %]
+
+[% DEFAULT title = "Choose the classification" %]
+[% PROCESS global/header.html.tmpl %]
+
+<table>
+ <tr>
+ <th align="right">
+ <a href="[% target FILTER uri %]?classification=__all
+ [% IF cloned_bug_id %]&amp;cloned_bug_id=[% cloned_bug_id FILTER uri %][% END -%]
+ [%- IF format %]&amp;format=[% format FILTER uri %][% END %]">
+ All</a>:
+ </th>
+
+ <td valign="top">&nbsp;Show all products</td>
+ </tr>
+ <tr>
+ <th colspan="2">&nbsp;</th>
+ </tr>
+
+[% FOREACH class = classifications %]
+ <tr>
+ <th align="right">
+ <a href="[% target FILTER uri %]?classification=[% class.name FILTER uri -%]
+ [%- IF cloned_bug_id %]&amp;cloned_bug_id=[% cloned_bug_id FILTER uri %][% END -%]
+ [%- IF format %]&amp;format=[% format FILTER uri %][% END %]">
+ [% class.name FILTER html %]</a>:
+ </th>
+
+ [% IF class.description %]
+ <td valign="top">&nbsp;[% class.description FILTER html_light %]</td>
+ [% END %]
+ </tr>
+[% END %]
+
+</table>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/global/choose-product.html.tmpl b/template/en/default/global/choose-product.html.tmpl
new file mode 100644
index 0000000..dfa0b00
--- /dev/null
+++ b/template/en/default/global/choose-product.html.tmpl
@@ -0,0 +1,61 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # classifications: array of hashes, with an 'object' key representing a
+ # classification object and 'products' the list of
+ # product objects the user can enter bugs into.
+ # target: the script that displays this template.
+ # cloned_bug_id: ID of the bug being cloned.
+ # format: the desired format to display the target.
+ #%]
+
+[% IF target == "enter_bug.cgi" %]
+ [% title = "Enter $terms.Bug" %]
+ [% h2 = BLOCK %]First, you must pick a product on which to enter [% terms.abug %]: [% END %]
+[% ELSIF target == "describecomponents.cgi" %]
+ [% title = "Browse" %]
+ [% h2 = "Select a product category to browse:" %]
+[% END %]
+
+[% DEFAULT title = "Choose a Product" %]
+[% PROCESS global/header.html.tmpl %]
+
+<h2>[% h2 FILTER html %]</h2>
+
+<table>
+
+[% FOREACH c = classifications %]
+ [% IF c.object %]
+ <tr>
+ <th colspan="2" align="left">[% c.object.name FILTER html %]:
+ [%+ c.object.description FILTER html_light %]</th>
+ </tr>
+ [% END %]
+
+ [% FOREACH p = c.products %]
+ <tr>
+ <th align="right" valign="top">
+ <a href="[% target %]?product=[% p.name FILTER uri -%]
+ [%- IF cloned_bug_id %]&amp;cloned_bug_id=[% cloned_bug_id FILTER uri %][% END -%]
+ [%- IF format %]&amp;format=[% format FILTER uri %][% END %]">
+ [% p.name FILTER html FILTER no_break %]</a>:&nbsp;
+ </th>
+
+ <td valign="top">[% p.description FILTER html_light %]</td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <th colspan="2">&nbsp;</th>
+ </tr>
+[% END %]
+
+</table>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/global/code-error.html.tmpl b/template/en/default/global/code-error.html.tmpl
new file mode 100644
index 0000000..086f34a
--- /dev/null
+++ b/template/en/default/global/code-error.html.tmpl
@@ -0,0 +1,463 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # header_done: boolean. True if the header has already been printed.
+ # error: string. The tag of the error.
+ # variables: hash. Useful data about the problem. The keys are the variable
+ # names, and the values the variable values.
+ #%]
+
+[%# This is a list of all the possible code errors. Please keep them in
+ # alphabetical order by error tag, and leave a blank line between errors.
+ #
+ # Note that you must explicitly filter every single template variable
+ # in this file; if you do not wish to change it, use the "none" filter.
+ #%]
+
+[% DEFAULT title = "Internal Error" %]
+
+[% error_message = BLOCK %]
+ [% IF error == "auth_invalid_email" %]
+ [% title = "Invalid Email Address" %]
+ We received an email address (<b>[% addr FILTER html %]</b>)
+ that didn't pass our syntax checking for a legal email address,
+ when trying to create or update your account.
+ [% IF default %]
+ A legal address must contain exactly one '@',
+ and at least one '.' after the @.
+ [% ELSE %]
+ [%+ Param('emailregexpdesc') FILTER html_light %]
+ [% END %]
+ It also must not contain any illegal characters.
+
+ [% ELSIF error == "authres_unhandled" %]
+ The result value of [% value FILTER html %] was not handled by
+ the login code.
+
+ [% ELSIF error == "bad_arg" %]
+ Bad argument <code>[% argument FILTER html %]</code> sent to
+ <code>[% function FILTER html %]</code> function.
+
+ [% ELSIF error == "bug_error" %]
+ Trying to retrieve [% terms.bug %] [%+ bug.bug_id FILTER html %] returned
+ the error [% bug.error FILTER html %].
+
+ [% ELSIF error == "chart_data_not_generated" %]
+ [% admindocslinks = {'extraconfig.html' => 'Setting up Charting'} %]
+ [% IF product %]
+ Charts for the <em>[% product FILTER html %]</em> product are not
+ available yet because no charting data has been collected for it since it
+ was created.
+ [% ELSE %]
+ No charting data has been collected yet.
+ [% END %]
+ Please wait a day and try again.
+ If you're seeing this message after a day, then you should contact
+ <a href="mailto:[% Param('maintainer') %]">[% Param('maintainer') %]</a>
+ and reference this error.
+
+ [% ELSIF error == "chart_datafile_corrupt" %]
+ The chart data file [% file FILTER html %] is corrupt.
+
+ [% ELSIF error == "chart_dir_nonexistent" %]
+ One of the directories <tt>[% dir FILTER html %]</tt> and
+ <tt>[% graph_dir FILTER html %]</tt> does not exist.
+
+ [% ELSIF error == "chart_file_open_fail" %]
+ Unable to open the chart datafile <tt>[% filename FILTER html %]</tt>.
+
+ [% ELSIF error == "column_alter_nonexistent_fk" %]
+ You attempted to modify the foreign key for
+ [%+ table FILTER html %].[% column FILTER html %], but there is
+ no foreign key on that column.
+
+ [% ELSIF error == "column_not_null_without_default" %]
+ Failed adding the column [% name FILTER html %]:
+ You cannot add a NOT NULL column with no default to an existing table
+ unless you specify something for the <code>$init_value</code> argument.
+
+ [% ELSIF error == "column_not_null_no_default_alter" %]
+ You cannot alter the [% name FILTER html %] column to be NOT NULL
+ without specifying a default or something for $set_nulls_to, because
+ there are NULL values currently in it.
+
+ [% ELSIF error == "comment_extra_data_not_allowed" %]
+ You tried to set the <code>extra_data</code> field to
+ '[% extra_data FILTER html %]' but comments of type [% type FILTER html %]
+ do not accept an <code>extra_data</code> argument.
+
+ [% ELSIF error == "comment_extra_data_required" %]
+ Comments of type [% type FILTER html %] require an <code>extra_data</code>
+ argument to be set.
+
+ [% ELSIF error == "comment_extra_data_not_numeric" %]
+ You tried to set the <code>extra_data</code> field to
+ '[% extra_data FILTER html %]' but comments of type [% type FILTER html %]
+ require a numeric <code>extra_data</code> argument.
+
+ [% ELSIF error == "comment_type_invalid" %]
+ '[% type FILTER html %]' is not a valid comment type.
+
+ [% ELSIF error == "db_rename_conflict" %]
+ Name conflict: Cannot rename [% old FILTER html %] to
+ [%+ new FILTER html %] because [% new FILTER html %] already exists.
+
+ [% ELSIF error == "cookies_need_value" %]
+ Every cookie must have a value.
+
+ [% ELSIF error == "env_no_email" %]
+ [% terms.Bugzilla %] did not receive an email address from the
+ environment.
+ [% IF Param("auth_env_email") %]
+ This means that the '[% Param("auth_env_email") FILTER html %]'
+ environment variable was empty or did not exist.
+ [% ELSE %]
+ You need to set the "auth_env_email" parameter to the name of
+ the environment variable that will contain the user's email
+ address.
+ [% END %]
+
+ [% ELSIF error == "extension_must_be_subclass" %]
+ <code>[% package FILTER html %]</code> from
+ <code>[% filename FILTER html %]</code> is not a subclass of
+ <code>[% class FILTER html %]</code>.
+
+ [% ELSIF error == "extension_must_return_name" %]
+ <code>[% extension FILTER html %]</code> returned
+ <code>[% returned FILTER html %]</code>, which is not a valid name
+ for an extension. Extensions must return their name, not <code>1</code>
+ or a number. See the documentation of
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/Extension.html">Bugzilla::Extension</a>
+ for details.
+
+ [% ELSIF error == "extension_no_name" %]
+ We did not find a <code>NAME</code> method in
+ <code>[% package FILTER html %]</code> (loaded from
+ <code>[% filename FILTER html %]</code>). This means that
+ the extension has one or more of the following problems:
+
+ <ul>
+ <li><code>[% filename FILTER html %]</code> did not define a
+ <code>[% package FILTER html %]</code> package.</li>
+ <li><code>[% package FILTER html %]</code> did not define a
+ <code>NAME</code> method (or the <code>NAME</code> method
+ returned an empty string).</li>
+ </ul>
+
+ [% ELSIF error == "extern_id_conflict" %]
+ The external ID '[% extern_id FILTER html %]' already exists
+ in the database for '[% username FILTER html %]', but your
+ account source says that '[% extern_user FILTER html %]' has that ID.
+
+ [% ELSIF error == "field_choice_must_use_type" %]
+ When you call a class method on <code>Bugzilla::Field::Choice</code>,
+ you must call <code>Bugzilla::Field::Choice-&gt;type('some_field')</code>
+ to generate the right class (you can't call class methods directly
+ on Bugzilla::Field::Choice).
+
+ [% ELSIF error == "field_not_custom" %]
+ '[% field.description FILTER html %]' ([% field.name FILTER html %])
+ is not a custom field.
+
+ [% ELSIF error == "field_type_not_specified" %]
+ [% title = "Field Type Not Specified" %]
+ You must specify a type when creating a custom field.
+
+ [% ELSIF error == "illegal_field" %]
+ A legal [% field FILTER html %] was not set.
+
+ [% ELSIF error == "invalid_customfield_type" %]
+ [% title = "Invalid Field Type" %]
+ The type <em>[% type FILTER html %]</em> is not a valid field type.
+
+ [% ELSIF error == "invalid_feature" %]
+ [% title = "Invalid Feature Name" %]
+ [% feature FILTER html %] is not a valid feature name. See
+ <code>OPTIONAL_MODULES</code> in
+ <code>Bugzilla::Install::Requirements</code> for valid names.
+
+ [% ELSIF error == "invalid_flag_association" %]
+ [% title = "Invalid Flag Association" %]
+ Some flags do not belong to
+ [% IF attach_id %]
+ attachment [% attach_id FILTER html %].
+ [% ELSE %]
+ [%+ terms.bug %] [%+ bug_id FILTER html %].
+ [% END %]
+
+ [% ELSIF error == "invalid_series_id" %]
+ [% title = "Invalid Series" %]
+ The series_id [% series_id FILTER html %] is not valid. It may be that
+ this series has been deleted.
+
+ [% ELSIF error == "invalid_timestamp" %]
+ The entered timestamp <code>[% timestamp FILTER html %]</code> could not
+ be parsed into a valid date and time.
+
+ [% ELSIF error == "invalid_webservergroup" %]
+ There is no such group: [% group FILTER html %]. Check your $webservergroup
+ setting in [% constants.bz_locations.localconfig FILTER html %].
+
+ [% ELSIF error == "flag_unexpected_object" %]
+ [% title = "Object Not Recognized" %]
+ Flags cannot be set for objects of type [% caller FILTER html %].
+ They can only be set for [% terms.bugs %] and attachments.
+
+ [% ELSIF error == "flag_type_inactive" %]
+ [% title = "Inactive Flag Type" %]
+ The flag type [% type FILTER html %] is inactive and cannot be used
+ to create new flags.
+
+ [% ELSIF error == "flag_type_target_type_invalid" %]
+ The target type was neither <em>[% terms.bug %]</em> nor <em>attachment</em>
+ but rather <em>[% target_type FILTER html %]</em>.
+
+ [% ELSIF error == "invalid_field_name" %]
+ Can't use [% field FILTER html %] as a field name.
+
+ [% ELSIF error == "jobqueue_insert_failed" %]
+ [% title = "Job Queue Failure" %]
+ Inserting a <code>[% job FILTER html %]</code> job into the Job
+ Queue failed with the following error: [% errmsg FILTER html %]
+
+ [% ELSIF error == "jobqueue_no_job_mapping" %]
+ <code>Bugzilla::JobQueue</code> has not been configured to handle
+ the job "[% job FILTER html %]". You need to add this job type
+ to the <code>JOB_MAP</code> constant in <code>Bugzilla::JobQueue</code>,
+ perhaps by using the 'job_map' hook.
+
+ [% ELSIF error == "ldap_bind_failed" %]
+ Failed to bind to the LDAP server. The error message was:
+ <code>[% errstr FILTER html %]</code>
+
+ [% ELSIF error == "ldap_cannot_retreive_attr" %]
+ The specified LDAP attribute [% attr FILTER html %] was not found.
+
+ [% ELSIF error == "ldap_connect_failed" %]
+ Could not connect to the LDAP server(s) <code>[% server FILTER html %]</code>.
+
+ [% ELSIF error == "ldap_start_tls_failed" %]
+ Could not start TLS with LDAP server: <code>[% error FILTER html %]</code>.
+
+ [% ELSIF error == "ldap_search_error" %]
+ An error occurred while trying to search LDAP for
+ &quot;[% username FILTER html %]&quot;:
+ [% IF errstr %]
+ <code>[% errstr FILTER html %]</code>
+ [% ELSE %]
+ Unable to find user in LDAP
+ [% END %]
+
+ [% ELSIF error == "ldap_server_not_defined" %]
+ The LDAP server for authentication has not been defined.
+
+ [% ELSIF error == "mail_send_error" %]
+ There was an error sending mail from '[% mail.header('From') FILTER html %]'
+ to '[% mail.header('To') FILTER html %]':
+ [%+ msg FILTER html %]
+
+ [% ELSIF error == "missing_series_id" %]
+ Having inserted a series into the database, no series_id was returned for
+ it. Series: [% series.category FILTER html %] /
+ [%+ series.subcategory FILTER html %] /
+ [%+ series.name FILTER html %].
+
+ [% ELSIF error == "object_dep_sort_loop" %]
+ There is a loop in VALIDATOR_DEPENDENCIES involving
+ '[%+ field FILTER html %]'. Here are the fields we considered:
+ [%+ considered.join(', ') FILTER html %].
+
+ [% ELSIF error == "param_invalid" %]
+ [% title = "Invalid Parameter" %]
+ <code>[% param FILTER html %]</code> is not a valid parameter
+ for the [% function FILTER html %] function.
+
+ [% ELSIF error == "param_must_be_numeric" %]
+ [% title = "Invalid Parameter" %]
+ Invalid parameter <code>[% param FILTER html %]</code> passed to
+ <code>[% function FILTER html %]</code>: It must be numeric.
+
+ [% ELSIF error == "param_required" %]
+ [% title = "Missing Parameter" %]
+ The function <code>[% function FILTER html %]</code> requires
+ a <code>[% param FILTER html %]</code> argument, and that
+ argument was not set.
+
+ [% ELSIF error == "params_required" %]
+ [% title = "Missing Parameter" %]
+ The function <code>[% function FILTER html %]</code> requires
+ that you set one of the following parameters:
+ <code>[% params.join(', ') FILTER html %]</code>
+
+ [% ELSIF error == "product_empty_group_controls" %]
+ [% title = "Missing Group Controls" %]
+ New settings must be defined to edit group controls for
+ the [% group.name FILTER html %] group.
+
+ [% ELSIF error == "product_illegal_group_control" %]
+ [% title = "Illegal Group Control" %]
+ '[% value FILTER html %]' is not a legal value for
+ the '[% field FILTER html %]' field.
+
+ [% ELSIF error == "protection_violation" %]
+ The function <code>[% function FILTER html %]</code> was called
+
+ [% IF argument %]
+ with the argument <code>[% argument FILTER html %]</code>
+ [% END %]
+
+ from
+
+ [% IF caller %]
+ <code>[%+ caller FILTER html %]</code>, which is
+ [% END %]
+
+ outside the package. This function may only be called from
+ a subclass of <code>[% superclass FILTER html %]</code>.
+
+ [% ELSIF error == "radius_preparation_error" %]
+ An error occurred while preparing for a RADIUS authentication request:
+ <code>[% errstr FILTER html %]</code>.
+
+ [% ELSIF error == "search_cp_without_op" %]
+ Search argument f[% id FILTER html %] is "CP" but there is no
+ matching "OP" before it.
+
+ [% ELSIF error == "search_invalid_joiner" %]
+ '[% joiner FILTER html %]' is not a valid joiner for a search.
+
+ [% ELSIF error == "setting_info_invalid" %]
+ To create a new setting, you must supply a setting name, a list of
+ value/sortindex pairs, and the default value.
+
+ [% ELSIF error == "setting_name_invalid" %]
+ The setting name <em>[% name FILTER html %]</em> is not a valid
+ option. Setting names must begin with a letter, and contain only
+ letters, digits, or the symbols '_', '-', '.', or ':'.
+
+ [% ELSIF error == "setting_subclass_invalid" %]
+ There is no such Setting subclass as
+ <code>[% subclass FILTER html %]</code>.
+
+ [% ELSIF error == "setting_value_invalid" %]
+ The value "<code>[% value FILTER html %]</code>" is not in the list of
+ legal values for the <em>[% name FILTER html %]</em> setting.
+
+ [% ELSIF error == "token_generation_error" %]
+ Something is seriously wrong with the token generation system.
+
+ [% ELSIF error == "cancel_token_does_not_exist" %]
+ The token to be cancelled does not exist.
+
+ [% ELSIF error == "template_error" %]
+ [% template_error_msg FILTER html %]
+
+ [% ELSIF error == "template_invalid" %]
+ Template with invalid file name found in hook call: [% name FILTER html %].
+
+ [% ELSIF error == "unable_to_retrieve_password" %]
+ I was unable to retrieve your old password from the database.
+
+ [% ELSIF error == "undefined_field" %]
+ Form field [% field FILTER html %] was not defined.
+
+ [% ELSIF error == "unknown_method" %]
+ The requested method '[% method FILTER html %]' was not found.
+
+ [% ELSIF error == "usage_mode_invalid" %]
+ '[% invalid_usage_mode FILTER html %]' is not a valid usage mode.
+
+ [% ELSIF error == "must_be_patch" %]
+ [% title = "Attachment Must Be Patch" %]
+ Attachment #[% attach_id FILTER html %] must be a patch.
+
+ [% ELSIF error == "not_in_transaction" %]
+ Attempted to end transaction without starting one first.
+
+ [% ELSIF error == "invalid_post_bug_submit_action" %]
+ Invalid setting for post_bug_submit_action
+
+ [% ELSIF error == "search_field_operator_unsupported" %]
+ [% terms.Bugzilla %] does not support the search type
+ "[% operator FILTER html %]".
+
+ [% ELSE %]
+ [%# Try to find hooked error messages %]
+ [% error_message = Hook.process("errors") %]
+ [% IF NOT error_message %]
+ [% title = "Internal error" %]
+ An internal error has occurred, but [% terms.Bugzilla %] doesn't know
+ what <code>[% error FILTER html %]</code> means.
+
+ If you are a [% terms.Bugzilla %] end-user seeing this message, please save
+ this page and send it to [% Param('maintainer') %].
+ [% ELSE %]
+ [% error_message FILTER none %]
+ [% END %]
+ [% END %]
+[% END %]
+
+[%# We only want HTML error messages for ERROR_MODE_WEBPAGE %]
+[% USE Bugzilla %]
+[% IF Bugzilla.error_mode != constants.ERROR_MODE_WEBPAGE %]
+ [% IF Bugzilla.usage_mode == constants.USAGE_MODE_BROWSER %]
+ [% error_message FILTER none %]
+ [% ELSE %]
+ [% error_message FILTER txt %]
+ [% END %]
+ [% RETURN %]
+[% END %]
+
+[% UNLESS header_done %]
+ [% PROCESS global/header.html.tmpl %]
+[% END %]
+
+[% PROCESS global/docslinks.html.tmpl
+ docslinks = docslinks
+ admindocslinks = admindocslinks
+%]
+
+<p>
+ An unexpected error occurred. This could be a temporary problem, or some code
+ is behaving incorrectly. If this problem persists, please email this page
+ to <a href="mailto:[% Param("maintainer") %]">[% Param("maintainer") %]</a>
+ with details of what you were doing at the time this message appeared.
+</p>
+
+<tt>
+ <script type="text/javascript"> <!--
+ document.write("<p>URL: " +
+ document.location.href.replace(/&/g,"&amp;")
+ .replace(/</g,"&lt;")
+ .replace(/>/g,"&gt;") + "</p>");
+ // -->
+ </script>
+</tt>
+
+<table cellpadding="20">
+ <tr>
+ <td id="error_msg" class="throw_error">
+ [% error_message FILTER none %]
+ </td>
+ </tr>
+</table>
+
+<p>Traceback:</p>
+<pre>[% traceback FILTER html %]</pre>
+
+[% IF variables %]
+ <pre>
+Variables:
+ [% FOREACH key = variables.keys %]
+ [%+ key FILTER html %]: [%+ variables.$key FILTER html %]
+ [% END %]
+ </pre>
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/global/common-links.html.tmpl b/template/en/default/global/common-links.html.tmpl
new file mode 100644
index 0000000..800fd59
--- /dev/null
+++ b/template/en/default/global/common-links.html.tmpl
@@ -0,0 +1,111 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% DEFAULT qs_suffix = "" %]
+[% USE Bugzilla %]
+
+<ul class="links">
+ <li><a href="./">Home</a></li>
+ <li><span class="separator">| </span><a href="enter_bug.cgi">New</a></li>
+ <li><span class="separator">| </span><a href="describecomponents.cgi">Browse</a></li>
+ <li><span class="separator">| </span><a href="query.cgi">Search</a></li>
+
+ <li class="form">
+ <span class="separator">| </span>
+ <form action="buglist.cgi" method="get"
+ onsubmit="if (this.quicksearch.value == '')
+ { alert('Please enter one or more search terms first.');
+ return false; } return true;">
+ <input type="hidden" id="no_redirect[% qs_suffix FILTER html %]" name="no_redirect" value="0">
+ <script type="text/javascript">
+ if (history && history.replaceState) {
+ var no_redirect = document.getElementById("no_redirect[% qs_suffix FILTER js %]");
+ no_redirect.value = 1;
+ }
+ </script>
+ <input class="txt" type="text" id="quicksearch[% qs_suffix FILTER html %]" name="quicksearch"
+ title="Quick Search" value="[% quicksearch FILTER html %]">
+ <input class="btn" type="submit" value="Search"
+ id="find[% qs_suffix FILTER html %]">
+ [%-# Work around FF bug: keep this on one line %]</form>
+ <a href="page.cgi?id=quicksearch.html" title="Quicksearch Help">[?]</a></li>
+
+ <li><span class="separator">| </span><a href="report.cgi">Reports</a></li>
+
+ <li>
+ [% IF Param('shutdownhtml') || Bugzilla.has_flags %]
+ <span class="separator">| </span>
+ [% IF user.id %]
+ <a href="request.cgi?requester=[% user.login FILTER uri %]&amp;requestee=
+ [% user.login FILTER uri %]&amp;do_union=1&amp;group=type&amp;action=queue">My Requests</a>
+ [% ELSE %]
+ <a href="request.cgi">Requests</a>
+ [% END %]
+ [% END %]
+ [%-# Work around FF bug: keep this on one line %]</li>
+
+ [% IF user.login %]
+ <li><span class="separator">| </span><a href="userprefs.cgi">Preferences</a></li>
+ [% IF user.in_group('tweakparams') || user.in_group('editusers') || user.can_bless
+ || (Param('useclassification') && user.in_group('editclassifications'))
+ || user.in_group('editcomponents') || user.in_group('admin') || user.in_group('creategroups')
+ || user.in_group('editkeywords') || user.in_group('bz_canusewhines')
+ || user.get_products_by_permission("editcomponents").size %]
+ <li><span class="separator">| </span><a href="admin.cgi">Administration</a></li>
+ [% END %]
+
+ [% PROCESS link_to_documentation %]
+
+ <li>
+ <span class="separator">| </span>
+ [% IF user.authorizer.can_logout %]
+ <a href="index.cgi?logout=1">Log&nbsp;out</a>
+ [% ELSE %]
+ Logged&nbsp;in&nbsp;as
+ [% END %]
+ [% IF sudoer %]
+ [%+ sudoer.login FILTER html %] (<b>impersonating
+ [%+ user.login FILTER html %]</b>
+ <a href="relogin.cgi?action=end-sudo">end session</a>)
+ [% ELSE %]
+ [%+ user.login FILTER html %]
+ [% END %]
+ [%-# Work around FF bug: keep this on one line %]</li>
+ [% ELSE %]
+
+ [% PROCESS link_to_documentation %]
+
+ [% IF Param('createemailregexp')
+ && user.authorizer.user_can_create_account %]
+ <li id="new_account_container[% qs_suffix FILTER html %]">
+ <span class="separator">| </span>
+ <a href="createaccount.cgi">New&nbsp;Account</a>
+ </li>
+ [% END %]
+
+ [%# Only display one login form when we're on a LOGIN_REQUIRED page. That
+ # way, we're guaranteed that the user will use the form that has
+ # hidden_fields in it (the center form) instead of this one. Also, it's
+ # less confusing to have one form (as opposed to three) when you're
+ # required to log in.
+ #%]
+ [% IF user.authorizer.can_login && !Bugzilla.page_requires_login %]
+ [% PROCESS "account/auth/login-small.html.tmpl" %]
+ [% END %]
+ [% END %]
+</ul>
+
+[% Hook.process("link-row") %]
+[% BLOCK link_to_documentation %]
+ [% IF doc_section && Param('docs_urlbase') %]
+ <li>
+ <span class="separator">| </span>
+ <a href="[% docs_urlbase _ doc_section FILTER html %]" target="_blank">Help</a>
+ </li>
+ [% END %]
+[% END %]
diff --git a/template/en/default/global/confirm-action.html.tmpl b/template/en/default/global/confirm-action.html.tmpl
new file mode 100644
index 0000000..9d89d8c
--- /dev/null
+++ b/template/en/default/global/confirm-action.html.tmpl
@@ -0,0 +1,53 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # script_name: the script generating this warning.
+ # token: a valid token for the current action.
+ # reason: reason of the failure.
+ #%]
+
+[% PROCESS global/header.html.tmpl title = "Suspicious Action"
+ style_urls = ['skins/standard/global.css'] %]
+
+<div class="throw_error">
+<!--reason=[%reason FILTER html %]-->
+ [% IF reason == "expired_token" %]
+ Your changes have been rejected because you exceeded the time limit
+ of [% constants.MAX_TOKEN_AGE FILTER html %] days before submitting your
+ changes to [% script_name FILTER html %]. Your page may have been displayed
+ for too long, or old changes have been resubmitted by accident.
+
+ [% ELSIF reason == "missing_token" %]
+ It looks like you didn't come from the right page.
+ One reason could be that you entered the URL in the address bar of your
+ web browser directly, which should be safe. Another reason could be that
+ you clicked on a URL which redirected you here <b>without your consent</b>.
+
+ [% ELSIF reason == "invalid_token" %]
+ You submitted changes to [% script_name FILTER html %] with an invalid
+ token, which may indicate that someone tried to abuse you, for instance
+ by making you click on a URL which redirected you here <b>without your
+ consent</b>.
+ [% END %]
+ <p>
+ Are you sure you want to commit these changes?
+ </p>
+</div>
+
+<form name="check" id="check" method="post" action="[% script_name FILTER html %]">
+ [% PROCESS "global/hidden-fields.html.tmpl"
+ exclude="^(Bugzilla_login|Bugzilla_password|token)$" %]
+ <input type="hidden" name="token" value="[% token FILTER html %]">
+ <input type="submit" id="confirm" value="Yes, Confirm Changes">
+</form>
+
+<p><a href="index.cgi">No, throw away these changes</a> (you will be redirected
+to the home page).</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/global/confirm-user-match.html.tmpl b/template/en/default/global/confirm-user-match.html.tmpl
new file mode 100644
index 0000000..c31567a
--- /dev/null
+++ b/template/en/default/global/confirm-user-match.html.tmpl
@@ -0,0 +1,191 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # fields: hash/record; the fields being matched, each of which has:
+ # type: single|multi: whether or not the user can select multiple matches
+ # flag_type: for flag requestee fields, the type of flag being requested
+ # matches: hash; Hierarchical. The levels go like this:
+ # field_name {
+ # pattern_text {
+ # 'users' = @user_list (user objects)
+ # 'status' = success|fail|trunc (result of search.
+ # 'trunc' (truncated) means max was reached)
+ # }
+ # }
+ # script: string; The name of the calling script, used to create a
+ # self-referential URL
+ #%]
+
+[%# This lists fields which use the user auto-completion feature and which
+ # are not listed in field_descs. %]
+[% field_labels = { # Used by editcomponents.cgi
+ "initialcc" => "Default CC List",
+ "initialowner" => "Default Assignee",
+ "initialqacontact" => "Default QA Contact",
+ # Used by process_bug.cgi
+ "masscc" => "CC List",
+ # Used by request.cgi
+ "requester" => "Requester",
+ "requestee" => "Requestee",
+ # Used by userprefs.cgi
+ "new_watchedusers" => "Watch List",
+
+ }
+%]
+[% IF matchsuccess == 1 %]
+ [% PROCESS global/header.html.tmpl title="Confirm Match" %]
+
+ [% USE Bugzilla %]
+
+ <form method="post"
+ [% IF script -%]
+ action="[% script %]"
+ [%- END -%]
+ [% IF Bugzilla.cgi.param("data") %]
+ enctype="multipart/form-data"
+ [% END %]
+ >
+
+ <p>
+ [% IF matchmultiple %]
+ [% terms.Bugzilla %] cannot make a conclusive match for one or more
+ of the names and/or email addresses you entered on the previous page.
+ <br>Please examine the lists of potential matches below and select the
+ ones you want,
+ [% ELSE %]
+ [% terms.Bugzilla %] is configured to require verification whenever
+ you enter a name or partial email address.
+ <br>Below are the names/addresses you entered and the matched accounts.
+ Please confirm that they are correct,
+ [% END %]
+ or go back to the previous page to revise the names you entered.
+ </p>
+[% ELSE %]
+ [% PROCESS global/header.html.tmpl title="Match Failed" %]
+ <p>
+ [% terms.Bugzilla %] was unable to make any match at all for one or more of
+ the names and/or email addresses you entered on the previous page.
+ [% IF !user.id %]
+ <b>Note: You are currently logged out. Only exact matches against e-mail
+ addresses will be performed.</b>
+ [% END %]
+ </p>
+ <p>Please go back and try other names or email addresses.</p>
+[% END %]
+
+ <table border="0">
+ <tr>
+ <td colspan="2">
+ <hr width="100%" size="1">
+ </td>
+ </tr>
+
+ [%# this is messy to allow later expansion %]
+
+ [% FOREACH field = matches %]
+ <tr>
+ <td align="left" valign="top">
+ [% PROCESS field_names field_name=field.key %]:
+ </td>
+ <td align="left" valign="top">
+ [% FOREACH query = field.value %]
+ <div class="user_match">
+ <b>[% query.key FILTER html %]</b>
+ [% IF query.value.users.size %]
+ [% IF query.value.users.size > 1 %]
+ [% IF query.value.status == 'fail' %]
+ <font color="#FF0000">
+ matches multiple users.
+ </font>
+ Please go back and try again with a more specific
+ name/address.
+ [% ELSE %]
+ [% IF query.value.status == 'trunc' %]
+ matched
+ more than the maximum
+ of [% query.value.users.size %] users:<br>
+ [% ELSE %]
+ matched:<br>
+ [% END %]
+ <select name="[% field.key FILTER html %]"
+ id="[% field.key FILTER html %]"
+ [% IF fields.${field.key}.type == 'multi' %]
+ multiple="multiple"
+ [% IF query.value.users.size > 5 %]
+ size="5"
+ [% ELSE %]
+ size="[% query.value.users.size %]"
+ [% END %]
+ [% END %]
+ >
+ [% FOREACH match = query.value.users %]
+ <option value="[% match.login FILTER html %]">
+ [%- match.identity FILTER html -%]
+ </option>
+ [% END %]
+ </select>
+ [% END %]
+ [% ELSE %]
+ matched
+ <b>[% query.value.users.0.identity FILTER html %]</b>
+ [% END %]
+ [% ELSE %]
+ [% IF query.key.length < 3 %]
+ <font color="#FF0000">was too short for substring match
+ (minimum 3 characters)</font>
+ [% ELSE %]
+ <font color="#FF0000">did not match anything</font>
+ [% END %]
+ [% END %]
+ </div>
+ [% END %]
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <hr width="100%" size="1">
+ </td>
+ </tr>
+ [% END %]
+
+ </table>
+
+[% IF matchsuccess == 1 %]
+
+ [% SET exclude_these = ['Bugzilla_login', 'Bugzilla_password'] %]
+ [% FOREACH key IN matches.keys %]
+ [% exclude_these.push(key) IF cgi.param(key) == '' %]
+ [% END %]
+ [% SET exclude = '^' _ exclude_these.join('|') _ '$' %]
+ [% PROCESS "global/hidden-fields.html.tmpl" exclude = exclude %]
+
+ <p>
+ <input type="submit" id="continue" value="Continue">
+ </p>
+
+ </form>
+
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
+
+
+[% BLOCK field_names %]
+
+ [% IF field_descs.$field_name %]
+ [% field_descs.$field_name FILTER html %]
+ [% ELSIF field_labels.$field_name %]
+ [% field_labels.$field_name FILTER html %]
+ [% ELSIF field_name.match("^requestee") %]
+ [% fields.${field_name}.flag_type.name FILTER html %] requestee
+ [% ELSE %]
+ [% field_name FILTER html %]
+ [% END %]
+
+[% END %]
diff --git a/template/en/default/global/docslinks.html.tmpl b/template/en/default/global/docslinks.html.tmpl
new file mode 100644
index 0000000..c2cc830
--- /dev/null
+++ b/template/en/default/global/docslinks.html.tmpl
@@ -0,0 +1,45 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # docslinks: hash. Hash keys will be used as text of the documentation links,
+ # hash values will be used as links to the document, relative to
+ # the main Bugzilla documentation directory.
+ # Example: If you want a 'FAQ' link to point to, the "faq-general"
+ # named anchor on faq.html, assign
+ # { 'FAQ' => "faq.html#faq-general" }
+ # to docslinks.
+ # You may only link to sections by their given ID; it is not allowed
+ # to link to a section which is not given an ID (thus getting
+ # assigned an automatically generated ID). Otherwise, the link
+ # would break on a recompilation of the documentation.
+ # admindocslinks: hash. Same as docslinks, but will only be displayed to
+ # members of the admin group.
+ #%]
+
+[% IF Param('docs_urlbase') &&
+ docslinks.keys.size || (admindocslinks.keys.size && user.in_group('admin')) %]
+ <div id="docslinks">
+ <h2>Related documentation</h2>
+ <ul>
+ [% IF user.in_group('admin') %]
+ [% PROCESS docslinkslist docstype = admindocslinks %]
+ [% END %]
+ [% PROCESS docslinkslist docstype = docslinks %]
+ </ul>
+ </div>
+[% END %]
+
+[% BLOCK docslinkslist %]
+ [% FOREACH docslink = docstype.keys %]
+ <li>
+ <a href="[% docs_urlbase FILTER html %]
+ [% docslink FILTER none %]">[% docstype.$docslink FILTER html %]</a>
+ </li>
+ [% END %]
+[% END %]
diff --git a/template/en/default/global/field-descs.none.tmpl b/template/en/default/global/field-descs.none.tmpl
new file mode 100644
index 0000000..f1e0747
--- /dev/null
+++ b/template/en/default/global/field-descs.none.tmpl
@@ -0,0 +1,142 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# Remember to PROCESS rather than INCLUDE this template. %]
+
+[% SET search_descs = {
+ "noop" => "---",
+ "equals" => "is equal to",
+ "notequals" => "is not equal to",
+ "anyexact" => "is equal to any of the strings",
+ "substring" => "contains the string",
+ "casesubstring" => "contains the string (exact case)",
+ "notsubstring" => "does not contain the string",
+ "anywordssubstr" => "contains any of the strings",
+ "allwordssubstr" => "contains all of the strings",
+ "nowordssubstr" => "contains none of the strings",
+ "regexp" => "matches regular expression",
+ "notregexp" => "does not match regular expression",
+ "lessthan" => "is less than",
+ "lessthaneq" => "is less than or equal to",
+ "greaterthan" => "is greater than",
+ "greaterthaneq" => "is greater than or equal to",
+ "anywords" => "contains any of the words",
+ "allwords" => "contains all of the words",
+ "nowords" => "contains none of the words",
+ "changedbefore" => "changed before",
+ "changedafter" => "changed after",
+ "changedfrom" => "changed from",
+ "changedto" => "changed to",
+ "changedby" => "changed by",
+ "matches" => "matches",
+ "notmatches" => "does not match",
+} %]
+
+[% field_types = { ${constants.FIELD_TYPE_UNKNOWN} => "Unknown Type",
+ ${constants.FIELD_TYPE_FREETEXT} => "Free Text",
+ ${constants.FIELD_TYPE_SINGLE_SELECT} => "Drop Down",
+ ${constants.FIELD_TYPE_MULTI_SELECT} => "Multiple-Selection Box",
+ ${constants.FIELD_TYPE_TEXTAREA} => "Large Text Box",
+ ${constants.FIELD_TYPE_DATETIME} => "Date/Time",
+ ${constants.FIELD_TYPE_BUG_ID} => "$terms.Bug ID",
+ } %]
+
+[% IF in_template_var %]
+ [% PROCESS "global/value-descs.none.tmpl" %]
+ [% SET vars.value_descs = value_descs %]
+ [% SET vars.terms = terms %]
+
+ [%# field_descs is loaded as a global template variable and cached
+ # across all templates--see VARIABLES in Bugzilla/Template.pm.
+ #%]
+ [% vars.field_descs = {
+ "[Bug creation]" => "[$terms.Bug creation]",
+ "actual_time" => "Actual Hours",
+ "alias" => "Alias",
+ "assigned_to" => "Assignee",
+ "assigned_to_realname" => "Assignee Real Name",
+ "attach_data.thedata" => "Attachment data",
+ "attachments.description" => "Attachment description",
+ "attachments.filename" => "Attachment filename",
+ "attachments.mimetype" => "Attachment mime type",
+ "attachments.ispatch" => "Attachment is patch",
+ "attachments.isobsolete" => "Attachment is obsolete",
+ "attachments.isprivate" => "Attachment is private",
+ "attachments.submitter" => "Attachment creator",
+ "blocked" => "Blocks",
+ "bug_file_loc" => "URL",
+ "bug_group" => "Group",
+ "bug_id" => "$terms.Bug ID",
+ "bug_severity" => "Severity",
+ "bug_status" => "Status",
+ "changeddate" => "Changed",
+ "cc" => "CC",
+ "classification" => "Classification",
+ "cclist_accessible" => "CC list accessible",
+ "commenter" => "Commenter",
+ "component_id" => "Component ID",
+ "component" => "Component",
+ "content" => "Content",
+ "creation_ts" => "Creation date",
+ "days_elapsed" => "Days since $terms.bug changed",
+ "deadline" => "Deadline",
+ "delta_ts" => "Changed",
+ "dependson" => "Depends on",
+ "dup_id" => "Duplicate",
+ "estimated_time" => "Orig. Est.",
+ "everconfirmed" => "Ever confirmed",
+ "flagtypes.name" => "Flags",
+ "keywords" => "Keywords",
+ "longdesc" => "Comment",
+ "longdescs.count" => "Number of Comments",
+ "longdescs.isprivate" => "Comment is private",
+ "newcc" => "CC",
+ "op_sys" => "OS",
+ "opendate" => "Opened",
+ "owner_idle_time" => "Time Since Assignee Touched",
+ "percentage_complete" => "%Complete",
+ "priority" => "Priority",
+ "product_id" => "Product ID",
+ "product" => "Product",
+ "qa_contact" => "QA Contact",
+ "qa_contact_realname" => "QA Contact Real Name",
+ "remaining_time" => "Hours Left",
+ "rep_platform" => "Hardware",
+ "reporter" => "Reporter",
+ "reporter_accessible" => "Reporter accessible",
+ "reporter_realname" => "Reporter Real Name",
+ "requestees.login_name" => "Flag Requestee",
+ "resolution" => "Resolution",
+ "see_also" => "See Also",
+ "setters.login_name" => "Flag Setter",
+ "setting" => "Setting",
+ "settings" => "Settings",
+ "short_desc" => "Summary",
+ "short_short_desc" => "Summary",
+ "status_whiteboard" => "Whiteboard",
+ "tag" => "Tags",
+ "target_milestone" => "Target Milestone",
+ "version" => "Version",
+ "work_time" => "Hours Worked",
+ } %]
+
+ [%# Also include any custom fields or fields which don't have a
+ Description here, by copying their Description from the
+ database. If you want to override this for your language
+ or your installation, just use a hook. %]
+ [% UNLESS Param('shutdownhtml') %]
+ [% FOREACH bz_field = bug_fields.values %]
+ [% SET vars.field_descs.${bz_field.name} = bz_field.description
+ IF !vars.field_descs.${bz_field.name}.defined %]
+ [% END %]
+ [% END %]
+
+ [% PROCESS "bug/field-help.none.tmpl" %]
+[% END %]
+
+[% Hook.process("end") %]
diff --git a/template/en/default/global/footer.html.tmpl b/template/en/default/global/footer.html.tmpl
new file mode 100644
index 0000000..e161a06
--- /dev/null
+++ b/template/en/default/global/footer.html.tmpl
@@ -0,0 +1,36 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # This template has no interface. However, you must fulfill the interface to
+ # global/useful-links.html.tmpl.
+ #%]
+
+ [% Hook.process('main-end') %]
+</div>
+
+[%# Migration note: below this point, this file corresponds to the old Param
+ # 'footerhtml'
+ #%]
+
+<div id="footer">
+ <div class="intro">[% Hook.process('intro') %]</div>
+
+[%# Migration note: the old param 'blurbhtml' goes here %]
+
+[%# Migration note: useful-links.html.tmpl corresponds to %commandmenu% %]
+
+ [% PROCESS "global/useful-links.html.tmpl" %]
+
+ <div class="outro">[% Hook.process('outro') %]</div>
+</div>
+
+[% Hook.process("end") %]
+
+</body>
+</html>
diff --git a/template/en/default/global/header.html.tmpl b/template/en/default/global/header.html.tmpl
new file mode 100644
index 0000000..dceb44d
--- /dev/null
+++ b/template/en/default/global/header.html.tmpl
@@ -0,0 +1,313 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # (All the below interface elements are optional.)
+ # title: string. Page title.
+ # header: string. Main page header.
+ # subheader: string. Page subheader.
+ # header_addl_info: string. Additional header information.
+ # bodyclasses: array of extra CSS classes for the <body>
+ # onload: string. JavaScript code to run when the page finishes loading.
+ # javascript: string. Javascript to go in the header.
+ # javascript_urls: list. List of URLs to Javascript.
+ # style: string. CSS style.
+ # style_urls: list. List of URLs to CSS style sheets.
+ # message: string. A message to display to the user. May contain HTML.
+ # atomlink: Atom link URL, May contain HTML
+ #%]
+
+[% IF message %]
+ [% PROCESS global/messages.html.tmpl %]
+[% END %]
+
+[% DEFAULT
+ subheader = ""
+ header_addl_info = ""
+ onload = ""
+ style_urls = []
+ yui = []
+%]
+
+[% SET yui_css = {
+ autocomplete => 1,
+ calendar => 1,
+ datatable => 1,
+ button => 1,
+} %]
+
+[%# Note: This is simple dependency resolution--you can't have dependencies
+ # that depend on each other. You have to specify all of a module's deps,
+ # if that module is going to be specified in "yui".
+ #%]
+[% SET yui_deps = {
+ autocomplete => ['json', 'connection', 'datasource'],
+ datatable => ['json', 'connection', 'datasource', 'element'],
+} %]
+
+[%# When using certain YUI modules, we need to process certain
+ # extra JS templates.
+ #%]
+[% SET yui_templates = {
+ datatable => ['global/value-descs.js.tmpl'],
+} %]
+
+[%# These are JS URLs that are *always* on the page and come before
+ # every other JS URL.
+ #%]
+[% SET starting_js_urls = [
+ "js/yui/yahoo-dom-event/yahoo-dom-event.js",
+ "js/yui/cookie/cookie-min.js",
+] %]
+
+
+[%# We should be able to set the default value of the header variable
+ # to the value of the title variable using the DEFAULT directive,
+ # but that doesn't work if a caller sets header to the empty string
+ # to avoid header inheriting the value of title, since DEFAULT
+ # mistakenly treats empty strings as undefined and gives header the
+ # value of title anyway. To get around that problem we explicitly
+ # set header's default value here only if it is undefined. %]
+[% IF !header.defined %][% header = title %][% END %]
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+ <head>
+ [% Hook.process("start") %]
+ <title>[% title %]</title>
+
+ [% IF Param('utf8') %]
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ [% END %]
+
+[%# Migration note: contents of the old Param 'headerhtml' would go here %]
+
+ [% PROCESS "global/site-navigation.html.tmpl" %]
+
+ [% PROCESS 'global/setting-descs.none.tmpl' %]
+
+ [% SET yui = yui_resolve_deps(yui, yui_deps) %]
+ [% SET css_sets = css_files(style_urls, yui, yui_css) %]
+
+ [%# CSS cascade, parts 1 & 2: YUI & Standard Bugzilla stylesheet set (persistent).
+ # Always present. %]
+ <link href="[% 'skins/standard/global.css' FILTER mtime FILTER html %]"
+ rel="alternate stylesheet"
+ title="[% setting_descs.standard FILTER html %]">
+ [% FOREACH style_url = css_sets.standard %]
+ [% PROCESS format_css_link css_set_name = 'standard' %]
+ [% END %]
+
+ [%# CSS cascade, part 3: Third-party stylesheet set, per user prefs. %]
+ [% FOREACH style_url = css_sets.skin %]
+ [% PROCESS format_css_link css_set_name = user.settings.skin.value %]
+ [% END %]
+
+ [%# CSS cascade, part 4: page-specific styles. %]
+ [% IF style %]
+ <style type="text/css">
+ [% style %]
+ </style>
+ [% END %]
+
+ [%# CSS cascade, part 5: Custom Bugzilla stylesheet set (persistent).
+ # Always present. Site administrators may override all other style
+ # definitions, including skins, using custom stylesheets.
+ #%]
+ [% FOREACH style_url = css_sets.custom %]
+ [% PROCESS format_css_link css_set_name = 'standard' %]
+ [% END %]
+
+ [%# YUI Scripts %]
+ [% FOREACH yui_name = yui %]
+ [% starting_js_urls.push("js/yui/$yui_name/${yui_name}-min.js") %]
+ [% END %]
+ [% starting_js_urls.push('js/global.js') %]
+
+ [% FOREACH javascript_url = starting_js_urls %]
+ [% PROCESS format_js_link %]
+ [% END %]
+
+ <script type="text/javascript">
+ <!--
+ YAHOO.namespace('bugzilla');
+ YAHOO.util.Event.addListener = function (el, sType, fn, obj, overrideContext) {
+ if ( ("onpagehide" in window || YAHOO.env.ua.gecko) && sType === "unload") { sType = "pagehide"; };
+ var capture = ((sType == "focusin" || sType == "focusout") && !YAHOO.env.ua.ie) ? true : false;
+ return this._addListener(el, this._getType(sType), fn, obj, overrideContext, capture);
+ };
+ if ( "onpagehide" in window || YAHOO.env.ua.gecko) {
+ YAHOO.util.Event._simpleRemove(window, "unload",
+ YAHOO.util.Event._unload);
+ }
+ [%# The language selector needs javascript to set its cookie,
+ # so it is hidden in HTML/CSS by the "bz_default_hidden" class.
+ # If the browser can run javascript, it will then "unhide"
+ # the language selector using the following code.
+ #%]
+ function unhide_language_selector() {
+ YAHOO.util.Dom.removeClass(
+ 'lang_links_container', 'bz_default_hidden'
+ );
+ }
+ YAHOO.util.Event.onDOMReady(unhide_language_selector);
+
+ [%# Make some Bugzilla information available to all scripts.
+ # We don't import every parameter and constant because we
+ # don't want to add a lot of uncached JS to every page.
+ #%]
+ var BUGZILLA = {
+ param: {
+ cookiepath: '[% Param('cookiepath') FILTER js %]',
+ maxusermatches: [% Param('maxusermatches') FILTER js %]
+ },
+ constant: {
+ COMMENT_COLS: [% constants.COMMENT_COLS FILTER js %]
+ },
+ string: {
+ [%# Please keep these in alphabetical order. %]
+
+ attach_desc_required:
+ 'You must enter a Description for this attachment.',
+ component_required:
+ 'You must select a Component for this [% terms.bug %].',
+ description_required:
+ 'You must enter a Description for this [% terms.bug %].',
+ short_desc_required:
+ 'You must enter a Summary for this [% terms.bug %].',
+ version_required:
+ 'You must select a Version for this [% terms.bug %].'
+ }
+ };
+
+ [% FOREACH yui_name = yui %]
+ [% FOREACH yui_template = yui_templates.$yui_name %]
+ [% INCLUDE $yui_template %]
+ [% END %]
+ [% END %]
+ [% IF javascript %]
+ [% javascript %]
+ [% END %]
+ // -->
+ </script>
+
+ [% FOREACH javascript_url = javascript_urls %]
+ [% PROCESS format_js_link %]
+ [% END %]
+
+ [%# this puts the live bookmark up on firefox for the Atom feed %]
+ [% IF atomlink %]
+ <link rel="alternate"
+ type="application/atom+xml" title="Atom feed"
+ href="[% atomlink FILTER html %]">
+ [% END %]
+
+ [%# Required for the 'Autodiscovery' feature in Firefox 2 and IE 7. %]
+ <link rel="search" type="application/opensearchdescription+xml"
+ title="[% terms.Bugzilla %]" href="./search_plugin.cgi">
+ <link rel="shortcut icon" href="images/favicon.ico" >
+ [% Hook.process("additional_header") %]
+ </head>
+
+[%# Migration note: contents of the old Param 'bodyhtml' go in the body tag,
+ # but set the onload attribute in the DEFAULT directive above.
+ #%]
+
+ <body onload="[% onload %]"
+ class="[% urlbase.replace('^https?://','').replace('/$','').replace('[-~@:/.]+','-') FILTER css_class_quote %]
+ [% FOREACH class = bodyclasses %]
+ [% ' ' %][% class FILTER css_class_quote %]
+ [% END %] yui-skin-sam">
+
+[%# Migration note: the following file corresponds to the old Param
+ # 'bannerhtml'
+ #%]
+
+<div id="header">
+
+[% INCLUDE global/banner.html.tmpl %]
+
+<table border="0" cellspacing="0" cellpadding="0" id="titles">
+<tr>
+ <td id="title">
+ <p>[% terms.Bugzilla %]
+ [% " &ndash; $header" IF header %]</p>
+ </td>
+
+ [% IF subheader %]
+ <td id="subtitle">
+ <p class="subheader">[% subheader %]</p>
+ </td>
+ [% END %]
+
+ [% IF header_addl_info %]
+ <td id="information">
+ <p class="header_addl_info">[% header_addl_info %]</p>
+ </td>
+ [% END %]
+</tr>
+</table>
+
+<table id="lang_links_container" cellpadding="0" cellspacing="0"
+ class="bz_default_hidden"><tr><td>
+[% IF Bugzilla.languages.size > 1 %]
+ <ul class="links">
+ [% FOREACH lang = Bugzilla.languages.sort %]
+ <li>[% IF NOT loop.first %]<span class="separator"> | </span>[% END %]
+ [% IF lang == current_language %]
+ <span class="lang_current">[% lang FILTER html FILTER upper %]</span>
+ [% ELSE %]
+ <a href="#" onclick="set_language('[% lang FILTER none %]');">
+ [%- lang FILTER html FILTER upper %]</a>
+ [% END %]
+ </li>
+ [% END %]
+ </ul>
+[% END %]
+</td></tr></table>
+
+[% PROCESS "global/common-links.html.tmpl" qs_suffix = "_top" %]
+</div> [%# header %]
+
+<div id="bugzilla-body">
+
+[% IF Param('announcehtml') %]
+[% Param('announcehtml') FILTER none %]
+[% END %]
+
+[% IF message %]
+ <div id="message">[% message %]</div>
+[% END %]
+
+[% BLOCK format_css_link %]
+ [% IF style_url.match('/IE-fixes\.css') %]
+ <!--[if lte IE 7]>
+ [%# Internet Explorer treats [if IE] HTML comments as uncommented.
+ # We use it to import CSS fixes so that Bugzilla looks decent on IE 7
+ # and below.
+ #%]
+ [% END %]
+
+ [% IF css_set_name == 'standard' %]
+ [% SET css_title_link = '' %]
+ [% ELSE %]
+ [% css_title_link = BLOCK ~%]
+ title="[% setting_descs.${user.settings.skin.value} || user.settings.skin.value FILTER html %]"
+ [% END %]
+ [% END %]
+
+ <link href="[% style_url FILTER html %]" rel="stylesheet"
+ type="text/css" [% css_title_link FILTER none %]>
+
+ [% '<![endif]-->' IF style_url.match('/IE-fixes\.css') %]
+[% END %]
+
+[% BLOCK format_js_link %]
+ <script type="text/javascript" src="[% javascript_url FILTER mtime FILTER html %]"></script>
+[% END %]
diff --git a/template/en/default/global/hidden-fields.html.tmpl b/template/en/default/global/hidden-fields.html.tmpl
new file mode 100644
index 0000000..88d2673
--- /dev/null
+++ b/template/en/default/global/hidden-fields.html.tmpl
@@ -0,0 +1,46 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # exclude: string; a regular expression matching fields to exclude
+ # from the list of hidden fields generated by this template
+ #%]
+
+[%# The global Bugzilla->cgi object is used to obtain form variable values. %]
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+[%# Generate hidden form fields for non-excluded fields. %]
+[% FOREACH field = cgi.param() %]
+ [% NEXT IF exclude && field.search(exclude) %]
+ [%# The '.slice(0)' bit is here to force the 'param(field)' to be evaluated
+ in a list context, so we can avoid extra code checking for single valued or
+ empty fields %]
+ [% IF field == "data" && cgi.param("data") %]
+ <div class="box">
+ <p>
+ We were unable to store the file you uploaded because of incomplete information
+ in the form you just submitted. Because we are unable to retain the file between
+ form submissions, you must re-attach the file in addition to completing the
+ remaining missing information above.
+ </p>
+ <p>
+ Please re-attach the file <b>[% cgi.param(field) FILTER html %]</b> in
+ the field below:
+ </p>
+ <p>
+ <input type="file" id="data" name="data" size="50">
+ </p>
+ </div>
+ [% ELSE %]
+ [% FOREACH mvalue = cgi.param(field).slice(0) %]
+ <input type="hidden" name="[% field FILTER html %]"
+ value="[% mvalue FILTER html_linebreak %]">
+ [% END %]
+ [% END %]
+[% END %]
diff --git a/template/en/default/global/js-products.html.tmpl b/template/en/default/global/js-products.html.tmpl
new file mode 100644
index 0000000..e40a3e3
--- /dev/null
+++ b/template/en/default/global/js-products.html.tmpl
@@ -0,0 +1,21 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# The javascript block gets used in header.html.tmpl. %]
+[% javascript = BLOCK %]
+ var useclassification = false; // No classification level in use
+ var first_load = true; // Is this the first time we load the page?
+ var last_sel = []; // Caches last selection
+ var cpts = new Array();
+ [% n = 1 %]
+ [% FOREACH prod = products %]
+ cpts['[% n %]'] = [
+ [%- FOREACH comp = prod.components %]'[% comp.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ];
+ [% n = n+1 %]
+ [% END %]
+[% END %]
diff --git a/template/en/default/global/message.html.tmpl b/template/en/default/global/message.html.tmpl
new file mode 100644
index 0000000..949fc1e
--- /dev/null
+++ b/template/en/default/global/message.html.tmpl
@@ -0,0 +1,28 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # url: string. An optional URL to go to.
+ # link: string. The link text for that URL.
+ #%]
+
+[% DEFAULT title = "$terms.Bugzilla Message" %]
+
+[% PROCESS global/header.html.tmpl %]
+
+[%# The "header" template automatically displays a message if it finds one.
+ Note that the global messages list is in messages.html.tmpl. %]
+
+[%# Display a URL if the calling script or message block has included one. %]
+[% IF url && link %]
+ <p>
+ <a href="[% url FILTER html %]">[% link FILTER html %]</a>
+ </p>
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/global/message.txt.tmpl b/template/en/default/global/message.txt.tmpl
new file mode 100644
index 0000000..44694ee
--- /dev/null
+++ b/template/en/default/global/message.txt.tmpl
@@ -0,0 +1,12 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# Yes, this may show some HTML. But it's the best we
+ # can do at the moment. %]
+[% PROCESS global/messages.html.tmpl %]
+[% message FILTER txt %]
diff --git a/template/en/default/global/messages.html.tmpl b/template/en/default/global/messages.html.tmpl
new file mode 100644
index 0000000..f55ab92
--- /dev/null
+++ b/template/en/default/global/messages.html.tmpl
@@ -0,0 +1,927 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# This is a list of all the possible messages. Please keep them in
+ # alphabetical order by message tag, and leave a blank line between messages.
+ #%]
+
+[% message_tag = message %]
+
+[% message = BLOCK %]
+ [% IF message_tag == "account_created" %]
+ The user account [% otheruser.login FILTER html %] has been created
+ successfully.
+ [% IF groups.size %]
+ You may want to edit the group settings now, using the form below.
+ [% END %]
+
+ [% ELSIF message_tag == "account_creation_canceled" %]
+ [% title = "User Account Creation Canceled" %]
+ The creation of the user account [% account FILTER html %] has been
+ canceled.
+
+ [% ELSIF message_tag == "account_updated" %]
+ [% IF changed_fields.size
+ + groups_added_to.size + groups_removed_from.size
+ + groups_granted_rights_to_bless.size + groups_denied_rights_to_bless.size %]
+ [% title = "User $loginold updated" %]
+ The following changes have been made to the user account
+ [%+ loginold FILTER html %]:
+ <ul>
+ [% FOREACH field = changed_fields %]
+ <li>
+ [% IF field == 'login_name' %]
+ The login is now [% otheruser.login FILTER html %].
+ [% ELSIF field == 'realname' %]
+ The real name has been updated.
+ [% ELSIF field == 'cryptpassword' %]
+ A new password has been set.
+ [% ELSIF field == 'disabledtext' %]
+ The "login disabled" text has been modified.
+ [% ELSIF field == 'is_enabled' %]
+ Logging in with this user account has been [% otheruser.is_enabled ? 'enabled' : 'disabled' %].
+ [% ELSIF field == 'extern_id' %]
+ The user's External Login ID has been modified.
+ [% ELSIF field == 'disable_mail' %]
+ [% IF otheruser.email_disabled %]
+ [% terms.Bug %]mail has been disabled.
+ [% ELSE %]
+ [% terms.Bug %]mail has been enabled.
+ [% END %]
+ [% END %]
+ </li>
+ [% END %]
+ [% IF groups_added_to.size %]
+ <li>
+ The account has been added to the following group[% 's' IF groups_added_to.size > 1 %]:
+ [%+ groups_added_to.join(', ') FILTER html %]
+ </li>
+ [% END %]
+ [% IF groups_removed_from.size %]
+ <li>
+ The account has been removed from the following group[% 's' IF groups_removed_from.size > 1 %]:
+ [%+ groups_removed_from.join(', ') FILTER html %]
+ </li>
+ [% END %]
+ [% IF groups_granted_rights_to_bless.size %]
+ <li>
+ The account has been granted rights to bless the
+ [%+ groups_granted_rights_to_bless.join(', ') FILTER html %]
+ group[% 's' IF groups_granted_rights_to_bless.size > 1 %].
+ </li>
+ [% END %]
+ [% IF groups_denied_rights_to_bless.size %]
+ <li>
+ The account has been denied rights to bless the
+ [%+ groups_denied_rights_to_bless.join(', ') FILTER html %]
+ group[% 's' IF groups_denied_rights_to_bless.size > 1 %].
+ </li>
+ [% END %]
+ </ul>
+ [% ELSE %]
+ [% title = "User $otheruser.login not changed" %]
+ You didn't request any changes to the user's account
+ [%+ otheruser.login FILTER html %].
+ [% END %]
+
+ [% ELSIF message_tag == "account_deleted" %]
+ [% title = "User $otheruser.login deleted" %]
+ The user account [% otheruser.login FILTER html %] has been deleted
+ successfully.
+
+ [% ELSIF message_tag == "account_disabled" %]
+ Logging in with this user account [% account FILTER html %] is disabled, so
+ you cannot change its password.
+
+ [% ELSIF message_tag == "attachment_creation_failed" %]
+ The [% terms.bug %] was created successfully, but attachment creation
+ failed.
+ Please add your attachment by clicking the "Add an Attachment" link
+ below.
+
+ [% ELSIF message_tag == "bug_group_description" %]
+ Access to [% terms.bugs %] in the [% product.name FILTER html %] product
+
+ [% ELSIF message_tag == "buglist_adding_field" %]
+ [% title = "Adding field to search page..." %]
+ [% link = "Click here if the page does not redisplay automatically." %]
+
+ [% ELSIF message_tag == "buglist_updated_named_query" %]
+ [% title = "Search updated" %]
+ Your search named <code><a
+ href="buglist.cgi?cmdtype=runnamed&amp;namedcmd=[% queryname FILTER uri %]"
+ >[% queryname FILTER html %]</a></code> has been updated.
+
+ [% ELSIF message_tag == "buglist_new_default_query" %]
+ OK, you now have a new default search. You may
+ also bookmark the result of any individual search.
+
+ [% ELSIF message_tag == "buglist_new_named_query" %]
+ [% title = "Search created" %]
+ OK, you have a new search named <code><a
+ href="buglist.cgi?cmdtype=runnamed&amp;namedcmd=[% queryname FILTER uri %]"
+ >[% queryname FILTER html %]</a></code>.
+
+ [% ELSIF message_tag == "buglist_query_gone" %]
+ [% title = "Search is gone" %]
+ [% link = "Un-forget the search" %]
+ OK, the <b>[% namedcmd FILTER html %]</b> search is gone.
+
+ [% ELSIF message_tag == "buglist_sorted_by_relevance" %]
+ [% terms.Bugs %] on this list are sorted by relevance, with the most
+ relevant [% terms.bugs %] at the top.
+
+ [% ELSIF message_tag == "change_columns" %]
+ [% title = "Change columns" %]
+ Resubmitting your search with new columns...
+ Click <a href="[% redirect_url FILTER html %]">here</a>
+ if the page does not automatically refresh.
+
+ [% ELSIF message_tag == "classification_created" %]
+ [% title = "New Classification Created" %]
+ The <em>[% classification.name FILTER html %]</em> classification has been created.
+
+ [% ELSIF message_tag == "classification_deleted" %]
+ [% title = "Classification Deleted" %]
+ The <em>[% classification.name FILTER html %]</em> classification has been deleted.
+
+ [% ELSIF message_tag == "classification_updated" %]
+ [% title = "Classification Updated" %]
+ [% IF changes.keys.size %]
+ Changes to the <em>[% classification.name FILTER html %]</em> classification
+ have been saved:
+ <ul>
+ [% IF changes.name.defined %]
+ <li>Name updated to '[% classification.name FILTER html %]'</li>
+ [% END %]
+ [% IF changes.description.defined %]
+ [% IF classification.description %]
+ <li>Description updated to '[% classification.description FILTER html %]'</li>
+ [% ELSE %]
+ <li>Description removed</li>
+ [% END %]
+ [% END %]
+ [% IF changes.sortkey.defined %]
+ <li>Sortkey updated to '[% classification.sortkey FILTER html %]'</li>
+ [% END %]
+ [% Hook.process('classification_updated_fields') %]
+ </ul>
+ [% ELSE %]
+ No changes made to <em>[% classification.name FILTER html %]</em>.
+ [% END %]
+
+ [% ELSIF message_tag == "component_created" %]
+ [% title = "Component Created" %]
+ The component <em>[% comp.name FILTER html %]</em> has been created.
+
+ [% ELSIF message_tag == "component_deleted" %]
+ [% title = "Component Deleted" %]
+ The component <em>[% comp.name FILTER html %]</em> has been deleted.
+ [% IF comp.bug_count %]
+ All [% terms.bugs %] being in this component and all references
+ to them have also been deleted.
+ [% END %]
+
+ [% ELSIF message_tag == "component_updated" %]
+ [% title = "Component Updated" %]
+ [% IF changes.keys.size %]
+ Changes to the component <em>[% comp.name FILTER html %]</em> have been saved:
+ <ul>
+ [% IF changes.name.defined %]
+ <li>Name updated to '[% comp.name FILTER html %]'</li>
+ [% END %]
+ [% IF changes.description.defined %]
+ <li>Description updated to '[% comp.description FILTER html_light %]'</li>
+ [% END %]
+ [% IF changes.initialowner.defined %]
+ <li>Default assignee updated to '[% comp.default_assignee.login FILTER html %]'</li>
+ [% END %]
+ [% IF changes.initialqacontact.defined %]
+ [% IF comp.default_qa_contact %]
+ <li>Default QA contact updated to '[% comp.default_qa_contact.login FILTER html %]'</li>
+ [% ELSE %]
+ <li>Default QA contact deleted</li>
+ [% END %]
+ [% END %]
+ [% IF changes.cc_list.defined %]
+ [% IF comp.initial_cc.size %]
+ [% cc_list = [] %]
+ [% FOREACH cc_user = comp.initial_cc %]
+ [% cc_list.push(cc_user.login) %]
+ [% END %]
+ <li>Default CC list updated to [% cc_list.join(", ") FILTER html %]</li>
+ [% ELSE %]
+ <li>Default CC list deleted</li>
+ [% END %]
+ [% END %]
+ [% IF changes.isactive.defined %]
+ <li>[% comp.is_active ? "Enabled" : "Disabled" %] for [% terms.bugs %]</li>
+ [% END %]
+ [% Hook.process('component_updated_fields') %]
+ </ul>
+ [% ELSE %]
+ No changes made to <em>[% comp.name FILTER html %]</em>.
+ [% END %]
+
+ [% ELSIF message_tag == "custom_field_created" %]
+ [% title = "Custom Field Created" %]
+ The new custom field '[% field.name FILTER html %]' has been
+ successfully created.
+
+ [% ELSIF message_tag == "custom_field_deleted" %]
+ [% title = "Custom Field Deleted" %]
+ The custom field '[% field.name FILTER html %]' has been
+ successfully deleted.
+
+ [% ELSIF message_tag == "custom_field_updated" %]
+ [% title = "Custom Field Updated" %]
+ Properties of the '[% field.name FILTER html %]' field have been
+ successfully updated.
+
+ [% ELSIF message_tag == "default_settings_updated" %]
+ [% IF changes_saved %]
+ Changes to default preferences have been saved.
+ [% ELSE %]
+ No changes made.
+ [% END %]
+
+ [% ELSIF message_tag == "emailold_change_canceled" %]
+ [% title = "Cancel Request to Change Email Address" %]
+ The request to change the email address for your account to
+ [%+ new_email FILTER html %] has been canceled.
+
+ [% ELSIF message_tag == "email_change_canceled" %]
+ [% title = "Cancel Request to Change Email Address" %]
+ The request to change the email address for the
+ account [%+ old_email FILTER html %] to
+ [%+ new_email FILTER html %] has been canceled.
+
+ [% ELSIF message_tag == "email_change_canceled_reinstated" %]
+ [% title = "Cancel Request to Change Email Address" %]
+ The request to change the email address for the
+ account [%+ old_email FILTER html %] to
+ [%+ new_email FILTER html %] has been canceled.
+ Your old account settings have been reinstated.
+
+ [% ELSIF message_tag == "extension_created" %]
+ An extension named [% name FILTER html %] has been created
+ in [% path FILTER html %].
+
+ [% ELSIF message_tag == "field_value_created" %]
+ [% title = "New Field Value Created" %]
+ The value <em>[% value.name FILTER html %]</em> has been added as a
+ valid choice for the <em>[% field.description FILTER html %]</em>
+ (<em>[% field.name FILTER html %]</em>) field.
+ [% IF field.name == "bug_status" %]
+ You should now visit the <a href="editworkflow.cgi">status workflow
+ page</a> to include your new [% terms.bug %] status.
+ [% END %]
+
+ [% ELSIF message_tag == "field_value_deleted" %]
+ [% title = "Field Value Deleted" %]
+ The value <em>[% value.name FILTER html %]</em> of the
+ <em>[% field.description FILTER html %]</em>
+ (<em>[% field.name FILTER html %]</em>) field has been deleted.
+
+ [% ELSIF message_tag == "field_value_updated" %]
+ [% title = "Field Value Updated" %]
+ [% IF changes.keys.size %]
+ The <em>[% value_old FILTER html %]</em> value of the
+ <em>[% field.description FILTER html %]</em>
+ (<em>[% field.name FILTER html %]</em>) field has been changed:
+ <ul>
+ [% IF changes.value %]
+ <li>Field value updated to
+ <em>[% changes.value.1 FILTER html %]</em>.
+ [% IF value.is_default %]
+ (Note that this value is the default for this field. All
+ references to the default value will now point to this new value.)
+ [% END %]
+ </li>
+ [% END %]
+ [% IF changes.sortkey %]
+ <li>Sortkey updated to
+ <em>[% changes.sortkey.1 FILTER html %]</em>.</li>
+ [% END %]
+ [% IF changes.visibility_value_id %]
+ [% IF value.visibility_value.defined %]
+ <li>It only appears when
+ [%+ value.field.value_field.description FILTER html %] is set to
+ '[%+ value.visibility_value.name FILTER html %]'.</li>
+ [% ELSE %]
+ <li>It now always appears, no matter what
+ [%+ value.field.value_field.description FILTER html %] is set to.
+ </li>
+ [% END %]
+ [% END %]
+ </ul>
+ [% ELSE %]
+ No changes made to the field value <em>[% value_old FILTER html %]</em>.
+ [% END %]
+
+ [% ELSIF message_tag == "flag_cleared" %]
+ Some flags didn't apply in the new product/component
+ and have been cleared.
+
+ [% ELSIF message_tag == "flag_creation_failed" %]
+ [% title = "Flag Creation Failure" %]
+ An error occured while validating flags:
+ [%+ flag_creation_error FILTER none %]
+
+ [% ELSIF message_tag == "get_field_desc" %]
+ [% field_descs.$field_name FILTER html %]
+
+ [% ELSIF message_tag == "get_resolution" %]
+ [% display_value("resolution", resolution) FILTER html %]
+
+ [% ELSIF message_tag == "get_status" %]
+ [% display_value("bug_status", status) FILTER html %]
+
+ [% ELSIF message_tag == "group_created" %]
+ [% title = "New Group Created" %]
+ The group <em>[% group.name FILTER html %]</em> has been created.
+
+ [% ELSIF message_tag == "group_deleted" %]
+ [% title = "Group Deleted" %]
+ The group <em>[% name FILTER html %]</em> has been deleted.
+
+ [% ELSIF message_tag == "group_membership_removed" %]
+ [% title = "Group Membership Removed" %]
+ [% IF users.size %]
+ Explicit membership to the <em>[% group FILTER html %]</em> group removed
+ [% IF regexp %] for users matching '[% regexp FILTER html %]'[% END %]:
+ [% FOREACH user = users %]
+ [%+ user.login FILTER html %]
+ [% END %]
+ [% ELSE %]
+ No users are being affected by your action.
+ [% END %]
+
+ [% ELSIF message_tag == "group_updated" %]
+ [% IF changes.keys.size %]
+ The following changes have been made to the '[% group.name FILTER html %]'
+ group:
+ <ul>
+ [% FOREACH field = changes.keys.sort %]
+ [% SWITCH field %]
+ [% CASE 'name' %]
+ <li>The name was changed to '[% changes.name.1 FILTER html %]'</li>
+ [% CASE 'description' %]
+ <li>The description was updated.</li>
+ [% CASE 'userregexp' %]
+ <li>The regular expression was updated.</li>
+ [% CASE 'isactive' %]
+ [% IF changes.isactive.1 %]
+ <li>The group will now be used for [% terms.bugs %].</li>
+ [% ELSE %]
+ <li>The group will no longer be used for [% terms.bugs %].</li>
+ [% END %]
+ [% CASE 'icon_url' %]
+ <li>The group icon URL has been updated.</li>
+ [% CASE 'members_add' %]
+ <li>The following groups are now members of this group:
+ [%+ changes.members_add.join(', ') FILTER html %]</li>
+ [% CASE 'members_remove' %]
+ <li>The following groups are no longer members of this group:
+ [%+ changes.members_remove.join(', ') FILTER html %]</li>
+ [% CASE 'member_of_add' %]
+ <li>This group is now a member of the following groups:
+ [%+ changes.member_of_add.join(', ') FILTER html %]</li>
+ [% CASE 'member_of_remove' %]
+ <li>This group is no longer a member of the following groups:
+ [%+ changes.member_of_remove.join(', ') FILTER html %]</li>
+ [% CASE 'bless_from_add' %]
+ <li>The following groups may now add users to this group:
+ [%+ changes.bless_from_add.join(', ') FILTER html %]</li>
+ [% CASE 'bless_from_remove' %]
+ <li>The following groups may no longer add users to this group:
+ [%+ changes.bless_from_remove.join(', ') FILTER html %]</li>
+ [% CASE 'bless_to_add' %]
+ <li>This group may now add users to the following groups:
+ [%+ changes.bless_to_add.join(', ') FILTER html %]</li>
+ [% CASE 'bless_to_remove' %]
+ <li>This group may no longer add users to the following groups:
+ [%+ changes.bless_to_remove.join(', ') FILTER html %]</li>
+ [% CASE 'visible_from_add' %]
+ <li>The following groups can now see users in this group:
+ [%+ changes.visible_from_add.join(', ') FILTER html %]</li>
+ [% CASE 'visible_from_remove' %]
+ <li>The following groups may no longer see users in this group:
+ [%+ changes.visible_from_remove.join(', ') FILTER html %]</li>
+ [% CASE 'visible_to_me_add' %]
+ <li>This group may now see users in the following groups:
+ [%+ changes.visible_to_me_add.join(', ') FILTER html %]</li>
+ [% CASE 'visible_to_me_remove' %]
+ <li>This group may no longer see users in the following groups:
+ [%+ changes.visible_to_me_remove.join(', ') FILTER html %]</li>
+ [% CASE %]
+ [% Hook.process('group_updated_fields') %]
+ [% END %]
+ [% END %]
+ </ul>
+ [% ELSE %]
+ You didn't request any change for the '[% group.name FILTER html %]'
+ group.
+ [% END %]
+
+ [% ELSIF message_tag == "invalid_column_name" %]
+ The custom sort order specified contains one or more invalid
+ column names: <em>[% invalid_fragments.join(', ') FILTER html %]</em>.
+ They have been removed from the sort list.
+
+ [% ELSIF message_tag == "job_queue_depth" %]
+ [% count FILTER html %] jobs in the queue.
+
+ [% ELSIF message_tag == "keyword_created" %]
+ [% title = "New Keyword Created" %]
+ The keyword <em>[% name FILTER html %]</em> has been created.
+
+ [% ELSIF message_tag == "keyword_deleted" %]
+ [% title = "Keyword Deleted" %]
+ The <em>[% keyword.name FILTER html %]</em> keyword has been deleted.
+
+ [% ELSIF message_tag == "keyword_updated" %]
+ [% title = "Keyword Updated" %]
+ [% IF changes.keys.size %]
+ Changes to the <em>[% keyword.name FILTER html %]</em> keyword have
+ been saved:
+ <ul>
+ [% IF changes.name.defined %]
+ <li>Keyword renamed to <em>[% keyword.name FILTER html %]</em>.</li>
+ [% END %]
+ [% IF changes.description.defined %]
+ <li>Description updated to <em>[% keyword.description FILTER html %]</em></li>
+ [% END %]
+ </ul>
+ [% ELSE %]
+ No changes made.
+ [% END %]
+
+ [% ELSIF message_tag == "logged_out" %]
+ [% title = "Logged Out" %]
+ [% url = "index.cgi?GoAheadAndLogIn=1" %]
+ [% link = "Log in again." %]
+ <b>You logged out successfully</b>.
+ The cookie that was remembering your login is now gone. You will be
+ prompted for a login the next time it is required.
+
+ [% ELSIF message_tag == "login_changed" %]
+ [% title = "$terms.Bugzilla Login Changed" %]
+ Your [% terms.Bugzilla %] login has been changed.
+
+ [% ELSIF message_tag == "migrate_component_created" %]
+ Component created: [% comp.name FILTER html %]
+ (in [% product.name FILTER html %])
+
+ [% ELSIF message_tag == "migrate_creating_bugs" %]
+ Creating [% terms.bugs %]...
+
+ [% ELSIF message_tag == "migrate_field_created" %]
+ New custom field: [% field.description FILTER html %]
+ ([% field.name FILTER html %])
+
+ [% ELSIF message_tag == "migrate_product_created" %]
+ Product created: [% created.name FILTER html %]
+
+ [% ELSIF message_tag == "migrate_reading_bugs" %]
+ Reading [% terms.bugs %]...
+
+ [% ELSIF message_tag == "migrate_reading_products" %]
+ Reading products...
+
+ [% ELSIF message_tag == "migrate_reading_users" %]
+ Reading users...
+
+ [% ELSIF message_tag == "migrate_translating_bugs" %]
+ Converting [% terms.bug %] values to be appropriate for
+ [%+ terms.Bugzilla %]...
+
+ [% ELSIF message_tag == "migrate_user_created" %]
+ User created: [% created.email FILTER html %]
+ [% IF password %] Password: [% password FILTER html %][% END %]
+
+ [% ELSIF message_tag == "migrate_value_created" %]
+ [% IF product.defined %]
+ [% product.name FILTER html %]
+ [% END %]
+ [%+ field_descs.${field.name} FILTER html %] value
+ created: [% value FILTER html %]
+
+ [% ELSIF message_tag == "milestone_created" %]
+ [% title = "Milestone Created" %]
+ The milestone <em>[% milestone.name FILTER html %]</em> has been created.
+
+ [% ELSIF message_tag == "milestone_deleted" %]
+ [% title = "Milestone Deleted" %]
+ The milestone <em>[% milestone.name FILTER html %]</em> has been deleted.
+ [% IF milestone.bug_count %]
+ [%+ terms.Bugs %] targetted to this milestone have been retargetted to
+ the default milestone <em>[% product.default_milestone FILTER html %]</em>.
+ [% END %]
+
+ [% ELSIF message_tag == "milestone_updated" %]
+ [% title = "Milestone Updated" %]
+ [% IF changes.size %]
+ Changes to the milestone <em>[% milestone.name FILTER html %]</em>
+ have been saved:
+ <ul>
+ [% IF changes.value.defined %]
+ <li>Milestone name updated to <em>[% milestone.name FILTER html %]</em></li>
+ [% END %]
+ [% IF changes.sortkey.defined %]
+ <li>Sortkey updated to <em>[% milestone.sortkey FILTER html %]</em>
+ [% END %]
+ [% IF changes.isactive.defined %]
+ <li>[% milestone.is_active ? "Enabled" : "Disabled" %] for [% terms.bugs %]</li>
+ [% END %]
+ </ul>
+ [% ELSE %]
+ No changes made to milestone <em>[% milestone.name FILTER html %]</em>.
+ [% END %]
+
+ [% ELSIF message_tag == "parameters_updated" %]
+ [% title = "Parameters Updated" %]
+ [% IF param_changed.size > 0 %]
+ [% FOREACH param = param_changed %]
+ Changed <em>[% param FILTER html %]</em><br>
+ [% IF param == 'utf8' && Param('utf8') %]
+ <strong>You must now re-run <kbd>checksetup.pl</kbd>.</strong><br>
+ [% END %]
+ [% END %]
+ [% ELSE %]
+ No changes made.
+ [% END %]
+
+ [% IF shutdown_is_active == 1 %]
+ <hr>
+ [% terms.Bugzilla %] has now been shut down. To re-enable the system,
+ clear the <em>shutdownhtml</em> field.
+ [% END%]
+
+ [% ELSIF message_tag == "password_change_canceled" %]
+ [% title = "Cancel Request to Change Password" %]
+ Your request has been canceled.
+
+ [% ELSIF message_tag == "password_change_request" %]
+ [% title = "Request to Change Password" %]
+ A token for changing your password has been emailed to you.
+ Follow the instructions in that email to change your password.
+
+ [% ELSIF message_tag == "password_changed" %]
+ [% title = "Password Changed" %]
+ Your password has been changed.
+
+ [% ELSIF message_tag == "flag_type_created" %]
+ [% title = BLOCK %]Flag Type '[% name FILTER html %]' Created[% END %]
+ The flag type <em>[% name FILTER html %]</em> has been created.
+
+ [% ELSIF message_tag == "flag_type_updated" %]
+ [% title = BLOCK %]Flag Type '[% flagtype.name FILTER html %]' Updated[% END %]
+ [% IF changes.size %]
+ Changes to the flag type <em>[% flagtype.name FILTER html %]</em>
+ have been saved:
+ <ul>
+ [% IF changes.is_active.defined %]
+ <li>Flag type is now [% flagtype.is_active ? "active" : "inactive" %]</li>
+ [% END %]
+ [% IF changes.name.defined %]
+ <li>Flag type renamed to <em>[% flagtype.name FILTER html %]</em></li>
+ [% END %]
+ [% IF changes.description.defined %]
+ <li>Description updated to <em>[% flagtype.description FILTER html %]</em></li>
+ [% END %]
+ [% IF changes.cc_list.defined %]
+ [% IF flagtype.cc_list %]
+ <li>CC list updated to <em>[% flagtype.cc_list FILTER html %]</em></li>
+ [% ELSE %]
+ <li>CC list is now empty</li>
+ [% END %]
+ [% END %]
+ [% IF changes.sortkey.defined %]
+ <li>Sortkey updated to <em>[% flagtype.sortkey FILTER html %]</em></li>
+ [% END %]
+ [% IF changes.is_requestable.defined %]
+ <li>Flag type is [% "no longer" UNLESS flagtype.is_requestable %] requestable</li>
+ [% END %]
+ [% IF changes.is_requesteeble.defined AND flagtype.is_requestable %]
+ <li>
+ Flag type is [% "no longer" UNLESS flagtype.is_requesteeble %]
+ specifically requestable
+ </li>
+ [% END %]
+ [% IF changes.is_multiplicable.defined %]
+ <li>Flag type is [% "no longer" UNLESS flagtype.is_multiplicable %] multiplicable</li>
+ [% END %]
+ [% IF changes.grant_group_id.defined %]
+ [% IF flagtype.grant_group_id %]
+ <li>Grant group updated to <em>[% flagtype.grant_group.name FILTER html %]</em></li>
+ [% ELSE %]
+ <li>Grant group deleted</li>
+ [% END %]
+ [% END %]
+ [% IF changes.request_group_id.defined %]
+ [% IF flagtype.request_group_id %]
+ <li>Request group updated to <em>[% flagtype.request_group.name FILTER html %]</em></li>
+ [% ELSE %]
+ <li>Request group deleted</li>
+ [% END %]
+ [% END %]
+ [% IF changes.inclusions.defined || changes.exclusions.defined %]
+ <li>The inclusions and exclusions lists have been updated</li>
+ [% END %]
+ </ul>
+ [% ELSE %]
+ No changes made to flag type <em>[% flagtype.name FILTER html %]</em>.
+ [% END %]
+
+ [% ELSIF message_tag == "flag_type_deleted" %]
+ [% title = BLOCK %]Flag Type '[% name FILTER html %]' Deleted[% END %]
+ The flag type <em>[% name FILTER html %]</em> has been deleted.
+
+ [% ELSIF message_tag == "flag_type_deactivated" %]
+ [% title = BLOCK %]Flag Type '[% flag_type.name FILTER html %]' Deactivated[% END %]
+ The flag type <em>[% flag_type.name FILTER html %]</em> has been deactivated.
+
+ [% ELSIF message_tag == "install_admin_get_email" %]
+ Enter the e-mail address of the administrator:
+
+ [% ELSIF message_tag == "install_admin_get_name" %]
+ Enter the real name of the administrator:
+
+ [% ELSIF message_tag == "install_admin_get_password" %]
+ Enter a password for the administrator account:
+
+ [% ELSIF message_tag == "install_admin_created" %]
+ [% user.login FILTER html %] is now set up as an administrator.
+
+ [% ELSIF message_tag == "install_admin_setup" %]
+ Looks like we don't have an administrator set up yet.
+ Either this is your first time using [% terms.Bugzilla %], or your
+ administrator's privileges might have accidentally been deleted.
+
+ [% ELSIF message_tag == "install_column_add" %]
+ Adding new column '[% column FILTER html %]' to the '[% table FILTER html %]' table...
+
+ [% ELSIF message_tag == "install_column_drop" %]
+ Deleting the '[% column FILTER html %]' column from the '[% table FILTER html %]' table...
+
+ [% ELSIF message_tag == "install_column_rename" %]
+ Renaming column '[% old FILTER html %]' to '[% new FILTER html %]'...
+
+ [% ELSIF message_tag == "install_confirm_password" %]
+ Please retype the password to verify:
+
+ [% ELSIF message_tag == "install_default_classification" %]
+ Creating default classification '[% name FILTER html %]'...
+
+ [% ELSIF message_tag == "install_default_product" %]
+ Creating initial dummy product '[% name FILTER html %]'...
+
+ [% ELSIF message_tag == "install_file_perms_fix" %]
+ Fixing file permissions...
+
+ [% ELSIF message_tag == "install_fk_add" %]
+ Adding foreign key: [% table FILTER html %].[% column FILTER html %] -&gt; [% fk.TABLE FILTER html %].[% fk.COLUMN FILTER html %]...
+
+ [% ELSIF message_tag == "install_fk_drop" %]
+ Dropping foreign key: [% table FILTER html %].[% column FILTER html %] -&gt; [% fk.TABLE FILTER html %].[% fk.COLUMN FILTER html %]...
+
+ [% ELSIF message_tag == "install_fk_invalid" %]
+ ERROR: There are invalid values for the [% column FILTER html %] column in the [% table FILTER html %]
+ table. (These values do not exist in the [% foreign_table FILTER html %] table, in the
+ [%+ foreign_column FILTER html %] column.)
+
+ Before continuing with checksetup, you will need to fix these values,
+ either by deleting these rows from the database, or changing the values
+ of [% column FILTER html %] in [% table FILTER html %] to point to valid values in [% foreign_table FILTER html %].[% foreign_column FILTER html %].
+
+ The bad values from the [% table FILTER html %].[% column FILTER html %] column are:
+ [%+ values.join(', ') FILTER html %]
+
+ [% ELSIF message_tag == "install_fk_invalid_fixed" %]
+ WARNING: There were invalid values in [% table FILTER html %].[% column FILTER html %]
+ that have been [% IF action == 'delete' %]deleted[% ELSE %]set to NULL[% END %]:
+ [%+ values.join(', ') FILTER html %]
+
+ [% ELSIF message_tag == "install_fk_setup" %]
+ Setting up foreign keys...
+
+ [% ELSIF message_tag == "install_group_create" %]
+ Creating group [% name FILTER html %]...
+
+ [% ELSIF message_tag == "install_groups_setup" %]
+ Creating default groups...
+
+ [% ELSIF message_tag == "install_setting_new" %]
+ Adding a new user setting called '[% name FILTER html %]'
+
+ [% ELSIF message_tag == "install_setting_setup" %]
+ Setting up user preferences...
+
+ [% ELSIF message_tag == "install_success" %]
+ checksetup.pl complete.
+
+ [% ELSIF message_tag == "install_table_drop" %]
+ Dropping the '[% name FILTER html %]' table...
+
+ [% ELSIF message_tag == "install_table_rename" %]
+ Renaming the '[% old FILTER html %]' table to '[% new FILTER html %]'...
+
+ [% ELSIF message_tag == "install_urlbase_default" %]
+ Now that you have installed [% terms.Bugzilla %], you should visit the
+ 'Parameters' page (linked in the footer of the Administrator
+ account) to ensure it is set up as you wish - this includes
+ setting the 'urlbase' option to the correct URL.
+
+ [% ELSIF message_tag == "install_reset_password" %]
+ Enter a new password for [% user.login FILTER html %]:
+
+ [% ELSIF message_tag == "install_reset_password_done" %]
+ New password set.
+
+ [% ELSIF message_tag == "install_webservergroup_empty" %]
+ ****************************************************************************
+ WARNING! You have not entered a value for the "webservergroup" parameter
+ in localconfig. This means that certain files and directories which need
+ to be editable by both you and the web server must be world writable, and
+ other files (including the localconfig file which stores your database
+ password) must be world readable. This means that _anyone_ who can obtain
+ local access to this machine can do whatever they want to your
+ [%+ terms.Bugzilla %] installation, and is probably also able to run
+ arbitrary Perl code as the user that the web server runs as.
+
+ You really, really, really need to change this setting.
+ ****************************************************************************
+
+ [% ELSIF message_tag == "install_webservergroup_not_in" %]
+ Warning: you have entered a value for the "webservergroup" parameter in
+ localconfig, but you are not either a) running this script as [% constants.ROOT_USER FILTER html %];
+ or b) a member of this group. This can cause permissions problems and
+ decreased security. If you experience problems running [% terms.Bugzilla %]
+ scripts, log in as [% constants.ROOT_USER FILTER html %] and re-run this script, become a
+ member of the group, or remove the value of the "webservergroup" parameter.
+
+ [% ELSIF message_tag == "install_webservergroup_windows" %]
+ Warning: You have set webservergroup in [% constants.bz_locations.localconfig FILTER html %]
+ Please understand that this does not bring you any security when
+ running under Windows.
+ Verify that the file permissions in your [% terms.Bugzilla %] directory are
+ suitable for your system. Avoid unnecessary write access.
+
+ [% ELSIF message_tag == "install_workflow_init" %]
+ Setting up the default status workflow...
+
+ [% ELSIF message_tag == "product_created" %]
+ [% title = "Product Created" %]
+ The product <em>[% product.name FILTER html %]</em> has been created.
+
+ [% ELSIF message_tag == "product_deleted" %]
+ [% title = "Product Deleted" %]
+ The product <em>[% product.name FILTER html %]</em> and all its versions,
+ components, milestones and group controls have been deleted.
+ [% IF product.bug_count %]
+ All [% terms.bugs %] being in this product and all references
+ to them have also been deleted.
+ [% END %]
+
+ [% ELSIF message_tag == "product_invalid" %]
+ [% title = "$terms.Bugzilla Component Descriptions" %]
+ The product <em>[% product FILTER html %]</em> does not exist
+ or you don't have access to it. The following is a list of the
+ products you can choose from.
+
+ [% ELSIF message_tag == "report_created" %]
+ OK, you have a new saved report named <em>[% reportname FILTER html %]</em>.
+
+ [% ELSIF message_tag == "report_deleted" %]
+ OK, the <em>[% reportname FILTER html %]</em> report is gone.
+
+ [% ELSIF message_tag == "report_updated" %]
+ The saved report <em>[% reportname FILTER html %]</em> has been updated.
+
+ [% ELSIF message_tag == "remaining_time_zeroed" %]
+ The [% field_descs.remaining_time FILTER html %] field has been
+ set to zero automatically as part of closing this [% terms.bug %]
+ or moving it from one closed state to another.
+
+ [% ELSIF message_tag == "sanitycheck" %]
+ [%# We use this way to call sanitycheck-specific messages so that
+ # we can still use get_text(). %]
+ [% PROCESS "admin/sanitycheck/messages.html.tmpl" %]
+
+ [% ELSIF message_tag == "series_all_open" %]
+ All Open
+
+ [% ELSIF message_tag == "series_all_closed" %]
+ All Closed
+
+ [% ELSIF message_tag == "series_subcategory" %]
+ -All-
+
+ [% ELSIF message_tag == "sudo_started" %]
+ [% title = "Sudo session started" %]
+ The sudo session has been started. For the next 6 hours, or until you
+ end the session, everything you do you do as the user you are
+ impersonating ([% target FILTER html %]).
+
+ [% ELSIF message_tag == "sudo_ended" %]
+ [% title = "Sudo session complete" %]
+ Your sudo session has ended. All future actions will be attributed
+ to your own account.
+
+ [% ELSIF message_tag == "series_created" %]
+ [% title = "Series Created" %]
+ The series <em>[% series.category FILTER html %] /
+ [%+ series.subcategory FILTER html %] /
+ [%+ series.name FILTER html %]</em>
+ has been created. Note that you may need to wait up to
+ [%+ series.frequency * 2 %] days before there will be enough data for a
+ chart of this series to be produced.
+
+ [% ELSIF message_tag == "series_deleted" %]
+ [% title = "Series Deleted" %]
+ The series <em>[% series.category FILTER html %] /
+ [%+ series.subcategory FILTER html %] /
+ [%+ series.name FILTER html %]</em>
+ has been deleted.
+
+ [% ELSIF message_tag == "shutdown" %]
+ [% title = "$terms.Bugzilla is Down" %]
+ [% Param("shutdownhtml") %]
+ [% IF userid %]
+ <p>For security reasons, you have been logged out automatically.
+ The cookie that was remembering your login is now gone.
+ [% END %]
+
+ [% ELSIF message_tag == "term" %]
+ [% terms.$term FILTER html %]
+
+ [% ELSIF message_tag == "unexpected_flag_types" %]
+ Some flags could not be set. Please check your changes.
+
+ [% ELSIF message_tag == "user_match_failed" %]
+ You entered a username that did not match any known
+ [% terms.Bugzilla %] users, so we have instead left
+ the [% match_field FILTER html %] field blank.
+
+ [% ELSIF message_tag == "user_match_multiple" %]
+ You entered a username that matched more than one
+ user, so we have instead left the [% match_field FILTER html %]
+ field blank.
+
+ [% ELSIF message_tag == "version_created" %]
+ [% title = "Version Created" %]
+ The version <em>[% version.name FILTER html %]</em> of product
+ <em>[% product.name FILTER html %]</em> has been created.
+
+ [% ELSIF message_tag == "version_deleted" %]
+ [% title = "Version Deleted" %]
+ The version <em>[% version.name FILTER html %]</em> of product
+ <em>[% product.name FILTER html %]</em> has been deleted.
+
+ [% ELSIF message_tag == "version_updated" %]
+ [% title = "Version Updated" %]
+ [% IF changes.size %]
+ Changes to the version <em>[% version.name FILTER html %]</em>
+ have been saved:
+ <ul>
+ [% IF changes.value.defined %]
+ <li>Version renamed to <em>[% version.name FILTER html %]</em></li>
+ [% END %]
+ [% IF changes.isactive.defined %]
+ <li>[% version.is_active ? "Enabled" : "Disabled" %] for [% terms.bugs %]</li>
+ [% END %]
+ </ul>
+ [% ELSE %]
+ No changes made to version <em>[% version.name FILTER html %]</em>.
+ [% END %]
+
+ [% ELSIF message_tag == "whine_query_failed" %]
+ The query '[% query_name FILTER html %]' from [% author.login FILTER html %]
+ failed: [% reason FILTER html %]
+
+ [% ELSIF message_tag == "workflow_updated" %]
+ The workflow has been updated.
+ [% END %]
+[% END %]
+
+[% IF !message %]
+ [% message = Hook.process('messages') %]
+[% END %]
+
+[%# Give sensible error if the message function is used incorrectly. #%]
+[% IF !message %]
+ [% message = BLOCK %]
+ You are using [% terms.Bugzilla %]'s messaging functions incorrectly. You
+ passed in the string '[% message_tag %]'. The correct use is to pass
+ in a tag, and define that tag in the file <kbd>messages.html.tmpl</kbd>.<br>
+ <br>
+ If you are a [% terms.Bugzilla %] end-user seeing this message, please
+ save this page and send it to [% Param('maintainer') %].
+ [% END %]
+[% END %]
diff --git a/template/en/default/global/reason-descs.none.tmpl b/template/en/default/global/reason-descs.none.tmpl
new file mode 100644
index 0000000..ca26b1c
--- /dev/null
+++ b/template/en/default/global/reason-descs.none.tmpl
@@ -0,0 +1,28 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% SET reason_descs = {
+ ${constants.REL_ASSIGNEE} => "You are the assignee for the ${terms.bug}.",
+ ${constants.REL_REPORTER} => "You reported the ${terms.bug}.",
+ ${constants.REL_QA} => "You are the QA Contact for the ${terms.bug}.",
+ ${constants.REL_CC} => "You are on the CC list for the ${terms.bug}.",
+ ${constants.REL_GLOBAL_WATCHER} => "You are watching all $terms.bug changes.",
+} %]
+
+[% SET watch_reason_descs => {
+ ${constants.REL_ASSIGNEE} =>
+ "You are watching the assignee of the ${terms.bug}.",
+ ${constants.REL_REPORTER} =>
+ "You are watching the reporter of the ${terms.bug}.",
+ ${constants.REL_QA} =>
+ "You are watching the QA Contact of the ${terms.bug}.",
+ ${constants.REL_CC} =>
+ "You are watching someone on the CC list of the ${terms.bug}.",
+} %]
+
+[% Hook.process('end') %]
diff --git a/template/en/default/global/select-menu.html.tmpl b/template/en/default/global/select-menu.html.tmpl
new file mode 100644
index 0000000..e9f56b7
--- /dev/null
+++ b/template/en/default/global/select-menu.html.tmpl
@@ -0,0 +1,52 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # name: string; the name of the menu.
+ #
+ # multiple: boolean; whether or not the menu is multi-select
+ #
+ # size: integer; the number of items to display at once
+ #
+ # options: array or hash; the items with which to populate the array.
+ # If a hash is passed, the hash keys become the names displayed
+ # to the user while the hash values become the value of the item.
+ #
+ # default: string; the item selected in the menu by default.
+ #
+ # onchange: code; JavaScript to be run when the user changes the value
+ # selected in the menu.
+ #%]
+
+[%# Get the scalar representation of the options reference,
+ # which looks like "ARRAY(0xA352BA3F)" or "HASH(0xA352BA3F)",
+ # so we can figure out whether it is a reference to an array
+ # or a hash.
+ #%]
+[% options_type = BLOCK %][% options %][% END %]
+
+<select name="[% name FILTER html %]"
+ [% IF onchange %]onchange="[% onchange FILTER html %]"[% END %]
+ [% IF multiple %] multiple [% END %]
+ [% IF size %] size="[% size %]" [% END %]>
+ [% IF options_type.search("ARRAY") %]
+ [% FOREACH value = options %]
+ <option value="[% value FILTER html %]"
+ [% " selected" IF value == default %]>
+ [% value FILTER html %]
+ </option>
+ [% END %]
+ [% ELSIF options_type.search("HASH") %]
+ [% FOREACH option = options %]
+ <option value="[% option.value FILTER html %]"
+ [% " selected" IF option.value == default %]>
+ [% option.key FILTER html %]
+ </option>
+ [% END %]
+ [% END %]
+</select>
diff --git a/template/en/default/global/setting-descs.none.tmpl b/template/en/default/global/setting-descs.none.tmpl
new file mode 100644
index 0000000..d200683
--- /dev/null
+++ b/template/en/default/global/setting-descs.none.tmpl
@@ -0,0 +1,49 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# Remember to PROCESS rather than INCLUDE this template. %]
+
+[% setting_descs = {
+ "comment_sort_order" => "When viewing $terms.abug, show comments in this order",
+ "csv_colsepchar" => "Field separator character for CSV files",
+ "display_quips" => "Show a quip at the top of each $terms.bug list",
+ "zoom_textareas" => "Zoom textareas large when in use (requires JavaScript)",
+ "newest_to_oldest" => "Newest to Oldest",
+ "newest_to_oldest_desc_first" => "Newest to Oldest, but keep Description at the top",
+ "off" => "Off",
+ "oldest_to_newest" => "Oldest to Newest",
+ "on" => "On",
+ "post_bug_submit_action" => "After changing $terms.abug",
+ "next_bug" => "Show next $terms.bug in my list",
+ "same_bug" => "Show the updated $terms.bug",
+ "standard" => "Classic",
+ "skin" => "$terms.Bugzilla's general appearance (skin)",
+ "nothing" => "Do Nothing",
+ "state_addselfcc" => "Automatically add me to the CC list of $terms.bugs I change",
+ "always" => "Always",
+ "never" => "Never",
+ "cc_unless_role" => "Only if I have no role on them",
+ "lang" => "Language used in email",
+ "quote_replies" => "Quote the associated comment when you click on its reply link",
+ "quoted_reply" => "Quote the full comment",
+ "simple_reply" => "Reference the comment number only",
+ "comment_box_position" => "Position of the Additional Comments box",
+ "before_comments" => "Before other comments",
+ "after_comments" => "After other comments",
+ "timezone" => "Timezone used to display dates and times",
+ "local" => "Same as the server",
+ "quicksearch_fulltext" => "Include comments when performing quick searches (slower)",
+ "email_format" => "Preferred email format",
+ "html" => "HTML",
+ "text_only" => "Text Only",
+ "requestee_cc" => "Automatically add me to the CC list of $terms.bugs I am requested to review",
+ "bugmail_new_prefix" => "Add 'New:' to subject line of email sent when a new $terms.bug is filed",
+ }
+%]
+
+[% Hook.process('settings') %]
diff --git a/template/en/default/global/site-navigation.html.tmpl b/template/en/default/global/site-navigation.html.tmpl
new file mode 100644
index 0000000..5c68ad7
--- /dev/null
+++ b/template/en/default/global/site-navigation.html.tmpl
@@ -0,0 +1,75 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # bug.bug_id: integer. Number of current bug (for navigation purposes)
+ #%]
+
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+[% IF NOT (cgi.user_agent("MSIE [1-6]") OR cgi.user_agent("Mozilla/4")) %]
+ <link rel="Top" href="[% urlbase FILTER html %]">
+
+ [%# *** Attachment *** %]
+ [% IF attachment && attachment.bug_id %]
+ <link rel="Up" href="show_bug.cgi?id=[% attachment.bug_id FILTER none %]">
+ [% END %]
+
+
+ [%# *** Dependencies, Activity, Print-version *** %]
+ [% IF bug %]
+ <link rel="Show" title="Dependency Tree"
+ href="showdependencytree.cgi?id=[% bug.bug_id %]&amp;hide_resolved=1">
+ [% IF Param('webdotbase') %]
+ <link rel="Show" title="Dependency Graph"
+ href="showdependencygraph.cgi?id=[% bug.bug_id %]">
+ [% END %]
+
+ <link rel="Show" title="[% terms.Bug %] Activity"
+ href="show_activity.cgi?id=[% bug.bug_id %]">
+ <link rel="Show" title="Printer-Friendly Version"
+ href="show_bug.cgi?format=multiple&amp;id=[% bug.bug_id %]">
+ [% END %]
+
+
+ [%# *** Saved Searches *** %]
+ [% IF user.showmybugslink %]
+ [% user_login = user.login FILTER uri %]
+ <link rel="Saved&nbsp;Searches" title="My [% terms.Bugs %]"
+ href="[% Param('mybugstemplate').replace('%userid%', user_login) %]">
+ [% END %]
+
+ [% FOREACH q = user.queries_subscribed %]
+ <link rel="Saved&nbsp;Search"
+ title="[% q.name FILTER html %] ([% q.user.login FILTER html %])"
+ href="buglist.cgi?cmdtype=dorem&amp;remaction=run&amp;namedcmd=
+ [% q.name FILTER uri %]&amp;sharer_id=
+ [% q.user.id FILTER uri %]">
+ [% END %]
+
+ [%# *** Bugzilla Administration Tools *** %]
+ [% IF user.login %]
+ [% '<link rel="Administration" title="Parameters"
+ href="editparams.cgi">' IF user.in_group('tweakparams') %]
+ [% '<link rel="Administration" title="Users"
+ href="editusers.cgi">' IF user.in_group('editusers') %]
+ [% '<link rel="Administration" title="Products" href="editproducts.cgi">'
+ IF user.in_group('editcomponents') || user.get_products_by_permission("editcomponents").size %]
+ [% '<link rel="Administration" title="Flag Types"
+ href="editflagtypes.cgi">' IF user.in_group('editcomponents') %]
+ [% '<link rel="Administration" title="Groups"
+ href="editgroups.cgi">' IF user.in_group('creategroups') %]
+ [% '<link rel="Administration" title="Keywords"
+ href="editkeywords.cgi">' IF user.in_group('editkeywords') %]
+ [% '<link rel="Administration" title="Whining"
+ href="editwhines.cgi">' IF user.in_group('bz_canusewhines') %]
+ [% '<link rel="Administration" title="Sanity Check"
+ href="sanitycheck.cgi">' IF user.in_group('editcomponents') %]
+ [% END %]
+[% END %]
diff --git a/template/en/default/global/tabs.html.tmpl b/template/en/default/global/tabs.html.tmpl
new file mode 100644
index 0000000..4540668
--- /dev/null
+++ b/template/en/default/global/tabs.html.tmpl
@@ -0,0 +1,42 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # tabs: List of hashes. Must have at least one item. Each hash has:
+ # name: string. Name of the tab.
+ # link: string. relative URL to the tab's resource on this installation.
+ # label: string. text displayed in the tab.
+ # current_tab_name: string. name of the currently selected tab
+ #%]
+
+<div class="tabbed">
+ <table class="tabs" cellspacing="0" cellpadding="10" border="0" width="100%">
+ <tr>
+ <td class="spacer">&nbsp;</td>
+
+ [% FOREACH tab = tabs %]
+ [% IF tab.name == current_tab_name %]
+ <td id="tab_[% tab.name FILTER html %]" class="selected">
+ [% tab.label FILTER html %]</td>
+ [% ELSE %]
+ <td id="tab_[% tab.name FILTER html %]" class="clickable_area"
+ onClick="document.location='[% tab.link FILTER html %]'">
+ <a href="[% tab.link FILTER html %]">[% tab.label FILTER html %]</a>
+ </td>
+ [% END %]
+ [% END %]
+
+ <td class="spacer">&nbsp;</td>
+ </tr>
+ </table>
+
+ <div class="tabbody">
+ [% content %]
+ </div>
+
+</div>
diff --git a/template/en/default/global/textarea.html.tmpl b/template/en/default/global/textarea.html.tmpl
new file mode 100644
index 0000000..216f2dd
--- /dev/null
+++ b/template/en/default/global/textarea.html.tmpl
@@ -0,0 +1,55 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ #
+ # id: (optional) The "id"-attribute of the textarea.
+ # name: (optional) The "name"-attribute of the textarea.
+ # accesskey: (optional) The "accesskey"-attribute of the textarea.
+ # style: (optional) The "style"-attribute of the textarea.
+ # classes: (optional) The "class"-attribute of the textarea.
+ # wrap: (deprecated; optional) The "wrap"-attribute of the textarea.
+ # disabled: (optional) Disable the textarea.
+ # readonly: (optional) Prevent the textarea from being edited.
+ # minrows: (required) Number of rows the textarea shall have initially
+ # and when not having focus.
+ # maxrows: (optional) Number of rows the textarea shall have if
+ # maximized (which happens on getting focus). If not given,
+ # the textarea doesn't maximize when getting focus.
+ # defaultrows: (optional) Number of rows the textarea shall have if
+ # the zoom_textareas user preference if off. If not given,
+ # minrows will be used.
+ # cols: (required) Number of columns the textarea shall have.
+ # defaultcontent: (optional) Default content for the textarea.
+ # mandatory: (optional) Boolean specifying whether or not the textarea
+ # is mandatory.
+ #%]
+
+<textarea [% IF name %]name="[% name FILTER html %]"[% END %]
+ [% IF id %] id="[% id FILTER html %]"[% END %]
+ [% IF accesskey %] accesskey="[% accesskey FILTER html %]"[% END %]
+ [% IF style %] style="[% style FILTER html %]"[% END %]
+ [% IF classes %] class="[% classes FILTER html %]"[% END %]
+ [% IF wrap %] wrap="[% wrap FILTER html %]"[% END %]
+ [% IF disabled %] disabled="disabled"[% END %]
+ [% IF readonly %] readonly="readonly"[% END %]
+ [% IF defaultrows && user.settings.zoom_textareas.value == 'off' %]
+ rows="[% defaultrows FILTER html %]"
+ [% ELSE %]
+ rows="[% minrows FILTER html %]"
+ [% END %]
+ cols="[% cols FILTER html %]"
+ [% IF maxrows && user.settings.zoom_textareas.value == 'on' %]
+ onFocus="this.rows=[% maxrows FILTER html %]"
+ [% END %]
+ [% IF mandatory %]
+ aria-required="true"
+ [% END %]
+ [% IF onchange %]
+ onchange="[% onchange FILTER html %]"
+ [% END %]>[% defaultcontent FILTER html %]</textarea>
diff --git a/template/en/default/global/useful-links.html.tmpl b/template/en/default/global/useful-links.html.tmpl
new file mode 100644
index 0000000..5959ab6
--- /dev/null
+++ b/template/en/default/global/useful-links.html.tmpl
@@ -0,0 +1,74 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# Migration note: this whole file corresponds to the old %commandmenu%
+ substitution param in 'footerhtml' %]
+
+<ul id="useful-links">
+ <li id="links-actions">
+ [% PROCESS "global/common-links.html.tmpl" qs_suffix = "_bottom" %]
+ </li>
+
+ [%# Saved searches %]
+
+ [% IF user.showmybugslink OR user.queries.size
+ OR user.queries_subscribed.size
+ %]
+ [% print_pipe = 0 %]
+ <li id="links-saved">
+ <ul class="links">
+ [% IF user.showmybugslink %]
+ [% filtered_username = user.login FILTER uri %]
+ <li><a href="[% Param('mybugstemplate').replace('%userid%', filtered_username) %]">My [% terms.Bugs %]</a></li>
+ [% print_pipe = 1 %]
+ [% END %]
+
+ [% FOREACH q = user.queries %]
+ [% IF q.link_in_footer %]
+ <li>[% '<span class="separator">| </span>' IF print_pipe %]
+ <a href="buglist.cgi?cmdtype=runnamed&amp;namedcmd=[% q.name FILTER uri %]">[% q.name FILTER html %]</a></li>
+ [% print_pipe = 1 %]
+ [% END %]
+ [% END %]
+ [% new_line = print_pipe %]
+ [% print_pipe = 0 %]
+ [% FOREACH q = user.queries_subscribed %]
+ [% IF new_line %]
+ <br>
+ [% new_line = 0 %]
+ [% END %]
+ <li>
+ [% '<span class="separator">| </span>' IF print_pipe %]
+ <a href="buglist.cgi?cmdtype=dorem&amp;remaction=run&amp;namedcmd=
+ [% q.name FILTER uri %]&amp;sharer_id=
+ [% q.user.id FILTER uri %]"
+ class="shared"
+ title="Shared by [% q.user.identity FILTER html %]"
+ >[% q.name FILTER html FILTER no_break %]</a></li>
+ [% print_pipe = 1 %]
+ [% END %]
+ </ul>
+ </li>
+ [% END %]
+
+ [% IF user.reports.size %]
+ <li id="reports-saved">
+ <ul class="links">
+ [% FOREACH r = user.reports %]
+ <li>[% '<span class="separator">| </span>' IF print_pipe %]
+ <a href="report.cgi?[% r.query FILTER html %]&amp;saved_report_id=
+ [%~ r.id FILTER uri %]">[% r.name FILTER html %]</a></li>
+ [% print_pipe = 1 %]
+ [% END %]
+ </ul>
+ </li>
+ [% END %]
+
+ [%# Sections of links to more things users can do on this installation. %]
+ [% Hook.process("end") %]
+</ul>
diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl
new file mode 100644
index 0000000..8dbcd45
--- /dev/null
+++ b/template/en/default/global/user-error.html.tmpl
@@ -0,0 +1,1964 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # header_done: boolean. True if the Bugzilla header has already been printed.
+ # error: string. The tag of the error, or the error message to be displayed
+ # (deprecated). May contain HTML if it's an error message.
+ #%]
+
+[%# This is a list of all the possible user errors. Please keep them in
+ # alphabetical order by error tag, and leave a blank line between errors.
+ #
+ # Note that you must explicitly filter every single template variable
+ # in this file; if you do not wish to change it, use the "none" filter.
+ #
+ # Extension- or custom-specific error handling can be easily added
+ # via hooks: just place additional code into
+ # template/en/hook/global/user-error-errors.html.tmpl
+ # Note: be aware of uniqueness of error string parameter value, since
+ # nobody can guarantee the hook files processing order in the future.
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+
+[% DEFAULT title = "Error" %]
+
+[% error_message = BLOCK %]
+ [% IF error == "account_creation_disabled" %]
+ [% title = "Account Creation Disabled" %]
+ User account creation has been disabled.
+ <hr>
+ New accounts must be created by an administrator. The
+ maintainer is [% Param("maintainer") %].
+
+ [% ELSIF error == "account_creation_restricted" %]
+ [% title = "Account Creation Restricted" %]
+ User account creation has been restricted.
+ <hr>
+ Contact your administrator or the maintainer
+ ([% Param("maintainer") %]) for information about
+ creating an account.
+
+ [% ELSIF error == "account_disabled" %]
+ [% title = "Account Disabled" %]
+ [% disabled_reason FILTER none %]
+ <hr>
+ If you believe your account should be restored, please
+ send email to [% Param("maintainer") %] explaining why.
+
+ [% ELSIF error == "account_exists" %]
+ [% title = "Account Already Exists" %]
+ There is already an account with
+ [% IF email %]
+ the login name [% email FILTER html %].
+ [% ELSE %]
+ that login name.
+ [% END %]
+
+ [% ELSIF error == "account_locked" %]
+ [% title = "Account Locked" %]
+ Your IP ([% ip_addr FILTER html %]) has been locked out of this
+ account until [% unlock_at FILTER time %], as you have
+ exceeded the maximum number of login attempts.
+
+ [% ELSIF error == "alias_has_comma_or_space" %]
+ [% title = "Invalid Characters In Alias" %]
+ The alias you entered, <em>[% alias FILTER html %]</em>,
+ contains one or more commas or spaces. Aliases cannot contain
+ commas or spaces because those characters are used to separate
+ aliases from each other in lists. Please choose an alias
+ that does not contain commas and spaces.
+
+ [% ELSIF error == "alias_in_use" %]
+ [% title = "Alias In Use" %]
+ [% IF user.can_see_bug(bug_id) %]
+ [% terms.Bug %] [%+ bug_id FILTER bug_link(bug_id) FILTER none %]
+ [% ELSE %]
+ Another [% terms.bug %]
+ [% END %]
+ has already taken the alias <em>[% alias FILTER html %]</em>.
+ Please choose another alias.
+
+ [% ELSIF error == "alias_is_numeric" %]
+ [% title = "Alias Is Numeric" %]
+ You tried to give this [% terms.bug %] the alias <em>[% alias FILTER html %]</em>,
+ but aliases cannot be merely numbers, since they could
+ then be confused with [% terms.bug %] IDs. Please choose an
+ alias containing at least one letter.
+
+ [% ELSIF error == "alias_too_long" %]
+ [% title = "Alias Too Long" %]
+ [% terms.Bug %] aliases cannot be longer than 20 characters.
+ Please choose a shorter alias.
+
+ [% ELSIF error == "attachment_bug_id_mismatch" %]
+ [% title = "Invalid Attachments" %]
+ You tried to perform an action on attachments from different [% terms.bugs %].
+ This operation requires all attachments to be from the same [% terms.bug %].
+
+ [% ELSIF error == "auth_cant_create_account" %]
+ [% title = "Can't create accounts" %]
+ This site is using an authentication scheme which does not permit
+ account creation. Please contact an administrator to get a new account
+ created.
+
+ [% ELSIF error == "auth_failure" %]
+ [% title = "Authorization Required" %]
+ [% admindocslinks = {'groups.html' => 'Group Security'} %]
+ Sorry,
+ [% IF group %]
+ you aren't a member of the '[% group FILTER html %]' group,
+ [% END %]
+
+ [% IF reason %]
+ [% IF group %] and [% END %]
+ [% IF reason == "cant_bless" %]
+ you don't have permissions to add or remove people from a group,
+ [% ELSIF reason == "not_visible" %]
+ there are visibility restrictions on certain user groups,
+ [% END %]
+ [% END %]
+
+ [% IF group || reason %] and so [% END %] you are not authorized to
+ [% IF action == "access" %]
+ access
+ [% ELSIF action == "add" %]
+ add new
+ [% ELSIF action == "begin" %]
+ begin
+ [% ELSIF action == "modify" %]
+ modify
+ [% ELSIF action == "delete" %]
+ delete
+ [% ELSIF action == "edit" %]
+ add, modify or delete
+ [% ELSIF action == "run" %]
+ run
+ [% ELSIF action == "schedule" %]
+ schedule
+ [% ELSIF action == "search" %]
+ search
+ [% ELSIF action == "use" %]
+ use
+ [% ELSIF action == "approve" %]
+ approve
+ [% ELSE %]
+ [%+ Hook.process('auth_failure_action') %]
+ [% END %]
+
+ [% IF object == "administrative_pages" %]
+ administrative pages
+ [% ELSIF object == "attachment" %]
+ [% IF attach_id %]
+ attachment #[% attach_id FILTER html %]
+ [% ELSE %]
+ this attachment
+ [% END %]
+ [% ELSIF object == "bugs" %]
+ [%+ terms.bugs %]
+ [% ELSIF object == "bug_fields" %]
+ the [% field_descs.$field FILTER html %] field
+ [% ELSIF object == "charts" %]
+ the "New Charts" feature
+ [% ELSIF object == "classifications" %]
+ classifications
+ [% ELSIF object == "components" %]
+ components
+ [% ELSIF object == "custom_fields" %]
+ custom fields
+ [% ELSIF object == "field_values" %]
+ field values
+ [% ELSIF object == "flagtypes" %]
+ flag types
+ [% ELSIF object == "group_access" %]
+ group access
+ [% ELSIF object == "groups" %]
+ groups
+ [% ELSIF object == "keywords" %]
+ keywords
+ [% ELSIF object == "milestones" %]
+ milestones
+ [% ELSIF object == "multiple_bugs" %]
+ multiple [% terms.bugs %] at once
+ [% ELSIF object == "parameters" %]
+ parameters
+ [% ELSIF object == "products" %]
+ products
+ [% ELSIF object == "quips" %]
+ quips
+ [% ELSIF object == "reports" %]
+ whine reports
+ [% ELSIF object == "sanity_check" %]
+ a sanity check
+ [% ELSIF object == "settings" %]
+ settings
+ [% ELSIF object == "sudo_session" %]
+ a sudo session
+ [% ELSIF object == "timetracking_summaries" %]
+ time-tracking summary reports
+ [% ELSIF object == "user" %]
+ the user [% IF userid %] with ID '[% userid FILTER html %]'
+ [% ELSE %]you specified [% END %]
+ [% ELSIF object == "users" %]
+ users
+ [% ELSIF object == "versions" %]
+ versions
+ [% ELSIF object == "workflow" %]
+ the workflow
+ [% ELSE %]
+ [%+ Hook.process('auth_failure_object') %]
+ [% END %].
+
+ [% Hook.process("auth_failure") %]
+
+ [% ELSIF error == "auth_untrusted_request" %]
+ [% title = "Untrusted Authentication Request" %]
+ You tried to log in using the <em>[% login FILTER html %]</em> account,
+ but [% terms.Bugzilla %] is unable to trust your request. Make sure
+ your web browser accepts cookies and that you haven't been redirected
+ here from an external web site.
+ <a href="index.cgi?GoAheadAndLogIn=1">Click here</a> if you really want
+ to log in.
+
+ [% ELSIF error == "attachment_deletion_disabled" %]
+ [% title = "Attachment Deletion Disabled" %]
+ Attachment deletion is disabled on this installation.
+
+ [% ELSIF error == "attachment_removed" %]
+ [% title = "Attachment Removed" %]
+ The attachment you are attempting to access has been removed.
+
+ [% ELSIF error == "bad_page_cgi_id" %]
+ [% title = "Invalid Page ID" %]
+ The ID <code>[% page_id FILTER html %]</code> is not a
+ valid page identifier.
+
+ [% ELSIF error == "bug_access_denied" %]
+ [% title = "Access Denied" %]
+ [% admindocslinks = {'groups.html' => 'Group Security'} %]
+ You are not authorized to access [% terms.bug %] #[% bug_id FILTER html %].
+
+ [% ELSIF error == "bug_access_query" %]
+ [% title = "Access Denied" %]
+ [% docslinks = {'myaccount.html' => 'Creating an account'} %]
+ You are not authorized to access [% terms.bug %] #[% bug_id FILTER html %].
+ To see this [% terms.bug %], you must
+ first <a href="show_bug.cgi?id=
+ [% bug_id FILTER uri %]&amp;GoAheadAndLogIn=1">log
+ in to an account</a> with the appropriate permissions.
+
+ [% ELSIF error == "bug_url_invalid" %]
+ [% title = "Invalid $terms.Bug URL" %]
+ <code>[% url FILTER html %]</code> is not a valid URL to [% terms.abug %].
+ [% IF reason == 'http' %]
+ URLs must start with "http" or "https".
+ [% ELSIF reason == 'path_only' %]
+ You must specify a full URL.
+ [% ELSIF reason == 'id' %]
+ There is no valid [% terms.bug %] id in that URL.
+ [% ELSE %]
+ [%+ field_descs.see_also FILTER html %] URLs should point to one of:
+ <ul>
+ <li><code>show_bug.cgi</code> in a [% terms.Bugzilla %]
+ installation.</li>
+ <li>A b[% %]ug on launchpad.net</li>
+ <li>An issue on code.google.com.</li>
+ <li>A b[% %]ug on b[% %]ugs.debian.org.</li>
+ <li>An issue in a JIRA installation.</li>
+ <li>A ticket in a Trac installation.</li>
+ <li>A b[% %]ug in a MantisBT installation.</li>
+ <li>A b[% %]ug on sourceforge.net.</li>
+ <li>An issue on github.com.</li>
+ [% Hook.process('bug_url_invalid_tracker') %]
+ </ul>
+ [% END %]
+
+ [% ELSIF error == "bug_url_too_long" %]
+ [% title = "Invalid $terms.Bug URL" %]
+ [% terms.Bug %] URLs cannot be longer than
+ [%+ constants.MAX_BUG_URL_LENGTH FILTER none %] characters long.
+ <code>[% url FILTER html %]</code> is too long.
+
+ [% ELSIF error == "buglist_parameters_required" %]
+ [% title = "Parameters Required" %]
+ [% docslinks = {'query.html' => "Searching for $terms.bugs",
+ 'query.html#list' => "$terms.Bug lists"} %]
+ You may not search, or create saved searches, without any search terms.
+
+ [% ELSIF error == "cc_remove_denied" %]
+ [% title = "Change Denied" %]
+ You do not have permission to remove other people from the CC list.
+
+ [% ELSIF error == "chart_too_large" %]
+ [% title = "Chart Too Large" %]
+ Sorry, but 2000 x 2000 is the maximum size for a chart.
+
+ [% ELSIF error == "comment_id_invalid" %]
+ [% id FILTER html %] is not a valid comment id.
+
+ [% ELSIF error == "comment_invalid_isprivate" %]
+ You tried to modify the privacy of comment id [% id FILTER html %],
+ but that is not a valid comment on this [% terms.bug %].
+
+ [% ELSIF error == "comment_is_private" %]
+ Comment id [% id FILTER html %] is private.
+
+ [% ELSIF error == "comment_required" %]
+ [% title = "Comment Required" %]
+ You have to specify a
+ [% IF old.defined && new.defined %]
+ <b>comment</b> when changing the [% field_descs.$field FILTER html %]
+ of [% terms.abug %] from [% (old || "(empty)") FILTER html %]
+ to [% (new || "(empty)") FILTER html %].
+ [% ELSIF new %]
+ description for this [% terms.bug %].
+ [% ELSE %]
+ <b>comment</b> on this change.
+ [% END %]
+
+ [% ELSIF error == "comment_too_long" %]
+ [% title = "Comment Too Long" %]
+ Comments cannot be longer than
+ [%+ constants.MAX_COMMENT_LENGTH FILTER html %] characters.
+
+ [% ELSIF error == "auth_classification_not_enabled" %]
+ [% title = "Classification Not Enabled" %]
+ Sorry, classification is not enabled.
+
+ [% ELSIF error == "classification_name_too_long" %]
+ [% title = "Classification Name Too Long" %]
+ The name of a classification is limited to [% constants.MAX_CLASSIFICATION_SIZE FILTER html %]
+ characters. '[% name FILTER html %]' is too long ([% name.length %] characters).
+
+[% ELSIF error == "classification_not_specified" %]
+ [% title = "You Must Supply A Classification Name" %]
+ You must enter a classification name.
+
+ [% ELSIF error == "classification_already_exists" %]
+ [% title = "Classification Already Exists" %]
+ A classification with the name '[% name FILTER html %]' already exists.
+
+ [% ELSIF error == "classification_invalid_sortkey" %]
+ [% title = "Invalid Sortkey for Classification" %]
+ The sortkey '[% sortkey FILTER html %]' is invalid. It must be an
+ integer between 0 and [% constants.MAX_SMALLINT FILTER html %].
+
+ [% ELSIF error == "classification_not_deletable" %]
+ [% title = "Default Classification Cannot Be Deleted" %]
+ You cannot delete the default classification
+
+ [% ELSIF error == "classification_has_products" %]
+ Sorry, there are products for this classification. You
+ must reassign those products to another classification before you
+ can delete this one.
+
+ [% ELSIF error == "component_already_exists" %]
+ [% title = "Component Already Exists" %]
+ The <em>[% product.name FILTER html %]</em> product already has
+ a component named <em>[% name FILTER html %]</em>.
+
+ [% ELSIF error == "component_blank_description" %]
+ [% title = "Blank Component Description Not Allowed" %]
+ You must enter a non-blank description for this component.
+
+ [% ELSIF error == "component_blank_name" %]
+ [% title = "Blank Component Name Not Allowed" %]
+ You must enter a name for this new component.
+
+ [% ELSIF error == "component_has_bugs" %]
+ [% title = BLOCK %]Component has [% terms.Bugs %][% END %]
+ There are [% nb FILTER html %] [%+ terms.bugs %] entered for this component!
+ You must reassign those [% terms.bugs %] to another component before you
+ can delete this one.
+
+ [% ELSIF error == "component_is_last" %]
+ [% title = BLOCK %]Last Component in this Product[% END %]
+ '[% comp.name FILTER html %]' is the last component of the
+ '[% comp.product.name FILTER html %]' product. You cannot delete it.
+
+ [% ELSIF error == "component_name_too_long" %]
+ [% title = "Component Name Is Too Long" %]
+ The name of a component is limited to [% constants.MAX_COMPONENT_SIZE FILTER html %]
+ characters. '[% name FILTER html %]' is too long ([% name.length %] characters).
+
+ [% ELSIF error == "component_need_initialowner" %]
+ [% title = "Component Requires Default Assignee" %]
+ A default assignee is required for this component.
+
+ [% ELSIF error == "customfield_nonexistent" %]
+ [% title = "Unknown Custom Field" %]
+ There is no custom field with the name '[% name FILTER html %]'.
+
+ [% ELSIF error == "customfield_not_obsolete" %]
+ [% title = "Custom Field Not Obsolete" %]
+ The custom field '[% name FILTER html %]' is not obsolete.
+ Please obsolete a custom field before attempting to delete it.
+
+ [% ELSIF error == "customfield_has_activity" %]
+ [% title = "Custom Field Has Activity" %]
+ The custom field '[% name FILTER html %]' cannot be deleted because
+ it has recorded activity.
+
+ [% ELSIF error == "customfield_has_contents" %]
+ [% title = "Custom Field Has Contents" %]
+ The custom field '[% name FILTER html %]' cannot be deleted because
+ at least one [% terms.bug %] has a non empty value for this field.
+
+ [% ELSIF error == "dependency_loop_multi" %]
+ [% title = "Dependency Loop Detected" %]
+ The following [% terms.bug %](s) would appear on both the "depends on"
+ and "blocks" parts of the dependency tree if these changes
+ are committed:
+ [% FOREACH dep = deps %]
+ [%+ dep FILTER bug_link(dep) FILTER none %]
+ [% END %].
+ This would create a circular dependency, which is not allowed.
+
+ [% ELSIF error == "dependency_loop_single" %]
+ [% title = "Dependency Loop Detected" %]
+ You can't make [% terms.abug %] block itself or depend on itself.
+
+ [% ELSIF error == "dupe_id_required" %]
+ [% title = "Duplicate $terms.Bug Id Required" %]
+ You must specify [% terms.abug %] id to mark this [% terms.bug %]
+ as a duplicate of.
+
+ [% ELSIF error == "dupe_not_allowed" %]
+ [% title = "Cannot mark $terms.bugs as duplicates" %]
+ You cannot mark [% terms.bugs %] as duplicates when
+ changing several [% terms.bugs %] at once.
+
+ [% ELSIF error == "dupe_loop_detected" %]
+ [% title = "Loop detected among duplicates" %]
+ You cannot mark [% terms.bug %] [%+ bug_id FILTER html %] as
+ a duplicate of
+ [% IF dupe_of == bug_id %]
+ itself
+ [% ELSE %]
+ [%+ terms.bug %] [%+ dupe_of FILTER html %], because it
+ would create a duplicate loop
+ [% END %].
+
+ [% ELSIF error == "email_change_in_progress" %]
+ [% title = "Email Change Already In Progress" %]
+ Email change already in progress; please check your email.
+
+ [% ELSIF error == "email_no_body" %]
+ Your message did not contain any text, as far as we could tell.
+
+ [% ELSIF error == "empty_group_description" %]
+ [% title = "The group description cannot be empty" %]
+ You must enter a description for the group.
+
+ [% ELSIF error == "empty_group_name" %]
+ [% title = "The group name cannot be empty" %]
+ You must enter a name for the group.
+
+ [% ELSIF error == "entry_access_denied" %]
+ [% title = "Permission Denied" %]
+ [% admindocslinks = {'groups.html' => 'Group Security'} %]
+ Sorry, either the product <em>[% product FILTER html %]</em>
+ does not exist or you aren't authorized to
+ enter [% terms.abug %] into it.
+
+ [% ELSIF error == "extension_create_no_name" %]
+ You must specify a name for your extension, as an argument to this script.
+
+ [% ELSIF error == "extension_disabled" %]
+ [% title = "Extension Disabled" %]
+ You cannot access this page because the extension '[% name FILTER html %]'
+ is disabled.
+
+ [% ELSIF error == "extension_first_letter_caps" %]
+ The first letter of your extension's name must be a capital letter.
+ (You specified '[% name FILTER html %]'.)
+
+ [% ELSIF error == "feature_disabled" %]
+ The [% install_string("feature_$feature") FILTER html %] feature is not
+ available in this [% terms.Bugzilla %].
+ [% IF user.in_group('admin') %]
+ If you would like to enable this feature, please run
+ <kbd>checksetup.pl</kbd> to see how to install the necessary
+ requirements for this feature.
+ [% END %]
+
+ [% ELSIF error == "field_already_exists" %]
+ [% title = "Field Already Exists" %]
+ The field '[% field.name FILTER html %]'
+ ([% field.description FILTER html %]) already exists. Please
+ choose another name.
+
+ [% ELSIF error == "field_cant_control_self" %]
+ [% title = "Field Can't Control Itself" %]
+ The [% field.description FILTER html %] field can't be set to control
+ itself.
+
+ [% ELSIF error == "field_control_must_be_select" %]
+ [% title = "Invalid Field Type Selected" %]
+ Only drop-down and multi-select fields can be used to control
+ the visibility/values of other fields. [% field.description FILTER html %]
+ is not the right type of field.
+
+ [% ELSIF error == "field_invalid_name" %]
+ [% title = "Invalid Field Name" %]
+ '[% name FILTER html %]' is not a valid name for a field.
+ A name may contain only letters, numbers, and the underscore character.
+
+ [% ELSIF error == "field_invalid_sortkey" %]
+ [% title = "Invalid Sortkey for Field" %]
+ The sortkey [% sortkey FILTER html %] that you have provided for
+ this field is not a valid positive integer.
+
+ [% ELSIF error == "field_missing_description" %]
+ [% title = "Missing Description for Field" %]
+ You must enter a description for this field.
+
+ [% ELSIF error == "field_long_desc_too_long" %]
+ [% title = "Long Description for Field too long" %]
+ The long description you have provided for this field is longer than
+ [% constants.MAX_FIELD_LONG_DESC_LENGTH FILTER html %] characters.
+
+ [% ELSIF error == "field_missing_name" %]
+ [% title = "Missing Name for Field" %]
+ You must enter a name for this field.
+
+ [% ELSIF error == "field_value_control_select_only" %]
+ [% title = "Invalid Value Control Field" %]
+ Only Drop-Down or Multi-Select fields can have a field that
+ controls their values.
+
+ [% ELSIF error == "field_visibility_values_must_be_selected" %]
+ [% title = "Missing visibility field values" %]
+ At least one value must be selected for the visibility field
+ '[% field.name FILTER html %]'.
+
+ [% ELSIF error == "fieldname_invalid" %]
+ [% title = "Specified Field Does Not Exist" %]
+ The field '[% field.name FILTER html %]' does not exist or
+ cannot be edited with this interface.
+
+ [% ELSIF error == "fieldvalue_already_exists" %]
+ [% title = "Field Value Already Exists" %]
+ The value '[% value.name FILTER html %]' already exists for the
+ [%+ field.description FILTER html %] field.
+
+ [% ELSIF error == "fieldvalue_is_controller" %]
+ [% title = "Value Controls Other Fields" %]
+ You cannot delete the [% value.field.description FILTER html %]
+ '[% value.name FILTER html %]' because
+ [% IF fields.size %]
+ it controls the visibility of the following fields:
+ [%+ fields.join(', ') FILTER html %].
+ [% END %]
+ [% ' Also, ' IF fields.size AND vals.size %]
+ [% IF vals.size %]
+ it controls the visibility of the following field values:
+ <ul>
+ [% FOREACH field_name = vals.keys %]
+ [% FOREACH val = vals.${field_name} %]
+ <li>[% val.field.name FILTER html %]:
+ '[% val.name FILTER html %]'</li>
+ [% END %]
+ [% END %]
+ </ul>
+ [% END %]
+
+ [% ELSIF error == "fieldvalue_is_default" %]
+ [% title = "Specified Field Value Is Default" %]
+ '[% value.name FILTER html %]' is the default value for
+ the '[% field.description FILTER html %]' field and cannot be deleted
+ or disabled.
+ [% IF user.in_group('tweakparams') %]
+ You have to <a href="editparams.cgi?section=bugfields#
+ [%- param_name FILTER uri %]">change</a> the default value first.
+ [% END %]
+
+ [% ELSIF error == "fieldvalue_name_too_long" %]
+ [% title = "Field Value Is Too Long" %]
+ The value of a field is limited to
+ [%+ constants.FIELD_VALUE_MAX_SIZE FILTER none %] characters.
+ '[% value FILTER html %]' is too long ([% value.length %] characters).
+
+ [% ELSIF error == "fieldvalue_not_editable" %]
+ [% title = "Field Value Not Editable" %]
+ The value '[% old_value.name FILTER html %]' cannot be renamed because
+ it plays some special role for the '[% field.description FILTER html %]'
+ field.
+
+ [% ELSIF error == "fieldvalue_not_deletable" %]
+ [% title = "Field Value Not Deletable" %]
+ The value '[% value.name FILTER html %]' cannot be removed or
+ disabled, because it plays some special role for the
+ '[% field.description FILTER html %]' field.
+
+ [% ELSIF error == "fieldvalue_reserved_word" %]
+ [% title = "Reserved Word Not Allowed" %]
+ You cannot use the value '[% value FILTER html %]' for the
+ '[% field.description FILTER html %]' field. This value is used internally.
+ Please choose another one.
+
+ [% ELSIF error == "fieldvalue_sortkey_invalid" %]
+ [% title = "Invalid Field Value Sortkey" %]
+ The sortkey '[% sortkey FILTER html %]' for the
+ [%+ field.description FILTER html %] field must be an integer
+ between 0 and [% constants.MAX_SMALLINT FILTER none %].
+
+ [% ELSIF error == "fieldvalue_still_has_bugs" %]
+ [% title = "You Cannot Delete This Field Value" %]
+ You cannot delete the value '[% value.name FILTER html %]' from the
+ [%+ field.description FILTER html %] field, because there are still
+ [%+ value.bug_count FILTER html %] [%+ terms.bugs %] using it.
+
+ [% ELSIF error == "fieldvalue_undefined" %]
+ [% title = "Undefined Value Not Allowed" %]
+ You must specify a value.
+
+ [% ELSIF error == "file_not_specified" %]
+ [% title = "No File Specified" %]
+ You did not specify a file to attach.
+
+ [% ELSIF error == "filename_not_specified" %]
+ [% title = "No Filename Specified" %]
+ You must specify a filename for this attachment.
+
+ [% ELSIF error == "file_too_large" %]
+ [% title = "File Too Large" %]
+ [%# Convert maxlocalattachment from Mb to Kb %]
+ [% max_local = Param('maxlocalattachment') * 1024 %]
+ [% max_limit = [Param('maxattachmentsize'), max_local] %]
+ The file you are trying to attach is [% filesize FILTER html %]
+ kilobytes (KB) in size. Attachments cannot be more than
+ [%# Hack to get the max value between both limits %]
+ [%+ max_limit.nsort.last FILTER html %] KB. <br>
+ We recommend that you store your attachment elsewhere
+ and then paste the URL to this file on the attachment
+ creation page in the appropriate text field, which you can access by
+ clicking the "paste text as attachment" link.
+ <br>Alternately, if your attachment is an image, you could convert
+ it to a compressible format like JPG or PNG and try again.
+
+ [% ELSIF error == "flag_requestee_disabled" %]
+ [% title = "Flag not Requestable from Specific Person" %]
+ You can't ask a specific person for <em>[% type.name FILTER html %]</em>.
+
+ [% ELSIF error == "flag_requestee_needs_privs" %]
+ [% title = "Flag Requestee Needs Privileges" %]
+ [% requestee.identity FILTER html %] does not have permission to set the
+ <em>[% flagtype.name FILTER html %]</em> flag. Please select a user who is
+ a member of the <em>[% flagtype.grant_group.name FILTER html %]</em> group.
+
+ [% ELSIF error == "flag_requestee_unauthorized" %]
+ [% title = "Flag Requestee Not Authorized" %]
+ [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags',
+ 'groups.html' => 'Group Security'} %]
+ [% docslinks = {'flags-overview.html' => 'An overview on Flags',
+ 'flags.html' => 'Using Flags'} %]
+
+ You asked [% requestee.identity FILTER html %]
+ for <code>[% flag_type.name FILTER html %]</code> on [% terms.bug %]
+ [%+ bug_id FILTER html -%]
+ [% IF attach_id && attach_id > 0 %], attachment [% attach_id FILTER html %][% END %],
+ but that [% terms.bug %] has been restricted to users in certain groups,
+ and the user you asked isn't in all the groups to which
+ the [% terms.bug %] has been restricted.
+ Please choose someone else to ask, or make the [% terms.bug %] accessible
+ to users on its CC: list and add that user to the list.
+
+ [% ELSIF error == "flag_requestee_unauthorized_attachment" %]
+ [% title = "Flag Requestee Not Authorized" %]
+ [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags',
+ 'groups.html' => 'Group Security'} %]
+ [% docslinks = {'flags-overview.html' => 'An overview on Flags',
+ 'flags.html' => 'Using Flags'} %]
+
+ You asked [% requestee.identity FILTER html %]
+ for <code>[% flag_type.name FILTER html %]</code> on
+ [%+ terms.bug %] [%+ bug_id FILTER html %],
+ attachment [% attach_id FILTER html %], but that attachment
+ is restricted to users in the [% Param("insidergroup") FILTER html %] group,
+ and the user you asked isn't in that group. Please choose someone else
+ to ask, or ask an administrator to add the user to the group.
+
+ [% ELSIF error == "flag_status_invalid" %]
+ [% title = "Flag Status Invalid" %]
+ The flag status <em>[% status FILTER html %]</em>
+ [% IF id %]
+ for flag ID #[% id FILTER html %]
+ [% END %]
+ is invalid.
+
+ [% ELSIF error == "flag_type_cannot_deactivate" %]
+ [% title = "Cannot Deactivate Flag Type" %]
+ Sorry, but the flag type '[% flagtype.name FILTER html %]' also applies to some
+ products you cannot see, and so you are not allowed to deactivate it.
+
+ [% ELSIF error == "flag_type_cannot_delete" %]
+ [% title = "Flag Type Deletion Not Allowed" %]
+ Sorry, but the flag type '[% flagtype.name FILTER html %]' also applies to some
+ products you cannot see, and so you are not allowed to delete it.
+
+ [% ELSIF error == "flag_type_cc_list_invalid" %]
+ [% title = "Flag Type CC List Invalid" %]
+ [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags'} %]
+ The CC list [% cc_list FILTER html %] must be less than 200 characters long.
+
+ [% ELSIF error == "flag_type_component_without_product" %]
+ [% title = "Product Missing" %]
+ A component was selected without a product being selected.
+
+ [% ELSIF error == "flag_type_description_invalid" %]
+ [% title = "Flag Type Description Invalid" %]
+ [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags'} %]
+ You must enter a description for this flag type.
+
+ [% ELSIF error == "flag_type_name_invalid" %]
+ [% title = "Flag Type Name Invalid" %]
+ [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags'} %]
+ The name <em>[% name FILTER html %]</em> must be 1-50 characters long
+ and must not contain any spaces or commas.
+
+ [% ELSIF error == "flag_type_not_editable" %]
+ [% title = "Flag Type Not Editable" %]
+ You are not allowed to edit properties of the '[% flagtype.name FILTER html %]'
+ flag type, because this flag type is not available for the products you can administer.
+
+ [% ELSIF error == "flag_type_not_multiplicable" %]
+ [% docslinks = {'flags-overview.html' => 'An overview on Flags',
+ 'flags.html' => 'Using Flags'} %]
+ You cannot have several <em>[% type.name FILTER html %]</em> flags
+ for this [% IF attachment %] attachment [% ELSE %] [%+ terms.bug %] [% END %].
+
+ [% ELSIF error == "flag_update_denied" %]
+ [% title = "Flag Modification Denied" %]
+ [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags',
+ 'groups.html' => 'Group Security'} %]
+ [% docslinks = {'flags-overview.html' => 'An overview on Flags',
+ 'flags.html' => 'Using Flags'} %]
+ You tried to [% IF status == "+" %] grant [% ELSIF status == "-" %] deny
+ [% ELSIF status == "X" %] clear [% ELSE %] request [% END %]
+ <code>[% name FILTER html %]
+ [% IF status == "X" %][% old_status FILTER html %][% END %]</code>.
+
+ Only a user with the required permissions may make this change.
+
+ [% ELSIF error == "format_not_found" %]
+ [% title = "Format Not Found" %]
+ The requested format <em>[% format FILTER html %]</em> does not exist with
+ a content type of <em>[% ctype FILTER html %]</em>.
+ [% IF invalid %]
+ Both parameters must contain letters and hyphens only.
+ [% END %]
+
+ [% ELSIF error == "flag_type_sortkey_invalid" %]
+ [% title = "Flag Type Sort Key Invalid" %]
+ The sort key <em>[% sortkey FILTER html %]</em> must be an integer
+ between 0 and [% constants.MAX_SMALLINT FILTER none %].
+
+ [% ELSIF error == "freetext_too_long" %]
+ [% title = "Text Too Long" %]
+ The text you entered in the [% field_descs.$field FILTER html %]
+ field is too long ([% text.length FILTER html %] characters,
+ above the maximum length allowed of
+ [%+ constants.MAX_FREETEXT_LENGTH FILTER none %] characters).
+
+ [% ELSIF error == "group_cannot_delete" %]
+ [% title = "Cannot Delete Group" %]
+ The <em>[% group.name FILTER html %]</em> group cannot be deleted because
+ there are
+ <a href="editgroups.cgi?action=del&amp;group=
+ [%- group.id FILTER uri %]">records</a>
+ in the database which refer to it. All references to this group must
+ be removed before you can remove it.
+
+ [% ELSIF error == "group_exists" %]
+ [% title = "The group already exists" %]
+ The group [% name FILTER html %] already exists.
+
+ [% ELSIF error == "group_has_special_role" %]
+ [% title = "Group not deletable" %]
+ [% IF groups.size == 1 %]
+ [% attr = "it" %]
+ [% param = "parameter" %]
+ [% ELSE %]
+ [% attr = "them" %]
+ [% param = "parameters" %]
+ [% END %]
+ The group '[% name FILTER html %]' is used by the
+ '[% groups.join("' and '") FILTER html %]' [% param FILTER html %].
+ In order to delete this group, you first have to change the
+ [%+ param FILTER html %] to make [% attr FILTER html %] point to another group.
+
+
+ [% ELSIF error == "group_invalid_removal" %]
+ You tried to remove [% terms.bug %] [%+ bug_id FILTER html %]
+ from the '[% name FILTER html %]' group, but either this group does not exist,
+ or you are not allowed to remove [% terms.bugs %] from this group in the
+ '[% product FILTER html %]' product.
+
+ [% ELSIF error == "group_restriction_not_allowed" %]
+ [% title = "Group Restriction Not Allowed" %]
+ You tried to restrict [% bug_id ? "$terms.bug $bug_id" : terms.abug FILTER html %]
+ to the '[% name FILTER html %]' group, but either this group does not exist,
+ or you are not allowed to restrict [% terms.bugs %] to this group in the
+ '[% product FILTER html %]' product.
+
+ [% ELSIF error == "group_not_specified" %]
+ [% title = "Group not specified" %]
+ No group was specified.
+
+ [% ELSIF error == "group_not_visible" %]
+ [% title = "Group Not Allowed" %]
+ You are not allowed to see members of the [% group.name FILTER html %]
+ group.
+
+ [% ELSIF error == "system_group_not_deletable" %]
+ [% title = "System Groups not deletable" %]
+ <em>[% name FILTER html %]</em> is a system group.
+ This group cannot be deleted.
+
+ [% ELSIF error == "illegal_attachment_edit" %]
+ [% title = "Unauthorized Action" %]
+ You are not authorized to edit attachment [% attach_id FILTER html %].
+
+ [% ELSIF error == "illegal_attachment_edit_bug" %]
+ [% title = "Unauthorized Action" %]
+ You are not authorized to edit attachments on [% terms.bug %]
+ [%+ bug_id FILTER html %].
+
+ [% ELSIF error == "illegal_bug_status_transition" %]
+ [% title = "Illegal $terms.Bug Status Change" %]
+ [% IF old.defined %]
+ You are not allowed to change the [% terms.bug %] status from
+ [%+ old.name FILTER html %] to [% new.name FILTER html %].
+ [% ELSE %]
+ You are not allowed to file new [% terms.bugs %] with the
+ [%+ new.name FILTER html %] status.
+ [% END %]
+
+ [% ELSIF error == "illegal_change" %]
+ [% title = "Not allowed" %]
+ You tried to change the
+ <strong>[% field_descs.$field FILTER html %]</strong> field
+ [% IF oldvalue.defined AND oldvalue != "" %]
+ from <em>[% oldvalue.join(', ') FILTER html %]</em>
+ [% END %]
+ [% IF newvalue.defined AND newvalue != "" %]
+ to <em>[% newvalue.join(', ') FILTER html %]</em>
+ [% END %],
+ but only
+ [% IF privs < constants.PRIVILEGES_REQUIRED_EMPOWERED %]
+ the assignee
+ [% IF privs < constants.PRIVILEGES_REQUIRED_ASSIGNEE %] or reporter [% END %]
+ of the [% terms.bug %], or
+ [% END %]
+ a user with the required permissions may change that field.
+
+ [% ELSIF error == "illegal_change_deps" %]
+ [% title = "Not allowed" %]
+ You tried to change the
+ <strong>[% field_descs.$field FILTER html %]</strong> field
+ but only a user allowed to edit
+ both related [% terms.bugs %] may change that field.
+
+ [% ELSIF error == "illegal_date" %]
+ [% title = "Illegal Date" %]
+ '<tt>[% date FILTER html %]</tt>' is not a legal date.
+ [% IF format %]
+ Please use the format '<tt>[% format FILTER html %]</tt>'.
+ [% END %]
+
+ [% ELSIF error == "illegal_email_address" %]
+ [% title = "Invalid Email Address" %]
+ The e-mail address you entered (<b>[% addr FILTER html %]</b>)
+ didn't pass our syntax checking for a legal email address.
+ [% IF default %]
+ A legal address must contain exactly one '@',
+ and at least one '.' after the @.
+ [% ELSE %]
+ [%+ Param('emailregexpdesc') FILTER html_light %]
+ [% END %]
+ It also must not contain any illegal characters.
+
+ [% ELSIF error == "illegal_frequency" %]
+ [% title = "Too Frequent" %]
+ Unless you are an administrator, you may not create series which are
+ run more often than once every [% minimum FILTER html %] days.
+
+ [% ELSIF error == "illegal_group_control_combination" %]
+ [% title = "Your Group Control Combination Is Illegal" %]
+ [% admindocslinks = {'groups.html' => 'Assigning Group Controls to Products'} %]
+ Your group control combination for group &quot;
+ [% groupname FILTER html %]&quot; is illegal.
+
+ [% ELSIF error == "illegal_query_name" %]
+ [% title = "Illegal Search Name" %]
+ The name of your search cannot contain any of the following characters:
+ &lt;, &gt;, &amp;.
+
+ [% ELSIF error == "illegal_series_creation" %]
+ [% admindocslinks = {'groups.html' => 'Group security'} %]
+ [% docslinks = {'reporting.html' => 'Reporting'} %]
+ You are not authorized to create series.
+
+ [% ELSIF error == "illegal_series_edit" %]
+ [% admindocslinks = {'groups.html' => 'Group security'} %]
+ [% docslinks = {'reporting.html' => 'Reporting'} %]
+ You are not authorized to edit this series. To do this, you must either
+ be its creator, or an administrator.
+
+ [% ELSIF error == "illegal_time" %]
+ [% title = "Illegal Time" %]
+ '<tt>[% time FILTER html %]</tt>' is not a legal time.
+ [% IF format %]
+ Please use the format '<tt>[% format FILTER html %]</tt>'.
+ [% END %]
+
+ [% ELSIF error == "illegal_regexp" %]
+ [% title = "Illegal Regular Expression" %]
+ The regular expression you provided [% value FILTER html %] is not valid.
+ The error was: [% dberror FILTER html %].
+
+ [% ELSIF error == "insufficient_data_points" %]
+ [% docslinks = {'reporting.html' => 'Reporting'} %]
+ We don't have enough data points to make a graph (yet).
+
+ [% ELSIF error == "invalid_attach_id" %]
+ [% title = "Invalid Attachment ID" %]
+ The attachment id [% attach_id FILTER html %] is invalid.
+
+ [% ELSIF error == "bug_id_does_not_exist" %]
+ [% title = BLOCK %]Invalid [% terms.Bug %] ID[% END %]
+ [% terms.Bug %] #[% bug_id FILTER html %] does not exist.
+
+ [% ELSIF error == "improper_bug_id_field_value" %]
+ [% title = BLOCK %]
+ [% IF bug_id %]Invalid [% ELSE %]Missing [% END %] [% terms.Bug %] ID
+ [% END %]
+ [% IF bug_id %]
+ '[% bug_id FILTER html %]' is not a valid [% terms.bug %] number
+ nor an alias to [% terms.abug %].
+ [% ELSE %]
+ [% IF field %]
+ The '[% field_descs.$field FILTER html %]' field
+ cannot be empty.
+ [% END %]
+ You must enter a valid [% terms.bug %] number!
+ [% END %]
+
+ [% ELSIF error == "invalid_changedsince" %]
+ [% title = "Invalid 'Changed Since'" %]
+ The 'changed since' value, '[% changedsince FILTER html %]', must be an
+ integer >= 0.
+
+ [% ELSIF error == "invalid_content_type" %]
+ [% title = "Invalid Content-Type" %]
+ The content type <em>[% contenttype FILTER html %]</em> is invalid.
+ Valid types must be of the form <em>foo/bar</em> where <em>foo</em>
+ is one of <em>[% constants.LEGAL_CONTENT_TYPES.join(', ') FILTER html %]</em>
+ and <em>bar</em> must not contain any special characters (such as "=", "?", ...).
+
+ [% ELSIF error == "invalid_context" %]
+ [% title = "Invalid Context" %]
+ The context [% context FILTER html %] is invalid (must be a number,
+ "file" or "patch").
+
+ [% ELSIF error == "invalid_datasets" %]
+ [% title = "Invalid Datasets" %]
+ Invalid datasets <em>[% datasets.join(":") FILTER html %]</em>. Only digits,
+ letters and colons are allowed.
+
+ [% ELSIF error == "invalid_dimensions" %]
+ [% title = "Invalid Dimensions" %]
+ The width or height specified is not a positive integer.
+
+ [% ELSIF error == "invalid_format" %]
+ [% title = "Invalid Format" %]
+ The format "[% format FILTER html %]" is invalid (must be one of
+ [% FOREACH my_format = formats %]
+ "[% my_format FILTER html %]"
+ [% END %]
+ ).
+
+ [% ELSIF error == "invalid_group_ID" %]
+ [% title = "Invalid group ID" %]
+ The group you specified doesn't exist.
+
+ [% ELSIF error == "invalid_group_name" %]
+ [% title = "Invalid group name" %]
+ The group you specified, [% name FILTER html %], is not valid here.
+
+ [% ELSIF error == "invalid_keyword_id" %]
+ The keyword ID <em>[% id FILTER html %]</em> couldn't be found.
+
+ [% ELSIF error == "invalid_maxrows" %]
+ [% title = "Invalid Max Rows" %]
+ The maximum number of rows, '[% maxrows FILTER html %]', must be
+ a positive integer.
+
+ [% ELSIF error == "invalid_parameter" %]
+ [% title = "Invalid Parameter" %]
+ The new value for [% name FILTER html %] is invalid: [% err FILTER html %].
+
+ [% ELSIF error == "invalid_product_name" %]
+ [% title = "Invalid Product Name" %]
+ The product name '[% product FILTER html %]' is invalid or does not exist.
+
+ [% ELSIF error == "invalid_regexp" %]
+ [% title = "Invalid regular expression" %]
+ The regular expression you entered is invalid.
+
+ [% ELSIF error == "invalid_user" %]
+ [% title = "Invalid User" %]
+ There is no user account
+ [% IF user_id %]
+ with ID <em>[% user_id FILTER html %]</em>.
+ [% ELSIF user_login %]
+ with login name <em>[% user_login FILTER html %]</em>.
+ [% ELSE %]
+ given.
+ [% END %]
+
+ [% ELSIF error == "invalid_user_group" %]
+ [% title = "Invalid User Group" %]
+ [% IF users.size > 1 %] Users [% ELSE %] User [% END %]
+ '[% users.join(', ') FILTER html %]'
+ [% IF users.size > 1 %] are [% ELSE %] is [% END %]
+ not able to edit the
+ [% IF product %]
+ '[% product FILTER html %]'
+ [% END %]
+ [%+ field_descs.product FILTER html %]
+ [% IF bug_id %]
+ for [% terms.bug %] '[% bug_id FILTER html %]'.
+ [% ELSIF new %]
+ and may not be included on a new [% terms.bug %].
+ [% ELSE %]
+ for at least one [% terms.bug %] being changed.
+ [% END %]
+
+ [% ELSIF error == "invalid_username" %]
+ [% title = "Invalid Username" %]
+ The name <tt>[% name FILTER html %]</tt> is not a valid username.
+ Either you misspelled it, or the person has not
+ registered for a [% terms.Bugzilla %] account.
+
+ [% ELSIF error == "invalid_username_or_password" %]
+ [% title = "Invalid Username Or Password" %]
+ The username or password you entered is not valid.
+ [%# People get two login attempts before being warned about
+ # being locked out.
+ #%]
+ [% IF remaining <= 2 %]
+ If you do not enter the correct password after
+ [%+ remaining FILTER html %] more attempt(s), you will be
+ locked out of this account for
+ [%+ constants.LOGIN_LOCKOUT_INTERVAL FILTER html %] minutes.
+ To avoid being locked out, you can reset your password using
+ the "Forgot Password" link.
+ [% END %]
+
+ [% ELSIF error == "json_rpc_get_method_required" %]
+ When using JSON-RPC over GET, you must specify a 'method'
+ parameter. See the documentation at
+ [%+ docs_urlbase FILTER html %]api/Bugzilla/WebService/Server/JSONRPC.html
+
+ [% ELSIF error == "json_rpc_illegal_content_type" %]
+ When using JSON-RPC over POST, you cannot send data as
+ [%+ content_type FILTER html %]. Only application/json and
+ application/json-rpc are allowed.
+
+ [% ELSIF error == "json_rpc_invalid_params" %]
+ Could not parse the 'params' argument as valid JSON.
+ Error: [% err_msg FILTER html %]
+ Value: [% params FILTER html %]
+
+ [% ELSIF error == "json_rpc_invalid_callback" %]
+ You cannot use '[% callback FILTER html %]' as your 'callback' parameter.
+ For security reasons, only letters, numbers, and the following
+ characters are allowed in the 'callback' parameter: <code>[]._</code>
+
+ [% ELSIF error == "json_rpc_post_only" %]
+ For security reasons, you must use HTTP POST to call the
+ '[% method FILTER html %]' method.
+
+ [% ELSIF error == "keyword_already_exists" %]
+ [% title = "Keyword Already Exists" %]
+ A keyword with the name [% name FILTER html %] already exists.
+
+ [% ELSIF error == "keyword_blank_description" %]
+ [% title = "Blank Keyword Description Not Allowed" %]
+ You must enter a non-blank description for the keyword.
+
+ [% ELSIF error == "keyword_blank_name" %]
+ [% title = "Blank Keyword Name Not Allowed" %]
+ You must enter a non-blank name for the keyword.
+
+ [% ELSIF error == "keyword_invalid_name" %]
+ [% title = "Invalid Keyword Name" %]
+ You may not use commas or whitespace in a keyword name.
+
+ [% ELSIF error == "login_needed_for_password_change" %]
+ [% title = "Login Name Required" %]
+ You must enter a login name when requesting to change your password.
+
+ [% ELSIF error == "login_required_for_pronoun" %]
+ [% title = "Login Name Required" %]
+ You can't use %user% without being logged in, because %user% refers
+ to your login name, which we don't know.
+
+ [% ELSIF error == "login_required" %]
+ [%# Used for non-web-based LOGIN_REQUIRED situations. %]
+ You must log in before using this part of [% terms.Bugzilla %].
+
+ [% ELSIF error == "migrate_config_created" %]
+ The file <kbd>[% file FILTER html %]</kbd> contains configuration
+ variables that must be set before continuing with the migration.
+
+ [% ELSIF error == "migrate_from_invalid" %]
+ '[% from FILTER html %]' is not a valid type of [% terms.bug %]-tracker
+ to migrate from. See the contents of the <kbd>B[% %]ugzilla/Migrate/</kbd>
+ directory for a list of valid [% terms.bug %]-trackers.
+
+ [% ELSIF error == "milestone_already_exists" %]
+ [% title = "Milestone Already Exists" %]
+ [% admindocslinks = {'products.html' => 'Administering products',
+ 'milestones.html' => 'About Milestones'} %]
+ The milestone '[% name FILTER html %]' already exists for product '
+ [%- product FILTER html %]'.
+
+ [% ELSIF error == "milestone_blank_name" %]
+ [% title = "Blank Milestone Name Not Allowed" %]
+ You must enter a name for this milestone.
+
+ [% ELSIF error == "milestone_is_default" %]
+ [% title = "Default milestone not deletable" %]
+ [% admindocslinks = {'products.html' => 'Administering products',
+ 'milestones.html' => 'About Milestones'} %]
+ Sorry, but [% milestone.name FILTER html %] is the default milestone
+ for the '[% milestone.product.name FILTER html %]' product, and so
+ it cannot be deleted.
+
+ [% ELSIF error == "milestone_name_too_long" %]
+ [% title = "Milestone Name Is Too Long" %]
+ The name of a milestone is limited to [% constants.MAX_MILESTONE_SIZE FILTER html %]
+ characters. '[% name FILTER html %]' is too long ([% name.length %] characters).
+
+ [% ELSIF error == "milestone_required" %]
+ [% title = "Milestone Required" %]
+ You must select a target milestone for [% terms.bug %]
+ [%+ bug.id FILTER html %]
+ if you are going to accept it. Part of accepting
+ [%+ terms.abug %] is giving an estimate of when it will be fixed.
+
+ [% ELSIF error == "milestone_sortkey_invalid" %]
+ [% title = "Invalid Milestone Sortkey" %]
+ The sortkey '[% sortkey FILTER html %]' is not in the range
+ [%+ constants.MIN_SMALLINT FILTER html %] &le; sortkey &le;
+ [%+ constants.MAX_SMALLINT FILTER html %].
+
+ [% ELSIF error == "misarranged_dates" %]
+ [% title = "Misarranged Dates" %]
+ Your start date ([% datefrom FILTER html %]) is after
+ your end date ([% dateto FILTER html %]).
+
+ [% ELSIF error == "mismatched_bug_ids_on_obsolete" %]
+ Attachment [% attach_id FILTER html %] is attached to another [% terms.bug %],
+ but you tried to flag it as obsolete while creating a new attachment to
+ [%+ terms.bug %] [%+ my_bug_id FILTER html %].
+
+ [% ELSIF error == "missing_attachment_description" %]
+ [% title = "Missing Attachment Description" %]
+ You must enter a description for the attachment.
+
+ [% ELSIF error == "missing_bug_id" %]
+ [% title = "Missing $terms.Bug ID" %]
+ No [% terms.bug %] ID was given.
+
+ [% ELSIF error == "missing_category" %]
+ [% title = "Missing Category" %]
+ You did not specify a category for this series.
+
+ [% ELSIF error == "missing_component" %]
+ [% title = "Missing Component" %]
+ [% admindocslinks = {'products.html' => 'Administering products',
+ 'components.html' => 'Creating a component'} %]
+ Sorry, the product <em>[% product.name FILTER html %]</em>
+ has to have at least one active component in order for you to
+ enter [% terms.abug %] into it.<br>
+ [% IF user.in_group("editcomponents", product.id) %]
+ <a href="editcomponents.cgi?action=add&amp;product=[% product.name FILTER uri %]">Create
+ a new component</a>.
+ [% ELSE %]
+ Please contact [% Param("maintainer") %] and ask them
+ to add a component to this product.
+ [% END %]
+
+ [% ELSIF error == "missing_content_type" %]
+ [% title = "Missing Content-Type" %]
+ You asked [% terms.Bugzilla %] to auto-detect the content type, but
+ your browser did not specify a content type when uploading the file,
+ so you must enter a content type manually.
+
+ [% ELSIF error == "missing_cookie" %]
+ [% title = "Missing Cookie" %]
+ Sorry, I seem to have lost the cookie that recorded
+ the results of your last search. I'm afraid you will have to start
+ again from the <a href="query.cgi">search page</a>.
+
+ [% ELSIF error == "missing_datasets" %]
+ [% title = "No Datasets Selected" %]
+ [% docslinks = {'reporting.html' => 'Reporting'} %]
+ You must specify one or more datasets to plot.
+
+ [% ELSIF error == "missing_frequency" %]
+ [% title = "Missing Frequency" %]
+ [% docslinks = {'reporting.html' => 'Reporting'} %]
+ You did not specify a valid frequency for this series.
+
+ [% ELSIF error == "missing_name" %]
+ [% title = "Missing Name" %]
+ [% docslinks = {'reporting.html' => 'Reporting'} %]
+ You did not specify a name for this series.
+
+ [% ELSIF error == "missing_query" %]
+ [% title = "Missing Search" %]
+ [% docslinks = {'query.html' => "Searching for $terms.bugs",
+ 'query.html#list' => "$terms.Bug lists"} %]
+ The search named <em>[% name FILTER html %]</em>
+ [% IF sharer_id && sharer_id != user.id %]
+ has not been made visible to you.
+ [% ELSE %]
+ does not exist.
+ [% END %]
+
+ [% ELSIF error == "need_quipid" %]
+ [% title = "Missing Quip ID" %]
+ A valid quip ID is needed.
+
+ [% ELSIF error == "missing_resolution" %]
+ [% title = "Resolution Required" %]
+ A valid resolution is required to mark [% terms.bugs %] as
+ [%+ status FILTER upper FILTER html %].
+
+ [% ELSIF error == "missing_subcategory" %]
+ [% title = "Missing Subcategory" %]
+ You did not specify a subcategory for this series.
+
+ [% ELSIF error == "missing_version" %]
+ [% title = "Missing Version" %]
+ [% admindocslinks = {'versions.html' => 'Defining versions'} %]
+ Sorry, the product <em>[% product.name FILTER html %]</em>
+ has to have at least one active version in order for you to
+ enter [% terms.abug %] into it.<br>
+ [% IF user.in_group("editcomponents", product.id) %]
+ <a href="editversions.cgi?action=add&amp;product=[% product.name FILTER uri %]">Create
+ a new version</a>.
+ [% ELSE %]
+ Please contact [% Param("maintainer") %] and ask them
+ to add a version to this product.
+ [% END %]
+
+ [% ELSIF error == "multiple_alias_not_allowed" %]
+ You cannot set aliases when modifying multiple [% terms.bugs %]
+ at once.
+
+ [% ELSIF error == "need_quip" %]
+ [% title = "Quip Required" %]
+ [% docslinks = {'quips.html' => 'About quips'} %]
+ Please enter a quip in the text field.
+
+ [% ELSIF error == "new_password_missing" %]
+ [% title = "New Password Missing" %]
+ You must enter a new password.
+
+ [% ELSIF error == "no_axes_defined" %]
+ [% title = "No Axes Defined" %]
+ [% docslinks = {'reporting.html' => 'Reporting'} %]
+ You didn't define any axes to plot.
+
+ [% ELSIF error == "no_bugs_chosen" %]
+ [% title = BLOCK %]No [% terms.Bugs %] Selected[% END %]
+ You apparently didn't choose any [% terms.bugs %]
+ [% IF action == "modify" %]
+ to modify.
+ [% ELSIF action == "view" %]
+ to view.
+ [% END %]
+
+ [% ELSIF error == "no_tag_to_edit" %]
+ [% title = "No Tag Selected" %]
+ You tried to create or remove a tag with no name.
+
+ [% ELSIF error == "no_initial_bug_status" %]
+ [% title = "No Initial $terms.Bug Status" %]
+ No [% terms.bug %] status is available on [% terms.bug %] creation.
+ Please report the problem to [% Param("maintainer") %].
+
+ [% ELSIF error == "no_new_quips" %]
+ [% title = "No New Quips" %]
+ [% admindocslinks = {'quips.html' => 'Controlling quip usage'} %]
+ This site does not permit the addition of new quips.
+
+ [% ELSIF error == "no_page_specified" %]
+ [% title = "No Page Specified" %]
+ You did not specify the id of a page to display.
+
+ [% ELSIF error == "no_products" %]
+ [% title = "No Products" %]
+ [% admindocslinks = {'products.html' => 'Setting up a product',
+ 'components.html' => 'Adding components to products',
+ 'groups.html' => 'Groups security'} %]
+ Either no products have been defined to enter [% terms.bugs %] against or you have not
+ been given access to any.
+
+ [% ELSIF error == "number_not_numeric" %]
+ [% title = "Numeric Value Required" %]
+ The value '[% num FILTER html %]' in the
+ <em>[% field_descs.$field FILTER html %]</em> field
+ is not a numeric value.
+
+ [% ELSIF error == "number_too_large" %]
+ [% title = "Number Too Large" %]
+ The value '[% num FILTER html %]' in the
+ <em>[% field_descs.$field FILTER html %]</em> field
+ is more than the maximum allowable value of '[% max_num FILTER html %]'.
+
+ [% ELSIF error == "number_too_small" %]
+ [% title = "Number Too Small" %]
+ The value '[% num FILTER html %]'
+ in the <em>[% field_descs.$field FILTER html %]</em> field
+ is less than the minimum allowable value of '[% min_num FILTER html %]'.
+
+ [% ELSIF error == "object_not_specified" %]
+ [% type = BLOCK %][% INCLUDE object_name class = class %][% END %]
+ [% title = BLOCK %][% type FILTER ucfirst FILTER html %] Not
+ Specified[% END %]
+ You must select/enter a [% type FILTER html %].
+
+ [% ELSIF error == "object_does_not_exist" %]
+ [% type = BLOCK %][% INCLUDE object_name class = class %][% END %]
+ [% title = BLOCK %]Invalid [% type FILTER ucfirst FILTER html %][% END %]
+ There is no [% type FILTER html %]
+ [% IF id.defined %]
+ with the id '[% id FILTER html %]'
+ [% ELSE %]
+ named '[% name FILTER html %]'
+ [% END %]
+ [% IF product.defined %]
+ in the '[% product.name FILTER html %]' product
+ [% END %].
+ [% IF class == "Bugzilla::User" %]
+ Either you mis-typed the name or that user has not yet registered
+ for a [% terms.Bugzilla %] account.
+ [% ELSIF class == "Bugzilla::Keyword" %]
+ The legal keyword names are <a href="describekeywords.cgi">listed
+ here</a>.
+ [% END %]
+
+ [% ELSIF error == "old_password_incorrect" %]
+ [% title = "Incorrect Password" %]
+ You did not enter your current password correctly.
+
+ [% ELSIF error == "old_password_required" %]
+ [% title = "Old Password Required" %]
+ You must enter your old password to change your email address.
+
+ [% ELSIF error == "password_change_requests_not_allowed" %]
+ [% title = "Password Change Requests Not Allowed" %]
+ The system is not configured to allow password change requests.
+
+ [% ELSIF error == "passwords_dont_match" %]
+ [% title = "Passwords Don't Match" %]
+ The two passwords you entered did not match.
+
+ [% ELSIF error == "password_current_too_short" %]
+ [% title = "New Password Required" %]
+ Your password is currently less than
+ [%+ constants.USER_PASSWORD_MIN_LENGTH FILTER html %] characters long,
+ which is the new minimum length required for passwords.
+ You must <a href="token.cgi?a=reqpw&amp;loginname=[% locked_user.email FILTER uri %]">
+ request a new password</a> in order to log in again.
+
+ [% ELSIF error == "password_too_short" %]
+ [% title = "Password Too Short" %]
+ The password must be at least
+ [%+ constants.USER_PASSWORD_MIN_LENGTH FILTER html %] characters long.
+
+ [% ELSIF error == "password_not_complex" %]
+ [% title = "Password Fails Requirements" %]
+ [% passregex = Param('password_complexity') %]
+ The password must contain at least one:
+ <ul>
+ [% IF passregex == 'letters_numbers_specialchars' %]
+ <li>letter</li>
+ <li>special character</li>
+ [% ELSIF passregex.search('letters') %]
+ <li>UPPERCASE letter</li>
+ <li>lowercase letter</li>
+ [% END %]
+ [% IF passregex.search('numbers') %]
+ <li>digit</li>
+ [% END %]
+ </ul>
+
+ [% ELSIF error == "product_access_denied" %]
+ [% title = "Product Access Denied" %]
+ Either the product
+ [%+ IF id.defined %]
+ with the id [% id FILTER html %]
+ [% ELSE %]
+ '[% name FILTER html %]'
+ [% END %]
+ does not exist or you don't have access to it.
+
+ [% ELSIF error == "product_illegal_group" %]
+ [% title = "Illegal Group" %]
+ [% group.name FILTER html %] is not an active [% terms.bug %] group
+ and so you cannot edit group controls for it.
+
+ [% ELSIF error == "product_name_already_in_use" %]
+ [% title = "Product name already exists" %]
+ [% admindocslinks = {'products.html' => 'Administering products'} %]
+ The product name '[% product FILTER html %]' already exists.
+
+ [% ELSIF error == "product_name_diff_in_case" %]
+ [% title = "Product name differs only in case" %]
+ [% admindocslinks = {'products.html' => 'Administering products'} %]
+ The product name '[% product FILTER html %]' differs from existing
+ product '[% existing_product FILTER html %]' only in case.
+
+ [% ELSIF error == "product_name_too_long" %]
+ [% title = "Product name too long" %]
+ The name of a product is limited to [% constants.MAX_PRODUCT_SIZE FILTER html %]
+ characters. '[% name FILTER html %]' is too long ([% name.length %] characters).
+
+ [% ELSIF error == "product_must_define_defaultmilestone" %]
+ [% title = "Must define new default milestone" %]
+ [% admindocslinks = {'products.html' => 'Administering products',
+ 'milestones.html' => 'About Milestones'} %]
+ You must <a href="editmilestones.cgi?action=add&amp;product=[% product FILTER uri %]">
+ create the milestone '[% milestone FILTER html %]'</a> before
+ it can be made the default milestone for product '[% product FILTER html %]'.
+
+ [% ELSIF error == "product_admin_denied" %]
+ [% title = "Product Access Denied" %]
+ You are not allowed to edit properties of product '[% product FILTER html %]'.
+
+ [% ELSIF error == "product_blank_name" %]
+ [% title = "Blank Product Name Not Allowed" %]
+ [% admindocslinks = {'products.html' => 'Administering products'} %]
+ You must enter a name for the product.
+
+ [% ELSIF error == "product_disabled" %]
+ [% title = BLOCK %]Product closed for [% terms.Bug %] Entry[% END %]
+ [% admindocslinks = {'products.html' => 'Administering products'} %]
+ Sorry, entering [% terms.abug %] into the
+ product <em>[% product.name FILTER html %]</em> has been disabled.
+
+ [% ELSIF error == "product_edit_denied" %]
+ [% title = "Product Edit Access Denied" %]
+ [% admindocslinks = {'products.html' => 'Administering products',
+ 'groups.html' => 'Group security'} %]
+ You are not permitted to edit [% terms.bugs %] in product
+ [%+ product FILTER html %].
+
+ [% ELSIF error == "product_has_bugs" %]
+ [% title = BLOCK %]Product has [% terms.Bugs %][% END %]
+ [% admindocslinks = {'products.html' => 'Administering products'} %]
+ There are [% nb FILTER html %] [%+ terms.bugs %] entered for this product!
+ You must move those [% terms.bugs %] to another product before you
+ can delete this one.
+
+ [% ELSIF error == "product_must_have_description" %]
+ [% title = "Product needs Description" %]
+ [% admindocslinks = {'products.html' => 'Administering products'} %]
+ You must enter a description for this product.
+
+ [% ELSIF error == "product_must_have_version" %]
+ [% title = "Product needs Version" %]
+ [% admindocslinks = {'products.html' => 'Administering products',
+ 'versions.html' => 'Administering versions'} %]
+ You must enter a valid version to create a new product.
+
+ [% ELSIF error == "product_unknown_component" %]
+ [% title = "Unknown Component" %]
+ Product '[% product FILTER html %]' has no component
+ [% IF comp_id %]
+ with ID [% comp_id FILTER html %].
+ [% ELSE %]
+ named '[% comp FILTER html %]'.
+ [% END %]
+
+ [% ELSIF error == "query_name_missing" %]
+ [% title = "No Search Name Specified" %]
+ [% docslinks = {'query.html#list' => "$terms.Bug lists"} %]
+ You must enter a name for your search.
+
+ [% ELSIF error == "query_name_too_long" %]
+ [% title = "Query Name Too Long" %]
+ The name of the query must be less than [% constants.MAX_LEN_QUERY_NAME FILTER html %]
+ characters long.
+
+ [% ELSIF error == "quicksearch_invalid_query" %]
+ [% title = "Invalid Query" %]
+ Your query is invalid.
+ [% IF operators %]
+ The [% operators.shift FILTER html %] operator cannot be followed by
+ [%+ operators.shift FILTER html %].
+ [% ELSE %]
+ A query cannot start with AND or OR, nor can it end with AND, OR or NOT.
+ They are reserved operators and must be quoted if you want to look for
+ these strings.
+ [% END %]
+
+ [% ELSIF error == "quicksearch_unbalanced_quotes" %]
+ [% title = "Badly Formatted Query" %]
+ [% terms.Bugzilla %] is unable to parse your query correctly:
+ <em>[% string FILTER html %]</em>.<br>
+ If you use quotes to enclose strings, make sure both quotes are present.
+ If you really want to look for a quote in a string, type \" instead of ".
+ For instance, <em>"I'm so \"special\", really"</em> (with quotes) will be
+ interpreted as <em>I'm so "special", really</em>.
+
+ [% ELSIF error == "quicksearch_unknown_field" %]
+ [% title = "QuickSearch Error" %]
+ There is a problem with your search:
+ [% FOREACH field = unknown %]
+ <p><code>[% field FILTER html %]</code> is not a valid field name.</p>
+ [% END %]
+ [% FOREACH field = ambiguous.keys %]
+ <p><code>[% field FILTER html %]</code> matches more than one field:
+ [%+ ambiguous.${field}.join(', ') FILTER html %]</p>
+ [% END %]
+
+ [% IF unknown.size %]
+ <p>The legal field names are
+ <a href="page.cgi?id=quicksearch.html#fields">listed here</a>.</p>
+ [% END %]
+
+ [% ELSIF error == "quip_too_long" %]
+ [% title = "Quip Too Long" %]
+ You entered a quip with a length of [% length FILTER none %] characters,
+ but the maximum allowed length is [% constants.MAX_QUIP_LENGTH FILTER none %]
+ characters.
+
+ [% ELSIF error == "reassign_to_empty" %]
+ [% title = "Illegal Reassignment" %]
+ To reassign [% terms.abug %], you must provide an address for
+ the new assignee.
+
+ [% ELSIF error == "report_axis_invalid" %]
+ [% title = "Invalid Axis" %]
+ <em>[% val FILTER html %]</em> is not a valid value for
+ [%+ IF fld == "x" %]the horizontal axis
+ [%+ ELSIF fld == "y" %]the vertical axis
+ [%+ ELSIF fld == "z" %]the multiple tables/images
+ [%+ ELSE %]a report axis[% END %] field.
+
+ [% ELSIF error == "report_name_missing" %]
+ [% title = "No Report Name Specified" %]
+ You must enter a name for your report.
+
+ [% ELSIF error == "report_access_denied" %]
+ [% title = "Report Access Denied" %]
+ You cannot access this report.
+
+ [% ELSIF error == "require_component" %]
+ [% title = "Component Needed" %]
+ To file this [% terms.bug %], you must first choose a component.
+ If necessary, just guess.
+
+ [% ELSIF error == "relationship_loop_single" %]
+ [% title = "Relationship Loop Detected" %]
+ [% field_descs.$field_name FILTER html %]
+ for [% terms.bug %] [%+ bug_id FILTER html %]
+ has a circular dependency on [% terms.bug %] [%+ dep_id FILTER html %].
+
+ [% ELSIF error == "request_queue_group_invalid" %]
+ The group field <em>[% group FILTER html %]</em> is invalid.
+
+ [% ELSIF error == "require_new_password" %]
+ [% title = "New Password Needed" %]
+ You cannot change your password without choosing a new one.
+
+ [% ELSIF error == "required_field" %]
+ [% title = "Field Must Be Set" %]
+ A value must be set for the '[% field_descs.${field.name} FILTER html %]'
+ field.
+
+ [% ELSIF error == "require_summary" %]
+ [% title = "Summary Needed" %]
+ You must enter a summary for this [% terms.bug %].
+
+ [% ELSIF error == "resolution_cant_clear" %]
+ [% terms.Bug %] [%+ bug_id FILTER bug_link(bug_id) FILTER none %] is
+ closed, so you cannot clear its resolution.
+
+ [% ELSIF error == "resolution_not_allowed" %]
+ [% title = "Resolution Not Allowed" %]
+ You cannot set a resolution for open [% terms.bugs %].
+
+ [% ELSIF error == "saved_search_used_by_whines" %]
+ [% title = "Saved Search In Use" %]
+ [% docslinks = {'whining.html' => 'About Whining'} %]
+ The saved search <em>[% search_name FILTER html %]</em> is being used
+ by <a href="editwhines.cgi">Whining events</a> with the following subjects:
+ [%+ subjects FILTER html %]
+
+ [% ELSIF error == "search_content_without_matches" %]
+ [% title = "Illegal Search" %]
+ The "content" field can only be used with "matches" search
+ and the "matches" search can only be used with the "content"
+ field.
+
+ [% ELSIF error == "search_grouped_field_invalid" %]
+ [% terms.Bugzilla %] does not support using the
+ "[%+ field_descs.$field FILTER html %]" ([% field FILTER html %])
+ field with grouped search conditions.
+
+ [% ELSIF error == "search_grouped_invalid_nesting" %]
+ You cannot nest clauses within grouped search conditions.
+
+ [% ELSIF error == "search_grouped_field_mismatch" %]
+ All conditions under a groups search must use the same field.
+
+ [% ELSIF error == "search_field_operator_invalid" %]
+ [% terms.Bugzilla %] does not support using the
+ "[%+ field_descs.$field FILTER html %]" ([% field FILTER html %])
+ field with the "[% search_descs.$operator FILTER html %]"
+ ([% operator FILTER html %]) search type.
+
+ [% ELSIF error == "see_also_self_reference" %]
+ You cannot put this [% terms.bug %] into its own
+ [%+ field_descs.see_also FILTER html %] field.
+
+ [% ELSIF error == "series_already_exists" %]
+ [% title = "Series Already Exists" %]
+ [% docslinks = {'reporting.html' => 'Reporting'} %]
+ A series named <em>[% series.category FILTER html %] /
+ [%+ series.subcategory FILTER html %] /
+ [%+ series.name FILTER html %]</em>
+ already exists.
+
+ [% ELSIF error == "still_unresolved_bugs" %]
+ [% title = "Unresolved Dependencies" %]
+ [% IF bug_id %]
+ [% terms.Bug %] [%+ bug_id FILTER bug_link(bug_id) FILTER none %]
+ [% ELSE %]
+ This [% terms.bug %]
+ [% END %]
+ has [% dep_count FILTER none %] unresolved
+ [% IF dep_count == 1 %]
+ dependency
+ [% ELSE %]
+ dependencies
+ [% END %].
+ They must either be resolved or removed from the
+ "[% field_descs.dependson FILTER html %]" field before you can resolve
+ this [% terms.bug %] as [% display_value("resolution", "FIXED") FILTER html %].
+
+ [% ELSIF error == "sudo_invalid_cookie" %]
+ [% title = "Invalid Sudo Cookie" %]
+ Your sudo cookie is invalid. Either it expired or you didn't start
+ a sudo session correctly. Refresh the page or load another page
+ to continue what you are doing as yourself.
+
+ [% ELSIF error == "sudo_illegal_action" %]
+ [% title = "Impersonation Not Authorized" %]
+ [% IF NOT sudoer.in_group("bz_sudoers") %]
+ You are not allowed to impersonate users.
+ [% ELSIF target_user AND target_user.in_group("bz_sudo_protect") %]
+ You are not allowed to impersonate [% target_user.identity FILTER html %].
+ [% ELSE %]
+ The user you tried to impersonate doesn't exist.
+ [% END %]
+
+ [% ELSIF error == "sudo_in_progress" %]
+ [% title = "Session In Progress" %]
+ A sudo session (impersonating [% target FILTER html %]) is in progress.
+ End that session (using the link in the footer) before starting a new one.
+
+ [% ELSIF error == "sudo_password_required" %]
+ [% title = "Password Required" %]
+ Your [% terms.Bugzilla %] password is required to begin a sudo
+ session. Please <a href="relogin.cgi?action=prepare-sudo&amp;target_login=
+ [%- target_login FILTER uri %]&amp;reason=
+ [%- reason FILTER uri %]">go back</a> and enter your password.
+
+ [% ELSIF error == "sudo_preparation_required" %]
+ [% title = "Preparation Required" %]
+ You may not start a sudo session directly. Please
+ <a href="relogin.cgi?action=prepare-sudo&amp;target_login=
+ [%- target_login FILTER uri %]&amp;reason=
+ [%- reason FILTER uri %]">start your session normally</a>.
+
+ [% ELSIF error == "sudo_protected" %]
+ [% title = "User Protected" %]
+ The user [% login FILTER html %] may not be impersonated by sudoers.
+
+ [% ELSIF error == "tag_name_too_long" %]
+ [% title = "Tag Name Too Long" %]
+ The tag name must be less than [% constants.MAX_LEN_QUERY_NAME FILTER html %]
+ characters long.
+
+ [% ELSIF error == "token_does_not_exist" %]
+ [% title = "Token Does Not Exist" %]
+ The token you submitted does not exist, has expired, or has
+ been canceled.
+
+ [% ELSIF error == "too_soon_for_new_token" %]
+ [% title = "Too Soon For New Token" %]
+ You have requested
+ [% IF type == "password" %]
+ a password
+ [% ELSIF type == "account" %]
+ an account
+ [% END %]
+ token too recently to request another.
+ Please wait [% constants.ACCOUNT_CHANGE_INTERVAL FILTER html %] minutes
+ then try again.
+
+ [% ELSIF error == "unknown_action" %]
+ [% IF action %]
+ Unknown action [% action FILTER html %]!
+ [% ELSE %]
+ I could not figure out what you wanted to do.
+ [% END %]
+
+ [% ELSIF error == "unknown_tab" %]
+ [% title = "Unknown Tab" %]
+ <code>[% current_tab_name FILTER html %]</code> is not a legal tab name.
+
+ [% ELSIF error == "value_inactive" %]
+ [% title = "Value is Not Active" %]
+ [% type = BLOCK %][% INCLUDE object_name class = class %][% END %]
+ The [% type FILTER html %] value '[% value FILTER html %]' is not active.
+
+ [% ELSIF error == "version_already_exists" %]
+ [% title = "Version Already Exists" %]
+ [% admindocslinks = {'versions.html' => 'Administering versions'} %]
+ The version '[% name FILTER html %]' already exists for product '
+ [%- product FILTER html %]'.
+
+ [% ELSIF error == "version_blank_name" %]
+ [% title = "Blank Version Name Not Allowed" %]
+ You must enter a name for this version.
+
+ [% ELSIF error == "version_has_bugs" %]
+ [% title = BLOCK %]Version has [% terms.Bugs %][% END %]
+ There are [% nb FILTER html %] [%+ terms.bugs %] associated with this
+ version! You must reassign those [% terms.bugs %] to another version
+ before you can delete this one.
+
+ [% ELSIF error == "version_is_last" %]
+ [% title = BLOCK %]Last Version in this Product[% END %]
+ '[% version.name FILTER html %]' is the last version of the
+ '[% version.product.name FILTER html %]' product. You cannot delete it.
+
+ [% ELSIF error == "users_deletion_disabled" %]
+ [% title = "Deletion not activated" %]
+ [% admindocslinks = {'useradmin.html' => 'User administration'} %]
+ Sorry, the deletion of user accounts is not allowed.
+
+ [% ELSIF error == "user_has_responsibility" %]
+ [% title = "Can't Delete User Account" %]
+ [% admindocslinks = {'useradmin.html' => 'User administration'} %]
+ The user you want to delete is set up as the default [% terms.bug %]
+ assignee
+ [% IF Param('useqacontact') %]
+ or QA contact
+ [% END %]
+ for at least one component.
+ For this reason, you cannot delete the account at this time.
+
+ [% ELSIF error == "user_access_by_id_denied" %]
+ [% title = "User Access By Id Denied" %]
+ Logged-out users cannot use the "ids" argument to this function
+ to access any user information.
+
+ [% ELSIF error == "user_access_by_match_denied" %]
+ [% title = "User-Matching Denied" %]
+ Logged-out users cannot use the "match" argument to this function
+ to access any user information.
+
+ [% ELSIF error == "user_login_required" %]
+ [% title = "Login Name Required" %]
+ [% admindocslinks = {'useradmin.html' => 'User administration'} %]
+ You must enter a login name for the new user.
+
+ [% ELSIF error == "user_match_failed" %]
+ [% title = "Match Failed" %]
+ <tt>[% name FILTER html %]</tt> does not exist or you are not allowed
+ to see that user.
+
+ [% ELSIF error == "user_match_too_many" %]
+ [% title = "No Conclusive Match" %]
+ [% terms.Bugzilla %] cannot make a conclusive match for one or more
+ of the names and/or email addresses you entered for
+ the [% fields.join(', ') FILTER html %] field(s).
+
+ [% ELSIF error == "user_not_insider" %]
+ [% title = "User Not In Insidergroup" %]
+ Sorry, but you are not allowed to (un)mark comments or attachments
+ as private.
+
+ [% ELSIF error == "wrong_token_for_cancelling_email_change" %]
+ [% title = "Wrong Token" %]
+ That token cannot be used to cancel an email address change.
+
+ [% ELSIF error == "wrong_token_for_changing_passwd" %]
+ [% title = "Wrong Token" %]
+ That token cannot be used to change your password.
+
+ [% ELSIF error == "wrong_token_for_confirming_email_change" %]
+ [% title = "Wrong Token" %]
+ That token cannot be used to change your email address.
+
+ [% ELSIF error == "wrong_token_for_creating_account" %]
+ [% title = "Wrong Token" %]
+ That token cannot be used to create a user account.
+
+ [% ELSIF error == "xmlrpc_invalid_value" %]
+ "[% value FILTER html %]" is not a valid value for a
+ &lt;[% type FILTER html %]&gt; field. (See the XML-RPC specification
+ for details.)
+
+ [% ELSIF error == "xmlrpc_illegal_content_type" %]
+ When using XML-RPC, you cannot send data as
+ [%+ content_type FILTER html %]. Allowed content types
+ are [% constants.XMLRPC_CONTENT_TYPE_WHITELIST.join(', ') FILTER html %].
+
+ [% ELSIF error == "zero_length_file" %]
+ [% title = "File Is Empty" %]
+ The file you are trying to attach is empty, does not exist, or you don't
+ have permission to read it.
+
+ [% ELSIF error == "illegal_user_id" %]
+ [% title = "Illegal User ID" %]
+ User ID '[% userid FILTER html %]' is not valid integer.
+
+ [% ELSIF error == "extern_id_exists" %]
+ [% title = "Account Already Exists" %]
+ There is already an account
+ [% IF existing_login_name %]
+ ([% existing_login_name FILTER html %])
+ [% END %]
+ with the External Login ID "[% extern_id FILTER html %]".
+
+ [% ELSE %]
+
+ [%# Try to find hooked error messages %]
+ [% error_message = Hook.process("errors") %]
+
+ [% IF not error_message %]
+ [% title = "Error string not found" %]
+ The user error string <code>[% error FILTER html %]</code> was not found.
+ Please send email to [% Param("maintainer") %] describing the steps taken
+ to obtain this message.
+ [% ELSE %]
+ [% error_message FILTER none %]
+ [% END %]
+ [% END %]
+[% END %]
+
+[%# We only want HTML error messages for ERROR_MODE_WEBPAGE %]
+[% USE Bugzilla %]
+[% IF Bugzilla.error_mode != constants.ERROR_MODE_WEBPAGE %]
+ [% IF Bugzilla.usage_mode == constants.USAGE_MODE_BROWSER %]
+ [% error_message FILTER none %]
+ [% ELSE %]
+ [% error_message FILTER txt %]
+ [% END %]
+ [% RETURN %]
+[% END %]
+
+[% UNLESS header_done %]
+ [% PROCESS global/header.html.tmpl %]
+[% END %]
+
+[% PROCESS global/docslinks.html.tmpl
+ docslinks = docslinks
+ admindocslinks = admindocslinks
+%]
+
+<table cellpadding="20">
+ <tr>
+ <td id="error_msg" class="throw_error">
+ [% error_message FILTER none %]
+ </td>
+ </tr>
+</table>
+
+<p>
+ Please press <b>Back</b> and try again.
+</p>
+
+[%# If a saved search fails, people want the ability to edit or delete it.
+ # This is the best way of getting information about that possible saved
+ # search from any error call location. %]
+
+[% namedcmd = Bugzilla.cgi.param("namedcmd") %]
+[% sharer_id = Bugzilla.cgi.param("sharer_id") %]
+[% IF namedcmd AND error != "missing_query"
+ AND error != "saved_search_used_by_whines"
+ AND !sharer_id %]
+ <p>
+ Alternatively, you can
+ <a href="buglist.cgi?cmdtype=dorem&amp;remaction=forget&amp;namedcmd=
+ [% namedcmd FILTER uri %]">forget</a>
+
+ [% FOREACH q = Bugzilla.user.queries %]
+ [% IF q.name == namedcmd %]
+ or <a href="query.cgi?[% q.url FILTER html %]">edit</a>
+ [% END %]
+ [% END %]
+
+ the saved search '[% namedcmd FILTER html %]'.
+ </p>
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
+
+[% BLOCK object_name %]
+ [% IF class == "Bugzilla::Attachment" %]
+ attachment
+ [% ELSIF class == "Bugzilla::User" %]
+ user
+ [% ELSIF class == "Bugzilla::Classification" %]
+ classification
+ [% ELSIF class == "Bugzilla::Product" %]
+ product
+ [% ELSIF class == "Bugzilla::Component" %]
+ component
+ [% ELSIF class == "Bugzilla::Version" %]
+ version
+ [% ELSIF class == "Bugzilla::Milestone" %]
+ milestone
+ [% ELSIF class == "Bugzilla::Status" %]
+ status
+ [% ELSIF class == "Bugzilla::Flag" %]
+ flag
+ [% ELSIF class == "Bugzilla::FlagType" %]
+ flagtype
+ [% ELSIF class == "Bugzilla::Field" %]
+ field
+ [% ELSIF class == "Bugzilla::Group" %]
+ group
+ [% ELSIF class == "Bugzilla::Keyword" %]
+ keyword
+ [% ELSIF class == "Bugzilla::Search::Recent" %]
+ recent search
+ [% ELSIF class == "Bugzilla::Search::Saved" %]
+ saved search
+ [% ELSIF ( matches = class.match('^Bugzilla::Field::Choice::(.+)') ) %]
+ [% SET field_name = matches.0 %]
+ [% field_descs.$field_name FILTER html %]
+ [% END %]
+ [% Hook.process('end_object_name', 'global/user-error.html.tmpl') %]
+[% END %]
diff --git a/template/en/default/global/user.html.tmpl b/template/en/default/global/user.html.tmpl
new file mode 100644
index 0000000..7050c6d
--- /dev/null
+++ b/template/en/default/global/user.html.tmpl
@@ -0,0 +1,26 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # who: A Bugzilla::User object that we are going to represent.
+ #%]
+
+<span class="vcard">
+ [% FILTER collapse %]
+ [% IF user.id %]
+ <a class="email" href="mailto:[% who.email FILTER html %]"
+ title="[% who.identity FILTER html %]">
+ [%- END -%]
+ [% IF who.name %]
+ <span class="fn">[% who.name FILTER html %]</span>
+ [% ELSE %]
+ [% who.login FILTER email FILTER html %]
+ [% END %]
+ [% '</a>' IF user.id %]
+ [% END %]
+</span>
diff --git a/template/en/default/global/userselect.html.tmpl b/template/en/default/global/userselect.html.tmpl
new file mode 100644
index 0000000..828c4bb
--- /dev/null
+++ b/template/en/default/global/userselect.html.tmpl
@@ -0,0 +1,99 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # name: mandatory; field name
+ # id: optional; field id
+ # value: optional; default field value/selection
+ # classes: optional; an array of classes to be added
+ # onchange: optional; onchange attribute value
+ # disabled: optional; if true, the field is disabled
+ # accesskey: optional, input only; accesskey attribute value
+ # size: optional, input only; size attribute value
+ # emptyok: optional, select only; if true, prepend menu option for "" to start of select
+ # hyphenok: optional, select only; if true, prepend menu option for "-" to start of select
+ # multiple: optional, do multiselect box, value is size (height) of box
+ # custom_userlist: optional, specify a limited list of users to use
+ # field_title: optional, extra information to display as a tooltip
+ #%]
+
+[% IF Param("usemenuforusers") %]
+<select name="[% name FILTER html %]"
+ [% IF id %] id="[% id FILTER html %]" [% END %]
+ [% IF classes %] class="[% classes.join(' ') FILTER html %]" [% END %]
+ [% IF onchange %] onchange="[% onchange FILTER html %]" [% END %]
+ [% IF disabled %] disabled="[% disabled FILTER html %]" [% END %]
+ [% IF accesskey %] accesskey="[% accesskey FILTER html %]" [% END %]
+ [% IF multiple %] multiple="multiple" size="[% multiple FILTER html %]" [% END %]
+ [% IF field_title %] title="[% field_title FILTER html %]" [% END %]
+>
+ [% IF emptyok %]
+ <option value=""></option>
+ [% END %]
+ [% IF hyphenok %]
+ <option value="-">-</option>
+ [% END %]
+
+ [% UNLESS custom_userlist %]
+ [% custom_userlist = user.get_userlist %]
+ [% END %]
+
+ [% SET selected = {} %]
+ [% IF value.defined %]
+ [% FOREACH selected_value IN value.split(', ') %]
+ [% SET selected.$selected_value = 1 %]
+ [% END %]
+ [% END %]
+
+ [% FOREACH tmpuser = custom_userlist %]
+ [% IF tmpuser.visible OR selected.${tmpuser.login} == 1 %]
+ <option value="[% tmpuser.login FILTER html %]"
+ [% IF selected.${tmpuser.login} == 1 %]
+ selected="selected"
+ [%# A user account appears only once. Remove it from the list, so that
+ # we know if there are some selected accounts which have not been listed. %]
+ [% selected.delete(tmpuser.login) %]
+ [% END %]
+ >[% tmpuser.identity FILTER html %]</option>
+ [% END %]
+ [% END %]
+
+ [%# If the list is not empty, this means some accounts have not been mentioned yet. %]
+ [% FOREACH selected_user = selected.keys %]
+ <option value="[% selected_user FILTER html %]" selected="selected">[% selected_user FILTER html %]</option>
+ [% END %]
+</select>
+[% ELSE %]
+ [% IF feature_enabled('jsonrpc') && Param('ajax_user_autocompletion') && id %]
+ <div id="[% id FILTER html %]_autocomplete"
+ [% IF classes %] class="[% classes.join(' ') FILTER html %]" [% END %]>
+ [% END %]
+ <input
+ name="[% name FILTER html %]"
+ value="[% value FILTER html %]"
+ [% IF classes %] class="[% classes.join(' ') FILTER html %]" [% END %]
+ [% IF onchange %] onchange="[% onchange FILTER html %]" [% END %]
+ [% IF disabled %] disabled="[% disabled FILTER html %]" [% END %]
+ [% IF accesskey %] accesskey="[% accesskey FILTER html %]" [% END %]
+ [% IF field_title %] title="[% field_title FILTER html %]" [% END %]
+ [% IF size %] size="[% size FILTER html %]" [% END %]
+ [% IF id %] id="[% id FILTER html %]" [% END %]
+ >
+ [% IF feature_enabled('jsonrpc') && Param('ajax_user_autocompletion') && id %]
+ <div id="[% id FILTER html %]_autocomplete_container"></div>
+ </div>
+ <script type="text/javascript">
+ if( typeof(YAHOO.bugzilla.userAutocomplete) !== 'undefined'
+ && YAHOO.bugzilla.userAutocomplete != null){
+ YAHOO.bugzilla.userAutocomplete.init( "[% id FILTER js %]",
+ "[% id FILTER js %]_autocomplete_container"
+ [% IF multiple %], true[% END%]);
+ }
+ </script>
+ [% END %]
+[% END %]
diff --git a/template/en/default/global/value-descs.js.tmpl b/template/en/default/global/value-descs.js.tmpl
new file mode 100644
index 0000000..7e79d10
--- /dev/null
+++ b/template/en/default/global/value-descs.js.tmpl
@@ -0,0 +1,21 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS "global/value-descs.none.tmpl" %]
+
+BUGZILLA.value_descs = {
+ [% FOREACH vd_field = value_descs.keys %]
+ [% vd_field FILTER js %]: {
+ [% FOREACH vd_value = value_descs.${vd_field}.keys %]
+ '[% vd_value FILTER js %]':
+ '[% value_descs.${vd_field}.${vd_value} FILTER js %]'
+ [%~ ',' UNLESS loop.last %]
+ [% END %]
+ }[% ',' UNLESS loop.last %]
+ [% END %]
+};
diff --git a/template/en/default/global/value-descs.none.tmpl b/template/en/default/global/value-descs.none.tmpl
new file mode 100644
index 0000000..a6aa814
--- /dev/null
+++ b/template/en/default/global/value-descs.none.tmpl
@@ -0,0 +1,24 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# You can use this hash to localize (translate) the values displayed
+ # for drop-down and multiple-select fields. Lines starting with "#"
+ # are comments.
+ #%]
+[% value_descs = {
+ "bug_status" => {
+ # "UNCONFIRMED" => "UNCO",
+ # "CONFIRMED" => "ITSABUG",
+ },
+
+ "resolution" => {
+ "" => "---",
+ # "FIXED" => "NO LONGER AN ISSUE",
+ # "WORKSFORME" => "NOTMYPROBLEM!",
+ },
+} %]
diff --git a/template/en/default/global/variables.none.tmpl b/template/en/default/global/variables.none.tmpl
new file mode 100644
index 0000000..9e411e3
--- /dev/null
+++ b/template/en/default/global/variables.none.tmpl
@@ -0,0 +1,33 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# This is a list of terms that may be changed to "brand" the Bugzilla
+ # instance (for example, referring to "bugs" as "issues".) When used, these
+ # strings are used in several different types of content, and are not
+ # protected with Template-Toolkit FILTERs. Consequently, no special
+ # characters are allowed.
+ #
+ # Remember to PROCESS rather than INCLUDE this template.
+ #%]
+
+[% terms = {
+ "bug" => "bug",
+ "Bug" => "Bug",
+ "abug" => "a bug",
+ "Abug" => "A bug",
+ "aBug" => "a Bug",
+ "ABug" => "A Bug",
+ "bugs" => "bugs",
+ "Bugs" => "Bugs",
+ "zeroSearchResults" => "Zarro Boogs found",
+ "Bugzilla" => "Bugzilla"
+ }
+%]
+
+[% USE Hook %]
+[% Hook.process("end") %]
diff --git a/template/en/default/index.html.tmpl b/template/en/default/index.html.tmpl
new file mode 100644
index 0000000..b47b912
--- /dev/null
+++ b/template/en/default/index.html.tmpl
@@ -0,0 +1,173 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # release: a hash containing data about new releases, if any.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "$terms.Bugzilla Main Page"
+ header = "Main Page"
+ header_addl_info = "version $constants.BUGZILLA_VERSION"
+ style_urls = [ 'skins/standard/index.css' ]
+%]
+
+
+<script type="text/javascript">
+<!--
+function onLoadActions() {
+ quicksearchHelpText('quicksearch_main', 'show');
+ if( window.external.AddSearchProvider ){
+ YAHOO.util.Dom.removeClass('quicksearch_plugin', 'bz_default_hidden');
+ }
+ document.getElementById('quicksearch_top').focus();
+}
+var quicksearch_message = "Enter [% terms.abug %] # or some search terms";
+
+function checkQuicksearch( form ) {
+ if (form.quicksearch.value == '' || form.quicksearch.value == quicksearch_message ) {
+ alert('Please enter one or more search terms first.');
+ return false;
+ }
+ return true;
+}
+
+function quicksearchHelpText(el_id, action){
+ var el = document.getElementById(el_id);
+ if ( action == "show") {
+ if( el.value == "" ) {
+ el.value = quicksearch_message
+ YAHOO.util.Dom.addClass(el, "quicksearch_help_text");
+ }
+ } else {
+ if( el.value == quicksearch_message ) {
+ el.value = "";
+ YAHOO.util.Dom.removeClass(el, "quicksearch_help_text");
+ }
+ }
+}
+YAHOO.util.Event.onDOMReady(onLoadActions);
+//-->
+</script>
+
+[% IF release %]
+ <div id="new_release">
+ [% IF release.data %]
+ [% IF release.deprecated %]
+ <p>[% terms.Bugzilla %] [%+ release.deprecated FILTER html %] is no longer
+ supported. You are highly encouraged to upgrade in order to keep your
+ system secure.</p>
+ [% END %]
+
+ <p>A new [% terms.Bugzilla %] version ([% release.data.latest_ver FILTER html %])
+ is available at
+ <a href="[% release.data.url FILTER html %]">[% release.data.url FILTER html %]</a>.<br>
+ Release date: [% release.data.date FILTER html %]</p>
+
+ <p class="notice">This message is only shown to logged in users with admin privs.
+ You can configure this notification from the
+ <a href="editparams.cgi?section=general#upgrade_notification_desc">Parameters</a> page.</p>
+ [% ELSIF release.error == "cannot_download" %]
+ <p>The remote file <a href="[% constants.REMOTE_FILE FILTER html %]">
+ [%~ constants.REMOTE_FILE FILTER html %]</a> cannot be downloaded
+ (reason: [% release.reason FILTER html %]).<br>
+ Either the remote server is temporarily unavailable, or your web server cannot access
+ the web. If you are behind a proxy, set the
+ <a href="editparams.cgi?section=advanced#proxy_url_desc">proxy_url</a> parameter correctly.</p>
+ [% ELSIF release.error == "no_write" %]
+ <p>The local XML file '[% constants.LOCAL_FILE FILTER html %]' cannot be created
+ (reason: [% release.reason FILTER html %]).<br>
+ Please make sure the web server can write into this directory.
+ [% ELSIF release.error == "no_update" %]
+ <p>The local XML file '[% constants.LOCAL_FILE FILTER html %]' cannot be updated.
+ Please make sure the web server can edit this file.</p>
+ [% ELSIF release.error == "no_access" %]
+ <p>The local XML file '[% constants.LOCAL_FILE FILTER html %]' cannot be read.
+ Please make sure this file has the correct rights set on it.</p>
+ [% ELSIF release.error == "corrupted" %]
+ <p>The local XML file '[% constants.LOCAL_FILE FILTER html %]' has an invalid XML format.
+ Please delete it and try accessing this page again.</p>
+ [% ELSIF release.error == "unknown_parameter" %]
+ <p>'[% Param("upgrade_notification") FILTER html %]' is not a valid notification
+ parameter. Please check this parameter in the
+ <a href="editparams.cgi?section=general#upgrade_notification_desc">Parameters</a> page.</p>
+ [% END %]
+ </div>
+[% END %]
+
+<div id="page-index">
+ <table>
+ <tr>
+ <td>
+ <h1 id="welcome"> Welcome to [% terms.Bugzilla %]</h1>
+ <div class="intro">[% Hook.process('intro') %]</div>
+
+ <div class="bz_common_actions">
+ <ul>
+ <li>
+ <a id="enter_bug" href="enter_bug.cgi"><span>File
+ [%= terms.aBug %]</span></a>
+ </li>
+ <li>
+ <a id="query" href="query.cgi"><span>Search</span></a>
+ </li>
+ <li>
+ <a id="account"
+ [% IF user.id %]
+ href="userprefs.cgi"><span>User Preferences</span></a>
+ [% ELSIF Param('createemailregexp')
+ && user.authorizer.user_can_create_account
+ %]
+ href="createaccount.cgi"><span>Open a New Account</span></a>
+ [% ELSE %]
+ href="?GoAheadAndLogIn=1"><span>Log In</span></a>
+ [% END %]
+ </li>
+ </ul>
+ </div>
+
+ <form id="quicksearchForm" name="quicksearchForm" action="buglist.cgi"
+ onsubmit="return checkQuicksearch(this);">
+ <div>
+ <input id="quicksearch_main" type="text" name="quicksearch"
+ title="Quick Search"
+ onfocus="quicksearchHelpText(this.id, 'hide');"
+ onblur="quicksearchHelpText(this.id, 'show');"
+ >
+ <input id="find" type="submit" value="Quick Search">
+ <ul class="additional_links" id="quicksearch_links">
+ <li>
+ <a href="page.cgi?id=quicksearch.html">Quick Search help</a>
+ </li>
+ <li class="bz_default_hidden" id="quicksearch_plugin">
+ |
+ <a href="javascript:window.external.AddSearchProvider('[% urlbase FILTER html %]search_plugin.cgi')">
+ Install the Quick Search plugin
+ </a>
+ </li>
+ </ul>
+ <ul class="additional_links">
+ <li>
+ <a href="[% docs_urlbase FILTER html %]using.html">
+ [%- terms.Bugzilla %] User's Guide</a>
+ </li>
+ <li>
+ |
+ <a href="page.cgi?id=release-notes.html">Release Notes</a>
+ </li>
+ [% Hook.process('additional_links') %]
+ </ul>
+ </div>
+ </form>
+ <div class="outro">[% Hook.process('outro') %]</div>
+ </td>
+ </tr>
+ </table>
+</div>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/list/change-columns.html.tmpl b/template/en/default/list/change-columns.html.tmpl
new file mode 100644
index 0000000..17d711e
--- /dev/null
+++ b/template/en/default/list/change-columns.html.tmpl
@@ -0,0 +1,131 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Change Columns"
+ javascript_urls = "js/change-columns.js"
+ onload = "initChangeColumns()"
+%]
+
+<p>
+ Select the columns you wish to appear in your [% terms.bug %] lists. Note that
+ this feature requires cookies to work.
+</p>
+
+[% field_descs.short_short_desc = "Summary (first 60 characters)" %]
+[% field_descs.short_desc = "Summary (Full)" %]
+[% field_descs.assigned_to_realname = "$field_descs.assigned_to Real Name" %]
+[% field_descs.reporter_realname = "$field_descs.reporter Real Name" %]
+[% field_descs.qa_contact_realname = "$field_descs.qa_contact Real Name" %]
+
+[%# Create a mapping of field descriptions to field names, so that
+ # the "Available Columns" list can be sorted alphabetically by
+ # field description.
+ #%]
+[% SET available_columns = {} %]
+[% FOREACH column = columns.keys %]
+ [% NEXT IF collist.contains(column) %]
+ [%# We lowecase the keys so that the sort happens case-insensitively. %]
+ [% SET column_desc = field_descs.$column || column FILTER lower %]
+ [% available_columns.$column_desc = column %]
+[% END %]
+
+<form name="changecolumns" action="colchange.cgi" onsubmit="change_submit();">
+ <input type="hidden" name="rememberedquery" value="[% buffer FILTER html %]">
+ <table>
+ <tr>
+ <th><div id="avail_header" class="bz_default_hidden">Available Columns</div></th>
+ <th></th>
+ <th colspan="2">Selected Columns</th>
+ </tr>
+ <tr>
+ <td>
+ <select name="available_columns" id="available_columns"
+ size="15" multiple="multiple" onchange="updateView();"
+ class="bz_default_hidden">
+ </select>
+ </td>
+ <td>
+ <button type="button" id="select_button" name="select"
+ class="bz_default_hidden arrow_button"
+ onclick="move_select()">&rarr;</button>
+ <br><br>
+ <button type="button" id="deselect_button" name="deselect"
+ class="bz_default_hidden arrow_button"
+ onclick="move_deselect()">&larr;</button>
+ </td>
+ <td>
+ <select name="selected_columns" id="selected_columns"
+ size="15" multiple="multiple" onchange="updateView();">
+ [% FOREACH column = collist %]
+ <option value="[% column FILTER html %]" selected="selected">
+ [% (field_descs.${column} || column) FILTER html %]
+ </option>
+ [% END %]
+ [% FOREACH key = available_columns.keys.sort %]
+ [% SET column = available_columns.$key %]
+ <option value="[% column FILTER html %]">
+ [%# Don't display the lower-cased column description,
+ # display the correct-case one. %]
+ [% (field_descs.$column || column) FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ </td>
+ <td>
+ <button type="button" id="up_button" name="up"
+ class="bz_default_hidden arrow_button"
+ onclick="move_up()">&uarr;</button>
+ <br><br>
+ <button type="button" id="down_button" name="down"
+ class="bz_default_hidden arrow_button"
+ onclick="move_down()">&darr;</button>
+ </td>
+ </tr>
+ </table>
+
+ <p>
+ <input id="nosplitheader" type="radio" name="splitheader" value="0"
+ [%+ "checked='checked'" IF NOT splitheader %]>
+ <label for="nosplitheader">
+ Normal headers (prettier)
+ </label>
+ <br>
+
+ <input id="splitheader" type="radio" name="splitheader" value="1"
+ [%+ "checked='checked'" IF splitheader %]>
+ <label for="splitheader">
+ Stagger headers (often makes list more compact)
+ </label>
+ </p>
+
+ [% IF saved_search %]
+ <p>
+ <input type="hidden" name="saved_search"
+ value="[% saved_search.id FILTER html%]" >
+ <input type="hidden" name="token"
+ value="[% issue_hash_token([saved_search.id, saved_search.name]) FILTER html %]">
+ <input type="checkbox" id="save_columns_for_search" checked="checked"
+ name="save_columns_for_search" value="1">
+ <label for="save_columns_for_search">Save this column list only
+ for search '[% saved_search.name FILTER html %]'</label>
+ </p>
+ [% ELSE %]
+ <input type="hidden" name="token"
+ value="[% issue_hash_token(['default-list']) FILTER html %]">
+ [% END %]
+
+ <p>
+ <input type="submit" id="change" value="Change Columns">
+ </p>
+
+ <input type="submit" id="resetit" name="resetit"
+ value="Reset to [% terms.Bugzilla %] default">
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/list/edit-multiple.html.tmpl b/template/en/default/list/edit-multiple.html.tmpl
new file mode 100644
index 0000000..465578a
--- /dev/null
+++ b/template/en/default/list/edit-multiple.html.tmpl
@@ -0,0 +1,435 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% dontchange = "--do_not_change--" %]
+<input type="hidden" name="dontchange" value="[% dontchange FILTER html %]">
+<input type="hidden" name="token" value="[% token FILTER html %]">
+
+<script type="text/javascript">
+ function SetCheckboxes(value) {
+ var elements = document.forms.changeform.getElementsByTagName('input'),
+ numelements = elements.length,
+ item, i;
+ for (i = 0; i < numelements; i++) {
+ item = elements[i];
+ if (item.type === 'checkbox' && item.name.match(/^id_/)) {
+ item.checked = value;
+ }
+ }
+ }
+ document.write(' <input type="button" name="uncheck_all" value="Uncheck All" onclick="SetCheckboxes(false);">');
+ document.write(' <input type="button" name="check_all" value="Check All" onclick="SetCheckboxes(true);">');
+</script>
+
+<hr>
+
+<p style="font-size:smaller">
+ To change multiple [% terms.bugs %]:</p>
+<ol style="font-size:smaller">
+ <li>Check the [% terms.bugs %] you want to change above.</li>
+ <li>Make your changes in the form fields below. If the change
+ you are making requires an explanation, include it in
+ the comments box.</li>
+ <li>Click the <em>Commit</em> button.</li>
+</ol>
+
+<table id="form">
+ <tr>
+
+ <th><label for="product">Product:</label></th>
+ <td>
+ [% PROCESS selectmenu menuname = "product"
+ menuitems = products
+ property = "name" %]
+ </td>
+
+ <th><label for="version">Version:</label></th>
+ <td>
+ [% PROCESS selectmenu menuname = "version"
+ menuitems = versions
+ property = "" %]
+ </td>
+
+ </tr>
+ <tr>
+
+ <th><label for="component">Component:</label></th>
+ <td>
+ [% PROCESS selectmenu menuname = "component"
+ menuitems = components %]
+ </td>
+
+ <th>
+ <label for="priority">
+ <a href="page.cgi?id=fields.html#priority">Priority</a>:
+ </label>
+ </th>
+ <td>
+ [% PROCESS selectmenu menuname = "priority"
+ menuitems = priorities %]
+ </td>
+
+ </tr>
+ <tr>
+
+ <th>
+ <label for="rep_platform">
+ <a href="page.cgi?id=fields.html#rep_platform">
+ [% field_descs.rep_platform FILTER html %]</a>:
+ </label>
+ </th>
+ <td>
+ [% PROCESS selectmenu menuname = "rep_platform"
+ menuitems = platforms %]
+ </td>
+
+ <th>
+ <label for="bug_severity">
+ <a href="page.cgi?id=fields.html#bug_severity">
+ [% field_descs.bug_severity FILTER html %]</a>:
+ </label>
+ </th>
+ <td>
+ [% PROCESS selectmenu menuname = "bug_severity"
+ menuitems = severities %]
+ </td>
+
+ </tr>
+
+ <tr>
+ <th>
+ <label for="op_sys">
+ <a href="page.cgi?id=fields.html#op_sys">[% field_descs.op_sys FILTER html %]</a>:
+ </label>
+ </th>
+ <td [% " colspan=\"3\"" IF !Param("usetargetmilestone") %]>
+ [% PROCESS selectmenu menuname = "op_sys"
+ menuitems = op_sys %]
+ </td>
+
+ [% IF Param("usetargetmilestone") %]
+ <th><label for="target_milestone">Target Milestone:</label></th>
+ <td>
+ [% PROCESS selectmenu menuname = "target_milestone"
+ menuitems = targetmilestones %]
+ </td>
+ [% END %]
+ </tr>
+
+ <tr>
+ <th><label for="bug_status">Status:</label></th>
+ <td colspan="3">[% PROCESS status_section %]</td>
+ </tr>
+ [% IF user.is_timetracker %]
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.estimated_time, editable = 1
+ %]
+ <td>
+ <input id="estimated_time"
+ name="estimated_time"
+ value="[% dontchange FILTER html %]"
+ size="6">
+ </td>
+ [% PROCESS bug/field.html.tmpl
+ field = bug_fields.deadline, value = dontchange
+ editable = 1, allow_dont_change = 1 %]
+ </tr>
+ <tr>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.remaining_time, editable = 1
+ %]
+ <td>
+ <input id="remaining_time"
+ name="remaining_time"
+ value="[% dontchange FILTER html %]"
+ size="6">
+ </td>
+ <th>&nbsp;</th>
+ <td>&nbsp;</td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <th><label for="assigned_to">Assignee:</label></th>
+ <td colspan="3">
+ [% INCLUDE global/userselect.html.tmpl
+ id => "assigned_to"
+ name => "assigned_to"
+ value => dontchange
+ size => 40
+ %]
+ <input type="checkbox" id="set_default_assignee" name="set_default_assignee" value="1">
+ <label for="set_default_assignee">Reset Assignee to default</label>
+ </td>
+ </tr>
+
+ [% IF Param("useqacontact") %]
+ <tr>
+ <th><label for="qa_contact">QA Contact:</label></th>
+ <td colspan="3">
+ [% INCLUDE global/userselect.html.tmpl
+ id => "qa_contact"
+ name => "qa_contact"
+ value => dontchange
+ size => 40
+ %]
+ <input type="checkbox" id="set_default_qa_contact" name="set_default_qa_contact" value="1">
+ <label for="set_default_qa_contact">Reset QA Contact to default</label>
+ </td>
+ </tr>
+ [% END %]
+
+ <tr>
+
+ <th><label for="masscc">CC List:</label></th>
+ <td colspan="3">
+ [% INCLUDE global/userselect.html.tmpl
+ id => "masscc"
+ name => "masscc"
+ value => ""
+ size => 40
+ multiple => 5
+ %]
+ <select name="ccaction">
+ <option value="add">Add these to the CC List</option>
+ <option value="remove">Remove these from the CC List</option>
+ </select>
+ </td>
+
+ </tr>
+
+ [% IF use_keywords %]
+ <tr>
+
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.keywords, editable = 1
+ desc_url = "describekeywords.cgi"
+ %]
+ <td colspan="3">
+ [% INCLUDE bug/field.html.tmpl
+ field = bug_fields.keywords, editable = 1, value = keywords
+ possible_values = all_keywords
+ no_tds = 1
+ %]
+ <select name="keywordaction">
+ <option value="add">Add these keywords</option>
+ <option value="remove">Delete these keywords</option>
+ <option value="set">Make the keywords be exactly this list</option>
+ </select>
+ </td>
+
+ </tr>
+ [% END %]
+
+ <tr>
+ <th>
+ <label for="dependson">
+ Depends On:
+ </label>
+ </th>
+ <td colspan="3">
+ <input id="dependson" name="dependson" size="40">
+ <select name="dependson_action">
+ <option value="add">Add these IDs</option>
+ <option value="remove">Delete these IDs</option>
+ </select>
+ </td>
+ </tr>
+
+ <tr>
+ <th>
+ <label for="blocked">
+ Blocks:
+ </label>
+ </th>
+ <td colspan="3">
+ <input id="blocked" name="blocked" size="40">
+ <select name="blocked_action">
+ <option value="add">Add these IDs</option>
+ <option value="remove">Delete these IDs</option>
+ </select>
+ </td>
+ </tr>
+
+ [% IF Param('usestatuswhiteboard') %]
+ <tr>
+ <td align="right">
+ <b>Status Whiteboard:</b>
+ </td>
+ <td colspan="7">
+ <input name="status_whiteboard"
+ value="[% dontchange FILTER html %]" size="60">
+ </td>
+ </tr>
+ [% END %]
+
+ [% USE Bugzilla %]
+ [%# Show all legal values and all fields, ignoring visibility controls. %]
+ [% bug = 0 %]
+ [% FOREACH field = Bugzilla.active_custom_fields %]
+ <tr>
+ [% PROCESS bug/field.html.tmpl value = dontchange
+ editable = 1
+ allow_dont_change = 1 %]
+ </tr>
+ [% END %]
+
+ [% Hook.process("after_custom_fields") %]
+
+</table>
+
+<b><label for="comment">Additional Comments:</label></b>
+[% IF user.is_insider %]
+ <input type="checkbox" name="comment_is_private" value="1"
+ id="newcommentprivacy"
+ onClick="updateCommentTagControl(this, 'comment')"/>
+ <label for="newcommentprivacy">
+ Make comment private (visible only to members of the
+ <strong>[% Param('insidergroup') FILTER html %]</strong> group)
+ </label>
+[% END %]
+<br>
+[% INCLUDE global/textarea.html.tmpl
+ name = 'comment'
+ id = 'comment'
+ minrows = 5
+ maxrows = 25
+ cols = constants.COMMENT_COLS
+%]<br>
+[% IF user.is_insider %]
+ <script>
+ updateCommentTagControl(document.getElementById('newcommentprivacy'), 'comment');
+ </script>
+[% END %]
+
+[% Hook.process('before_groups') %]
+
+[% IF groups.size > 0 %]
+
+ <script type="text/javascript">
+ function turn_off(myself, id) {
+ var other_checkbox = document.getElementById(id);
+ if (myself.checked && other_checkbox) {
+ other_checkbox.checked = false;
+ }
+ }
+ </script>
+
+ <b>Groups:</b><br>
+ <table border="1">
+ <tr>
+ <th>Remove<br>[% terms.bugs %]<br>from this<br>group</th>
+ <th>Add<br>[% terms.bugs %]<br>to this<br>group</th>
+ <th>Group Name:</th>
+ </tr>
+
+ [% FOREACH group = groups %]
+ <tr>
+ <td align="center">
+ <input type="checkbox" name="defined_groups"
+ id="defined_group_[% group.id %]"
+ value="[% group.name FILTER html %]"
+ onchange="turn_off(this, 'group_[% group.id %]')">
+ </td>
+ [% IF group.is_active %]
+ <td align="center">
+ <input type="checkbox" name="groups"
+ id="group_[% group.id FILTER html %]"
+ value="[% group.name FILTER html %]"
+ onchange="turn_off(this, 'defined_group_[% group.id %]')">
+ </td>
+ [% ELSE %]
+ <td>&nbsp;</td>
+ [% foundinactive = 1 %]
+ [% END %]
+
+ <td>
+ [% SET inactive = !group.is_active %]
+ [% group.description FILTER html_light FILTER inactive(inactive) %]
+ </td>
+
+ </tr>
+ [% END %]
+
+ </table>
+
+ [% IF foundinactive %]
+ <p style="font-size:smaller">(Note: [% terms.Bugs %] may not be added to [% FILTER inactive %]inactive
+ groups[% END %], only removed.)</p>
+ [% END %]
+
+[% END %]
+
+[%+ Hook.process('after_groups') %]
+
+<input type="submit" id="commit" value="Commit">
+
+[%############################################################################%]
+[%# Select Menu Block #%]
+[%############################################################################%]
+
+[% BLOCK selectmenu %]
+ <select id="[% menuname %]" name="[% menuname %]">
+ <option value="[% dontchange FILTER html %]" selected="selected">
+ [% dontchange FILTER html %]
+ </option>
+ [% FOREACH menuitem = menuitems %]
+ [% IF property %][% menuitem = menuitem.$property %][% END %]
+ <option value="[% menuitem FILTER html %]">[% display_value(menuname, menuitem) FILTER html %]</option>
+ [% END %]
+ </select>
+[% END %]
+
+[%############################################################################%]
+[%# Status Block #%]
+[%############################################################################%]
+
+[% BLOCK status_section %]
+ [% all_open_bugs = !current_bug_statuses.containsany(closedstates) %]
+ [% all_closed_bugs = !current_bug_statuses.containsany(openstates) %]
+ [% closed_status_array = [] %]
+
+ <select name="bug_status" id="bug_status">
+ <option value="[% dontchange FILTER html %]" selected="selected">[% dontchange FILTER html %]</option>
+
+ [% FOREACH bug_status = new_bug_statuses %]
+ <option value="[% bug_status.name FILTER html %]">
+ [% display_value("bug_status", bug_status.name) FILTER html %]
+ </option>
+ [% IF !bug_status.is_open %]
+ [% filtered_status = bug_status.name FILTER js %]
+ [% closed_status_array.push( filtered_status ) %]
+ [% END %]
+ [% END %]
+
+ [%# If all the bugs being changed are closed, allow the user to change their resolution. %]
+ [% IF all_closed_bugs %]
+ [% filtered_status = dontchange FILTER js %]
+ [% closed_status_array.push( filtered_status ) %]
+ [% END %]
+ </select>
+
+ <span id="resolution_settings">
+ <select id="resolution" name="resolution">
+ <option value="[% dontchange FILTER html %]" selected >[% dontchange FILTER html %]</option>
+ [% FOREACH r = resolutions %]
+ [% NEXT IF !r %]
+ [% NEXT IF r == "DUPLICATE" || r == "MOVED" %]
+ <option value="[% r FILTER html %]">[% display_value("resolution", r) FILTER html %]</option>
+ [% END %]
+ </select>
+ </span>
+
+ <script type="text/javascript">
+ var close_status_array = new Array("[% closed_status_array.join('", "') FILTER none %]");
+ YAHOO.util.Event.addListener('bug_status', "change", showHideStatusItems, '[% "is_duplicate" IF bug.dup_id %]');
+ YAHOO.util.Event.onDOMReady( showHideStatusItems );
+ </script>
+
+[% END %]
diff --git a/template/en/default/list/list-simple.html.tmpl b/template/en/default/list/list-simple.html.tmpl
new file mode 100644
index 0000000..24e2bcf
--- /dev/null
+++ b/template/en/default/list/list-simple.html.tmpl
@@ -0,0 +1,32 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # title: string. The title for this page. (optional)
+ #%]
+
+[% DEFAULT title = "$terms.Bug List" %]
+
+<html>
+
+ <head>
+ <title>[% title FILTER html %]</title>
+ <base href="[% urlbase FILTER html %]">
+ <link href="[% 'skins/standard/buglist.css' FILTER mtime %]"
+ rel="stylesheet" type="text/css">
+ </head>
+
+ <body>
+ [% IF bugs.size == 0 %]
+ <h3>[% terms.zeroSearchResults %].</h3>
+ [% ELSE %]
+ [% PROCESS list/table.html.tmpl %]
+ [% END %]
+ </body>
+
+</html>
diff --git a/template/en/default/list/list.atom.tmpl b/template/en/default/list/list.atom.tmpl
new file mode 100644
index 0000000..fddbbd7
--- /dev/null
+++ b/template/en/default/list/list.atom.tmpl
@@ -0,0 +1,82 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% DEFAULT title = "$terms.Bugzilla $terms.Bugs" %]
+
+<?xml version="1.0"[% IF Param('utf8') %] encoding="UTF-8"[% END %]?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title>[% title FILTER xml %]</title>
+ <link rel="alternate" type="text/html"
+ href="[% urlbase FILTER html %]buglist.cgi?
+ [%- urlquerypart.replace('ctype=atom[&]?','') FILTER xml %]"/>
+ <link rel="self" type="application/atom+xml"
+ href="[% urlbase FILTER html %]buglist.cgi?
+ [%- urlquerypart FILTER xml %]"/>
+ <updated>[% bugs.sort('changedtime').last.changedtime FILTER time("%Y-%m-%dT%H:%M:%SZ", "UTC")
+ FILTER xml %]</updated>
+ <id>[% urlbase FILTER html %]buglist.cgi?[% urlquerypart FILTER xml %]</id>
+
+ [% FOREACH bug = bugs %]
+ <entry>
+ <title>[% "@" IF bug.secure_mode %][[% terms.Bug %] [%+ bug.bug_id FILTER xml %]] [% bug.short_desc FILTER xml %]</title>
+ <link rel="alternate" type="text/html"
+ href="[% urlbase FILTER html %]show_bug.cgi?id=
+ [%- bug.bug_id FILTER xml %]"/>
+ <id>[% urlbase FILTER xml %]show_bug.cgi?id=[% bug.bug_id FILTER xml %]</id>
+ <author>
+ <name>[% bug.reporter_realname ? bug.reporter_realname : bug.reporter FILTER xml %]</name>
+ </author>
+ <updated>[% bug.changedtime FILTER time("%Y-%m-%dT%H:%M:%SZ", "UTC") FILTER xml %]</updated>
+ <summary type="html">
+ [%# Filter out the entire block, so that we don't need to escape the html code out %]
+ [% FILTER xml %]
+ <table>
+ <tr>
+ <th>Field</th><th>Value</th>
+ </tr><tr class="bz_feed_product">
+ <td>[% columns.product.title FILTER html %]</td>
+ <td>[% bug.product FILTER html %]</td>
+ </tr><tr class="bz_feed_component">
+ <td>[% columns.component.title FILTER html %]</td>
+ <td>[% bug.component FILTER html %]</td>
+ </tr><tr class="bz_feed_assignee">
+ <td>[% columns.assigned_to_realname.title FILTER html %]</td>
+ <td>[% bug.assigned_to_realname ? bug.assigned_to_realname : bug.assigned_to FILTER html %]</td>
+ </tr><tr class="bz_feed_reporter">
+ <td>[% columns.reporter_realname.title FILTER html %]</td>
+ <td>[% bug.reporter_realname ? bug.reporter_realname : bug.reporter FILTER html %]</td>
+ </tr><tr class="bz_feed_bug_status">
+ <td>[% columns.bug_status.title FILTER html %]</td>
+ <td>[% display_value("bug_status", bug.bug_status) FILTER html %]</td>
+ </tr><tr class="bz_feed_resolution">
+ <td>[% columns.resolution.title FILTER html %] </td>
+ <td>[% display_value("resolution", bug.resolution) FILTER html %]</td>
+ </tr><tr class="bz_feed_priority">
+ <td>[% columns.priority.title FILTER html %]</td>
+ <td>[% display_value("priority", bug.priority) FILTER html %]</td>
+ </tr><tr class="bz_feed_severity">
+ <td>[% columns.bug_severity.title FILTER html %] </td>
+ <td>[% display_value("bug_severity", bug.bug_severity) FILTER html %]</td>
+ [% IF Param("usetargetmilestone") %]
+ </tr><tr class="bz_feed_target_milestone">
+ <td>[% columns.target_milestone.title FILTER html %]</td>
+ <td>[% bug.target_milestone FILTER html %]</td>
+ [% END %]
+ </tr><tr class="bz_feed_creation_date">
+ <td>[% columns.opendate.title FILTER html %]</td>
+ <td>[% bug.opendate FILTER html %]</td>
+ </tr><tr class="bz_feed_changed_date">
+ <td>[% columns.changeddate.title FILTER html %]</td>
+ <td>[% bug.changeddate FILTER html -%]</td>
+ </tr>
+ </table>
+ [% END %]
+ </summary>
+ </entry>
+ [% END %]
+</feed>
diff --git a/template/en/default/list/list.csv.tmpl b/template/en/default/list/list.csv.tmpl
new file mode 100644
index 0000000..31c5d8d
--- /dev/null
+++ b/template/en/default/list/list.csv.tmpl
@@ -0,0 +1,38 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% colsepchar = user.settings.csv_colsepchar.value %]
+
+[% IF human %]
+ [% field_descs.bug_id FILTER csv %]
+ [% FOREACH column = displaycolumns %]
+ [% colsepchar %][% field_descs.$column FILTER csv %]
+ [% END %]
+[% ELSE %]
+ bug_id
+ [% FOREACH column = displaycolumns %]
+ [% colsepchar %][% column FILTER csv %]
+ [% END %]
+[% END %]
+
+[% FOREACH bug = bugs %]
+ [% bug.bug_id %]
+ [% FOREACH column = displaycolumns %]
+ [% colsepchar %]
+ [% IF column == "opendate" OR column == "changeddate" %]
+ [% rawcolumn = column.replace("date", "time") %]
+ [% bug.$column = bug.$rawcolumn FILTER time("%Y-%m-%d %H:%M:%S") %]
+ [% ELSIF column == 'bug_status' %]
+ [% bug.$column = display_value("bug_status", bug.$column) %]
+ [% ELSIF column == 'resolution' %]
+ [%- bug.$column = display_value("resolution", bug.$column) %]
+ [% END %]
+ [% bug.$column FILTER csv %]
+ [% END %]
+
+[% END %]
diff --git a/template/en/default/list/list.html.tmpl b/template/en/default/list/list.html.tmpl
new file mode 100644
index 0000000..e179a90
--- /dev/null
+++ b/template/en/default/list/list.html.tmpl
@@ -0,0 +1,342 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # searchtype: string. Type of search - either "series", "saved" or undef.
+ # ...
+ # defaultsavename: string. The default name for saving the query.
+ #%]
+
+[%############################################################################%]
+[%# Template Initialization #%]
+[%############################################################################%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+[% unfiltered_title = "$terms.Bug List" %]
+[% IF searchname || defaultsavename %]
+ [% unfiltered_title = unfiltered_title _ ": " _ (searchname OR defaultsavename) %]
+[% END %]
+[% title = unfiltered_title FILTER html %]
+
+[% qorder = order FILTER uri IF order %]
+
+[% javascript = BLOCK %]
+ [% IF quicksearch %]
+ [% new_param = BLOCK ~%]
+ quicksearch=[% quicksearch FILTER uri %]
+ [%~ IF cgi.param('list_id') ~%]
+ &list_id=[% cgi.param('list_id') FILTER uri %]
+ [%~ END %]
+ [% END %]
+ [% ELSIF cgi.param('token') != '' %]
+ [% new_param = cgi.canonicalise_query('token', 'cmdtype', 'remtype') %]
+ [% ELSE %]
+ [% new_param = cgi.canonicalise_query %]
+ [% END %]
+
+ [% IF new_param.length + 12 < constants.CGI_URI_LIMIT %]
+ if (history && history.replaceState) {
+ history.replaceState(null, "[% unfiltered_title FILTER js %]",
+ "buglist.cgi?[% new_param FILTER js %]");
+ document.title = "[% unfiltered_title FILTER js %]";
+ }
+ [% END %]
+ [% javascript FILTER none %]
+[% END %]
+
+[%############################################################################%]
+[%# Page Header #%]
+[%############################################################################%]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ style = style
+ atomlink = "buglist.cgi?$urlquerypart&title=$title&ctype=atom"
+ yui = [ 'autocomplete', 'calendar' ]
+ javascript_urls = [ "js/util.js", "js/field.js", "js/TUI.js" ]
+ style_urls = [ "skins/standard/buglist.css" ]
+ doc_section = "query.html#list"
+%]
+
+<div class="bz_query_head">
+ <span class="bz_query_timestamp">
+ [% currenttime FILTER time('%a %b %e %Y %T %Z') FILTER html %]<br>
+ </span>
+
+ [% IF debug %]
+ <div class="bz_query_debug">
+ <p>Total execution time: [% query_time FILTER html %] seconds</p>
+ [% FOREACH query = queries %]
+ <p>[% query.sql FILTER html %]</p>
+ <p>Execution time: [% query.time FILTER html %] seconds</p>
+ [% IF query.explain %]
+ <pre>[% query.explain FILTER html %]</pre>
+ [% END %]
+ [% END %]
+ </div>
+ [% END %]
+
+ [% IF user.settings.display_quips.value == 'on' %]
+ [% DEFAULT quip = "$terms.Bugzilla would like to put a random quip here, but no one has entered any." %]
+ <span class="bz_quip">
+ <a href="quips.cgi"><em>[% quip FILTER html %]</em></a>
+ </span>
+ [% END %]
+
+</div>
+
+[% IF toolong %]
+ <h2 class="bz_smallminded">
+ This list is too long for [% terms.Bugzilla %]'s little mind; the
+ Next/Prev/First/Last buttons won't appear on individual [% terms.bugs %].
+ </h2>
+[% END %]
+
+[% SET shown_types = [
+ 'notequals', 'regexp', 'notregexp', 'lessthan', 'lessthaneq',
+ 'greaterthan', 'greaterthaneq', 'changedbefore', 'changedafter',
+ 'changedfrom', 'changedto', 'changedby', 'notsubstring', 'nowords',
+ 'nowordssubstr', 'notmatches',
+] %]
+<a id="search_description_controller" class="bz_default_hidden"
+ href="javascript:TUI_toggle_class('search_description')">Hide Search Description</a>
+[%# Show the link if the browser supports JS %]
+<script type="text/javascript">
+ TUI_alternates['search_description'] = 'Show Search Description';
+ YAHOO.util.Dom.removeClass('search_description_controller',
+ 'bz_default_hidden');
+</script>
+
+<ul class="search_description">
+[% FOREACH desc_item = search_description %]
+ <li>
+ <strong>[% field_descs.${desc_item.field} FILTER html %]:</strong>
+ [% IF shown_types.contains(desc_item.type) || debug %]
+ ([% search_descs.${desc_item.type} FILTER html %])
+ [% END %]
+ [% FOREACH val IN desc_item.value.split(',') %]
+ [%+ display_value(desc_item.field, val) FILTER html %][% ',' UNLESS loop.last %]
+ [% END %]
+ [% IF debug %]
+ (<code>[% desc_item.term FILTER html %]</code>)
+ [% END %]
+ </li>
+[% END %]
+</ul>
+
+<hr>
+
+[%############################################################################%]
+[%# Preceding Status Line #%]
+[%############################################################################%]
+
+[% IF bugs.size > 9 %]
+ [% PROCESS num_results %]
+[% END %]
+
+[%############################################################################%]
+[%# Start of Change Form #%]
+[%############################################################################%]
+
+[% IF dotweak %]
+ <form name="changeform" method="post" action="process_bug.cgi">
+[% END %]
+
+[%############################################################################%]
+[%# Bug Table #%]
+[%############################################################################%]
+
+[% PROCESS list/table.html.tmpl %]
+
+[%############################################################################%]
+[%# Succeeding Status Line #%]
+[%############################################################################%]
+
+[% PROCESS num_results %]
+
+[% IF bugs.size == 0 %]
+ <ul class="zero_result_links">
+ <li>[% PROCESS enter_bug_link %]</li>
+ [% IF one_product.defined %]
+ <li><a href="enter_bug.cgi">File a new [% terms.bug %] in a
+ different product</a></li>
+ [% END %]
+ <li><a href="[% PROCESS edit_search_url %]">Edit this search</a></li>
+ <li><a href="query.cgi">Start a new search</a></li>
+ </ul>
+[% END %]
+
+<br>
+
+[%############################################################################%]
+[%# Rest of Change Form #%]
+[%############################################################################%]
+
+[% IF dotweak %]
+ [% PROCESS "list/edit-multiple.html.tmpl" %]
+ </form>
+ <hr>
+[% END %]
+
+[%############################################################################%]
+[%# Navigation Bar #%]
+[%############################################################################%]
+
+<table>
+ <tr>
+ [% IF bugs.size > 0 %]
+ <td valign="middle" class="bz_query_buttons">
+ <form method="post" action="show_bug.cgi">
+ [% id = buglist.join(",") %]
+ <input type="hidden" name="id" value="[% id FILTER html %]">
+ <input type="hidden" name="format" value="multiple">
+ <input type="submit" id="long_format" value="Long Format">
+ </form>
+ <form method="post" action="show_bug.cgi">
+ <input type="hidden" name="ctype" value="xml">
+ [% FOREACH id = buglist %]
+ <input type="hidden" name="id" value="[% id FILTER html %]">
+ [% END %]
+ <input type="hidden" name="excludefield" value="attachmentdata">
+ <input type="submit" value="XML" id="xml">
+ </form>
+
+ [% IF user.is_timetracker %]
+ <form method="post" action="summarize_time.cgi">
+ <input type="hidden" name="id" value="[% buglist_joined FILTER html %]">
+ <input type="submit" id="timesummary" value="Time Summary">
+ </form>
+ [% IF time_summary_limited %]
+ <small>
+ Time Summary will only include the [% terms.bugs %] shown above. In order to
+ to see a time summary for all [% terms.bugs %] found by the search, you can
+ <a href="buglist.cgi?[% urlquerypart FILTER html %]
+ [%- "&order=$qorder" FILTER html IF order %]&limit=0">
+ Show all search results</a>.</small>
+ [% END %]
+ [% END %]
+ </td>
+
+ <td>&nbsp;</td>
+
+ <td valign="middle" class="bz_query_links">
+ <a href="buglist.cgi?
+ [% urlquerypart FILTER html %]&amp;ctype=csv&amp;human=1">CSV</a> |
+ <a href="buglist.cgi?
+ [% urlquerypart FILTER html %]&amp;title=
+ [%- title FILTER html %]&amp;ctype=atom">Feed</a> |
+ <a href="buglist.cgi?
+ [% urlquerypart FILTER html %]&amp;ctype=ics">iCalendar</a> |
+ <a href="colchange.cgi?
+ [% urlquerypart FILTER html %]&amp;query_based_on=
+ [% defaultsavename OR searchname FILTER uri %]">Change&nbsp;Columns</a> |
+
+ [% IF bugs.size > 1 && caneditbugs && !dotweak %]
+ <a href="buglist.cgi?[% urlquerypart FILTER html %]
+ [%- "&order=$qorder" FILTER html IF order %]&amp;tweak=1"
+ >Change&nbsp;Several&nbsp;[% terms.Bugs %]&nbsp;at&nbsp;Once</a>
+ |
+ [% END %]
+
+ [% IF bugowners && user.id %]
+ <a href="mailto:
+ [% bugowners FILTER html %]">Send&nbsp;Mail&nbsp;to&nbsp;[% terms.Bug %]&nbsp;Assignees</a> |
+ [% END %]
+
+ [%# Links to more things users can do with this bug list. %]
+ [% Hook.process("links") %]
+ </td>
+ [% END %]
+
+ <td valign="middle" class="bz_query_edit">
+ <a href="[% PROCESS edit_search_url %]">Edit&nbsp;Search</a>
+ </td>
+
+ [% IF searchtype == "saved" %]
+ <td valign="middle" nowrap="nowrap" class="bz_query_forget">
+ |
+ <a href="buglist.cgi?cmdtype=dorem&amp;remaction=forget&amp;namedcmd=
+ [% searchname FILTER uri %]&amp;token=
+ [% issue_hash_token([search_id, searchname]) FILTER uri %]">
+ Forget&nbsp;Search&nbsp;'[% searchname FILTER html %]'</a>
+ </td>
+ [% ELSE %]
+ <td>&nbsp;</td>
+
+ <td valign="middle" class="bz_query_remember">
+ <form method="get" action="buglist.cgi">
+ <input type="submit" id="remember" value="Remember search"> as
+ <input type="hidden" name="newquery"
+ value="[% urlquerypart FILTER html %][% "&order=$qorder" FILTER html IF order %]">
+ <input type="hidden" name="cmdtype" value="doit">
+ <input type="hidden" name="remtype" value="asnamed">
+ <input type="hidden" name="token" value="[% issue_hash_token(['savedsearch']) FILTER html %]">
+ <input type="text" id="save_newqueryname" name="newqueryname" size="20"
+ title="New query name" value="[% defaultsavename FILTER html %]">
+ </form>
+ </td>
+ [% END %]
+ </tr>
+</table>
+
+[% IF one_product.defined && bugs.size %]
+ <p class="bz_query_single_product">
+ [% PROCESS enter_bug_link %]
+ </p>
+[% END %]
+
+[%############################################################################%]
+[%# Page Footer #%]
+[%############################################################################%]
+
+[% PROCESS global/footer.html.tmpl %]
+
+[%##########%]
+[%# Blocks #%]
+[%##########%]
+
+[% BLOCK edit_search_url %]
+ [% editqueryname = searchname OR defaultsavename OR '' %]
+ query.cgi?[% urlquerypart FILTER html %]
+ [%- IF editqueryname != '' %]&amp;known_name=
+ [%- editqueryname FILTER uri %]
+ [% END %]
+[% END %]
+
+[% BLOCK enter_bug_link %]
+ <a href="enter_bug.cgi
+ [%- IF one_product.defined %]?product=
+ [%- one_product.name FILTER uri %][% END %]">File
+ a new [% terms.bug %]
+ [% IF one_product.defined %]
+ in the "[% one_product.name FILTER html %]" product
+ [% END %]</a>
+[% END %]
+
+[% BLOCK num_results %]
+ <span class="bz_result_count">
+ [% IF bugs.size == 0 %]
+ <span class="zero_results">[% terms.zeroSearchResults %].</span>
+ [% ELSIF default_limited AND bugs.size >= Param('default_search_limit') %]
+ This result was limited to [% Param('default_search_limit') FILTER html %]
+ [%+ terms.bugs %].
+ <a href="buglist.cgi?[% urlquerypart FILTER html %]
+ [%- "&order=$qorder" FILTER html IF order %]&limit=0">See
+ all search results for this query</a>.
+ [% time_summary_limited = 1 %]
+ [% ELSIF bugs.size == 1 %]
+ One [% terms.bug %] found.
+ [% ELSE %]
+ [% bugs.size %] [%+ terms.bugs %] found.
+ [% END %]
+ </span>
+[% END %]
diff --git a/template/en/default/list/list.ics.tmpl b/template/en/default/list/list.ics.tmpl
new file mode 100644
index 0000000..4295b46
--- /dev/null
+++ b/template/en/default/list/list.ics.tmpl
@@ -0,0 +1,90 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+[%+ PROCESS ics_prodid +%]
+VERSION:2.0
+[% FOREACH bug = bugs %]
+BEGIN:VTODO
+[%+ PROCESS ics_dtstart +%]
+[%+ PROCESS ics_summary +%]
+[%+ PROCESS ics_uid base_url=urlbase bug_id=bug.bug_id +%]
+[%+ PROCESS ics_url base_url=urlbase bug_id=bug.bug_id +%]
+[%+ PROCESS ics_status bug_status = bug.bug_status +%]
+[%+ PROCESS ics_dtstamp +%]
+[%+ ics_priorities.${bug.priority} FILTER ics('PRIORITY') +%]
+[% IF bug.changeddate %]
+[%+ bug.changedtime FILTER time("%Y%m%dT%H%M%SZ", "UTC") FILTER ics('LAST-MODIFIED') +%]
+[% END %]
+[% IF bug.percentage_complete %]
+[%+ bug.percentage_complete FILTER format('%d') FILTER ics('PERCENT-COMPLETE') +%]
+[% END %]
+[% IF bug.product %]
+[%+ bug.product FILTER ics('X-BUGZILLA-PRODUCT') +%]
+[% END %]
+[% IF bug.component %]
+[%+ bug.component FILTER ics('X-BUGZILLA-COMPONENT') +%]
+[% END %]
+[% IF bug.version %]
+[%+ bug.version FILTER ics('X-BUGZILLA-VERSION') +%]
+[% END %]
+[% IF bug.keywords %]
+[%+ bug.keywords FILTER ics('X-BUGZILLA-KEYWORDS') +%]
+[% END %]
+END:VTODO
+[% END %]
+END:VCALENDAR
+
+[% BLOCK ics_prodid %]
+ [% "-//Mozilla/Bugzilla $constants.BUGZILLA_VERSION//EN" FILTER ics('PRODID') %]
+[% END %]
+
+[% BLOCK ics_uid %]
+ [% "${bug_id}@${base_url}" FILTER uri FILTER ics('UID') %]
+[% END %]
+
+[% BLOCK ics_url %]
+ [% "${base_url}show_bug.cgi?id=${bug_id}" FILTER uri FILTER ics('URL;VALUE=URI') %]
+[% END %]
+
+[% BLOCK ics_dtstart %]
+ [% bug.opentime FILTER time("%Y%m%dT%H%M%SZ", "UTC") FILTER ics('DTSTART') %]
+[% END %]
+
+[% BLOCK ics_dtstamp %]
+ [% currenttime FILTER time("%Y%m%dT%H%M%SZ", "UTC") FILTER ics('DTSTAMP') %]
+[% END %]
+
+[% BLOCK ics_status %]
+ [% status = "" %]
+ [% FOREACH state = closedstates %]
+ [% IF bug_status == state %]
+ [% status = 'COMPLETED' %]
+ [% LAST %]
+ [% END %]
+ [% END %]
+ [% IF NOT status %]
+ [% IF bug_status == 'IN_PROGRESS' || bug_status == 'ASSIGNED' %]
+ [% status = 'IN-PROGRESS' %]
+ [% ELSE %]
+ [% status = 'NEEDS-ACTION' %]
+ [% END %]
+ [% END %]
+ [% status FILTER ics('STATUS') %]
+[% END %]
+
+[% BLOCK ics_summary %]
+ [% IF bug.short_desc %]
+ [% summary = bug.short_desc %]
+ [% ELSIF bug.short_short_desc %]
+ [% summary = bug.short_short_desc %]
+ [% ELSE %]
+ [% summary = "$terms.Bug $bug.bug_id" %]
+ [% END %]
+ [% summary FILTER ics('SUMMARY') %]
+[% END %]
diff --git a/template/en/default/list/list.rdf.tmpl b/template/en/default/list/list.rdf.tmpl
new file mode 100644
index 0000000..00eca0e
--- /dev/null
+++ b/template/en/default/list/list.rdf.tmpl
@@ -0,0 +1,44 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+<?xml version="1.0"[% IF Param('utf8') %] encoding="UTF-8"[% END %]?>
+<!-- [% template_version %] -->
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:bz="http://www.bugzilla.org/rdf#"
+ xmlns:nc="http://home.netscape.com/NC-rdf#">
+
+<bz:result rdf:about="[% urlbase FILTER xml %]buglist.cgi?[% urlquerypart FILTER html %]">
+ <bz:installation rdf:resource="[% urlbase FILTER xml %]" />
+ <bz:query_timestamp>[% currenttime FILTER time('%Y-%m-%d %T %Z') FILTER html %]</bz:query_timestamp>
+ <bz:bugs>
+ <Seq>
+ [% FOREACH bug = bugs %]
+ <li>
+
+ <bz:bug rdf:about="[% urlbase FILTER xml %]show_bug.cgi?id=[% bug.bug_id %]">
+
+ <bz:id nc:parseType="Integer">[% bug.bug_id %]</bz:id>
+
+ [% FOREACH column = displaycolumns %]
+ <bz:[% column %]>[% bug.$column FILTER html %]</bz:[% column %]>
+ [% END %]
+
+ </bz:bug>
+
+ </li>
+
+ [% END %]
+
+ </Seq>
+
+ </bz:bugs>
+
+</bz:result>
+
+</RDF>
diff --git a/template/en/default/list/quips.html.tmpl b/template/en/default/list/quips.html.tmpl
new file mode 100644
index 0000000..31e766a
--- /dev/null
+++ b/template/en/default/list/quips.html.tmpl
@@ -0,0 +1,159 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # added_quip: string. Defined if the CGI added a quip data before
+ # displaying anything; if defined, its value is that quip.
+ # show_quips: boolean. True if we are showing the entire quip list.
+ # quips: list of strings. Defined if and only if show_quips is true.
+ # List of all quips.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "$terms.Bugzilla Quip System"
+ header = "Add your own clever headline"
+ %]
+
+[% IF added_quip %]
+ <p>
+ <font color="red">
+ Your quip '<tt>[% added_quip FILTER html %]</tt>' has been added.
+ [% IF Param("quip_list_entry_control") == "moderated" AND !user.in_group('bz_quip_moderators') %]
+ It will be used as soon as it gets approved.
+ [% END %]
+ </font>
+ </p>
+[% END %]
+
+[% IF deleted_quip %]
+ <p>
+ <font color="red">
+ The quip '<tt>[% deleted_quip FILTER html %]</tt>' has been deleted.
+ </font>
+ </p>
+[% END %]
+
+[% IF approved or unapproved %]
+ <p>[% approved.size %] quips approved and [% unapproved.size %] quips unapproved</p>
+[% END %]
+
+
+<p>
+ [% terms.Bugzilla %] will pick a random quip for the headline on each
+ [% terms.bug %] list.
+</p>
+
+[% IF Param("quip_list_entry_control") != "closed" %]
+ <p>
+ You can extend the quip list. Type in something clever or funny or boring
+ (but not obscene or offensive, please) and bonk on the button.
+ [% IF Param("quip_list_entry_control") == "moderated" AND !user.in_group('bz_quip_moderators') %]
+ Note that your quip has to be approved before it is used.
+ [% END %]
+ </p>
+
+ <form method="post" action="quips.cgi">
+ <input type="hidden" name="action" value="add">
+ <input type="hidden" name="token"
+ value="[% issue_hash_token(['create-quips']) FILTER html %]">
+ <input size="80" name="quip" maxlength="512">
+ <p>
+ <input type="submit" id="add" value="Add This Quip">
+ </p>
+ </form>
+[% ELSE %]
+ <p>No new entries may be submitted at this time.
+ </p>
+[% END %]
+
+[% IF show_quips %]
+ [% IF !user.in_group('bz_quip_moderators') %]
+ <h2>
+ Existing quips:
+ </h2>
+ <ul>
+ [% FOREACH quipid = quipids %]
+ [% NEXT IF NOT quips.$quipid.approved %]
+ <li>[% quips.$quipid.quip FILTER html %]</li>
+ [% END %]
+ </ul>
+ [% ELSE %]
+ <h2>Edit existing quips:</h2>
+ <p>
+ <strong>Note:</strong> Only approved quips will be shown.
+ If the parameter 'quip_list_entry_control' is set to <q>open</q>,
+ entered quips are automatically approved.
+ </p>
+ <form name="editform" method="post" action="quips.cgi">
+ <input type="hidden" name="action" value="approve">
+ <input type="hidden" name="token"
+ value="[% issue_hash_token(['approve-quips']) FILTER html %]">
+ <table border="1">
+ <thead><tr>
+ <th>Quip</th>
+ <th>Author</th>
+ <th>Action</th>
+ <th>Approved</th>
+ </tr></thead><tbody>
+ [% FOREACH quipid = quipids %]
+ <tr>
+ <td>[% quips.$quipid.quip FILTER html %]</td>
+ <td>
+ [% userid = quips.$quipid.userid %]
+ [% users.$userid FILTER html %]
+ [% "Unknown" IF NOT users.$userid %]
+ </td>
+ <td>
+ <a href="quips.cgi?action=delete&amp;quipid=[% quipid FILTER uri %]&amp;token=
+ [%- issue_hash_token(['quips', quipid]) FILTER uri %]">
+ Delete
+ </a>
+ </td>
+ <td>
+ <input type="hidden" name="defined_quipid_[% quipid FILTER html %]"
+ id="defined_quipid_[% quipid FILTER html %]"
+ value="1">
+ <input type="checkbox" name="quipid_[% quipid FILTER html %]"
+ id="quipid_[% quipid FILTER html %]"
+ [%- ' checked="checked"' IF quips.$quipid.approved %]>
+ </td>
+ </tr>
+ [% END %]
+ </tbody>
+ </table>
+ <script type="text/javascript"><!--
+ var numelements = document.forms.editform.elements.length;
+ function SetCheckboxes(value) {
+ var item;
+ for (var i=0 ; i<numelements ; i++) {
+ item = document.forms.editform.elements[i];
+ item.checked = value;
+ }
+ }
+ document.write(' <input type="button" name="uncheck_all" '
+ +'value="Uncheck All" onclick="SetCheckboxes(false);">');
+ document.write(' <input type="button" name="check_all" '
+ +'value="Check All" onclick="SetCheckboxes(true);">');
+ //--></script>
+
+ <input type="submit" id="update" value="Save Changes">
+ </form>
+ <br>
+ [% END %]
+[% ELSE %]
+ <p>
+ Those who like their wisdom in large doses can
+ <a href="quips.cgi?action=show">view
+ [% IF user.in_group('bz_quip_moderators') %]
+ and edit
+ [% END %]
+ the whole quip list</a>.
+ </p>
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/list/server-push.html.tmpl b/template/en/default/list/server-push.html.tmpl
new file mode 100644
index 0000000..c4a3a84
--- /dev/null
+++ b/template/en/default/list/server-push.html.tmpl
@@ -0,0 +1,30 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # debug: boolean. True if we want the search displayed while we wait.
+ # query: string. The SQL query which makes the buglist.
+ #%]
+
+<html>
+ <head>
+ <title>[% terms.Bugzilla %] is pondering your search</title>
+ <link href="[% 'skins/standard/global.css' FILTER mtime %]"
+ rel="stylesheet" type="text/css">
+ </head>
+ <body>
+ <h1 style="margin-top: 20%; text-align: center; font-size: xx-large;">Please stand by ...</h1>
+
+ [% IF debug %]
+ <p>[% query FILTER html %]</p>
+ [% IF query_explain.defined %]
+ <pre>[% query_explain FILTER html %]</pre>
+ [% END %]
+ [% END %]
+ </body>
+</html>
diff --git a/template/en/default/list/table.html.tmpl b/template/en/default/list/table.html.tmpl
new file mode 100644
index 0000000..96f4ea3
--- /dev/null
+++ b/template/en/default/list/table.html.tmpl
@@ -0,0 +1,250 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%############################################################################%]
+[%# Initialization #%]
+[%############################################################################%]
+
+[%# Don't display the table or do any processing if there are no bugs
+ # to display %]
+[% RETURN IF !bugs.size %]
+
+[%# Columns whose titles or values should be abbreviated to make the list
+ # more compact. For columns whose titles should be abbreviated,
+ # the shortened title is included. For columns whose values should be
+ # abbreviated, a maximum length is provided along with the ellipsis that
+ # should be added to an abbreviated value, if any.
+ # wrap is set if a column's contents should be allowed to be word-wrapped
+ # by the browser.
+ #%]
+
+[% field_descs.short_short_desc = field_descs.short_desc %]
+[% field_descs.assigned_to_realname = field_descs.assigned_to %]
+[% field_descs.reporter_realname = field_descs.reporter %]
+[% field_descs.qa_contact_realname = field_descs.qa_contact %]
+
+[% abbrev =
+ {
+ "bug_severity" => { maxlength => 3 , title => "Sev" } ,
+ "priority" => { maxlength => 7 , title => "Pri" } ,
+ "rep_platform" => { maxlength => 3 , title => "HW" } ,
+ "bug_status" => { maxlength => 4 } ,
+ "assigned_to" => { maxlength => 30 , ellipsis => "..." } ,
+ "assigned_to_realname" => { maxlength => 20 , ellipsis => "..." } ,
+ "reporter" => { maxlength => 30 , ellipsis => "..." } ,
+ "reporter_realname" => { maxlength => 20 , ellipsis => "..." } ,
+ "qa_contact" => { maxlength => 30 , ellipsis => "..." , title => "QAContact" } ,
+ "qa_contact_realname" => { maxlength => 20 , ellipsis => "..." , title => "QAContact" } ,
+ "resolution" => { maxlength => 4 } ,
+ "short_desc" => { wrap => 1 } ,
+ "short_short_desc" => { maxlength => 60 , ellipsis => "..." , wrap => 1 } ,
+ "status_whiteboard" => { title => "Whiteboard" , wrap => 1 } ,
+ "keywords" => { wrap => 1 } ,
+ "flagtypes.name" => { wrap => 1 } ,
+ "component" => { maxlength => 8 , title => "Comp" } ,
+ "product" => { maxlength => 8 } ,
+ "version" => { maxlength => 5 , title => "Vers" } ,
+ "op_sys" => { maxlength => 4 } ,
+ "bug_file_loc" => { maxlength => 30 } ,
+ "target_milestone" => { title => "TargetM" } ,
+ "longdescs.count" => { title => "# Comments" },
+ "percentage_complete" => { format_value => "%d %%" } ,
+ }
+%]
+
+[% PROCESS bug/time.html.tmpl %]
+
+[% Hook.process("before_table") %]
+
+[%############################################################################%]
+[%# Table Header #%]
+[%############################################################################%]
+
+[% tableheader = BLOCK %]
+ <table class="bz_buglist" cellspacing="0" cellpadding="4" width="100%">
+ <tr class="bz_buglist_header bz_first_buglist_header">
+ [% IF dotweak %]
+ <th>&nbsp;</th>
+ [% END %]
+ <th colspan="[% splitheader ? 2 : 1 %]" class="first-child">
+ <a href="buglist.cgi?
+ [% urlquerypart FILTER html %]&amp;order=
+ [% PROCESS new_order id='bug_id' %]
+ [%-#%]&amp;query_based_on=
+ [% defaultsavename OR searchname FILTER uri %]">ID
+ [% PROCESS order_arrow id='bug_id' ~%]
+ </a>
+ </th>
+
+ [% IF splitheader %]
+
+ [% FOREACH id = displaycolumns %]
+ [% NEXT UNLESS loop.count() % 2 == 0 %]
+ [% column = columns.$id %]
+ [% PROCESS columnheader %]
+ [% END %]
+
+ </tr><tr class="bz_buglist_header">
+ [% IF dotweak %]
+ <th>&nbsp;</th>
+ [% END %]
+ <th>&nbsp;</th>
+
+ [% FOREACH id = displaycolumns %]
+ [% NEXT IF loop.count() % 2 == 0 %]
+ [% column = columns.$id %]
+ [% PROCESS columnheader %]
+ [% END %]
+
+ [% ELSE %]
+
+ [% FOREACH id = displaycolumns %]
+ [% column = columns.$id %]
+ [% PROCESS columnheader %]
+ [% END %]
+
+ [% END %]
+
+ </tr>
+[% END %]
+
+[% BLOCK columnheader %]
+ <th colspan="[% splitheader ? 2 : 1 %]">
+ <a href="buglist.cgi?[% urlquerypart FILTER html %]&amp;order=
+ [% PROCESS new_order %]
+ [%-#%]&amp;query_based_on=
+ [% defaultsavename OR searchname FILTER uri %]">
+ [%- abbrev.$id.title || field_descs.$id || column.title FILTER html -%]
+ [% PROCESS order_arrow ~%]
+ </a>
+ </th>
+[% END %]
+
+[% BLOCK new_order %]
+ [% desc = '' %]
+ [% IF (om = order.match("\\b$id( DESC)?")) %]
+ [% desc = ' DESC' IF NOT om.0 %]
+ [% END %]
+ [% id _ desc FILTER uri %]
+ [% IF id != 'bug_id' AND order %]
+ [% ',' _ order.remove("\\b$id( DESC)?(,\\s*|\$)") FILTER uri %]
+ [% END %]
+[% END %]
+
+[% BLOCK order_arrow %]
+ [% IF order.match("^$id DESC") %]
+ <span class="bz_sort_order_primary">&#x25BC;</span>
+ [% ELSIF order.match("^$id(,\\s*|\$)") %]
+ <span class="bz_sort_order_primary">&#x25B2;</span>
+ [% ELSIF order.match("\\b$id DESC") %]
+ <span class="bz_sort_order_secondary">&#x25BC;</span>
+ [% ELSIF order.match("\\b$id(,\\s*|\$)") %]
+ <span class="bz_sort_order_secondary">&#x25B2;</span>
+ [% END %]
+[% END %]
+
+[%############################################################################%]
+[%# Bug Table #%]
+[%############################################################################%]
+
+[% tableheader %]
+
+[% FOREACH bug = bugs %]
+ [% count = loop.count() %]
+
+ <tr id="b[% bug.bug_id %]" class="bz_bugitem
+ bz_[% bug.bug_severity FILTER css_class_quote -%]
+ bz_[% bug.priority FILTER css_class_quote -%]
+ bz_[% bug.bug_status FILTER css_class_quote -%]
+ [%+ "bz_$bug.resolution" FILTER css_class_quote IF bug.resolution -%]
+ [%+ "bz_secure" IF bug.secure_mode -%]
+ [%+ "bz_secure_mode_$bug.secure_mode" FILTER css_class_quote IF bug.secure_mode -%]
+ [%+ count % 2 == 1 ? "bz_row_odd" : "bz_row_even" -%]
+ ">
+
+ [% IF dotweak %]
+ <td class="bz_checkbox_column">
+ <input type="checkbox" name="id_[% bug.bug_id %]">
+ </td>
+ [% END %]
+ <td class="first-child bz_id_column">
+ <a href="show_bug.cgi?id=[% bug.bug_id %]">[% bug.bug_id %]</a>
+ <span style="display: none">[%+ '[SEC]' IF bug.secure_mode %]</span>
+ </td>
+
+ [% FOREACH column = displaycolumns %]
+ <td [% 'style="white-space: nowrap"' IF NOT abbrev.$column.wrap %]
+ class="bz_[% column FILTER css_class_quote %]_column">
+ [% IF abbrev.$column.maxlength %]
+ <span title="[%- display_value(column, bug.$column) FILTER html %]">
+ [% END %]
+ [% IF abbrev.$column.format_value %]
+ [%- bug.$column FILTER format(abbrev.$column.format_value) FILTER html -%]
+ [% ELSIF column == 'actual_time' ||
+ column == 'remaining_time' ||
+ column == 'estimated_time' %]
+ [% PROCESS formattimeunit time_unit=bug.$column %]
+ [%# Display the login name of the user if their real name is empty. %]
+ [% ELSIF column.match('_realname$') && bug.$column == '' %]
+ [% SET login_column = column.remove('_realname$') %]
+ [% bug.${login_column}.truncate(abbrev.$column.maxlength,
+ abbrev.$column.ellipsis) FILTER html %]
+ [% ELSIF column == 'short_desc' || column == "short_short_desc" %]
+ <a href="show_bug.cgi?id=[% bug.bug_id FILTER html %]">
+ [%- bug.$column.truncate(abbrev.$column.maxlength, abbrev.$column.ellipsis) FILTER html -%]
+ </a>
+ [% ELSE %]
+ [%- display_value(column, bug.$column).truncate(abbrev.$column.maxlength, abbrev.$column.ellipsis) FILTER html -%]
+ [% END %]
+ [% IF abbrev.$column.maxlength %]
+ </span>
+ [% END %]
+ </td>
+ [% END %]
+
+ </tr>
+
+ [% IF loop.last() && time_info.time_present == 1 %]
+ [% PROCESS time_summary_line %]
+ [% END %]
+
+[% END %]
+
+</table>
+
+[% BLOCK time_summary_line %]
+ <tr class="bz_time_summary_line">
+ [% columns_to_span = 1 %] [%# bugID %]
+ [% IF dotweak %]
+ [% columns_to_span = columns_to_span + 1 %]
+ [% END %]
+ [% FOREACH column = displaycolumns %]
+ [% IF column == 'actual_time' ||
+ column == 'remaining_time' ||
+ column == 'estimated_time' ||
+ column == 'percentage_complete' %]
+ [% IF columns_to_span > 0 %]
+ <td class="bz_total bz_total_label" colspan="
+ [%- columns_to_span FILTER html %]"><b>Totals</b></td>
+ [% columns_to_span = 0 %]
+ [% END %]
+ [% IF column == 'percentage_complete' %]
+ <td class="bz_total">[% time_info.percentage_complete
+ FILTER format(abbrev.$column.format_value) FILTER html %]</td>
+ [% ELSE %]
+ <td class="bz_total">
+ [%- PROCESS formattimeunit time_unit=time_info.$column %]</td>
+ [% END %]
+ [% ELSIF columns_to_span == 0 %] [%# A column following the first total %]
+ <td class="bz_total">&nbsp;</td>
+ [% ELSE %] [%# We haven't gotten to a time column yet, keep computing span %]
+ [% columns_to_span = columns_to_span + 1 %]
+ [% END %]
+ [% END %]
+ </tr>
+[% END %]
diff --git a/template/en/default/pages/bug-writing.html.tmpl b/template/en/default/pages/bug-writing.html.tmpl
new file mode 100644
index 0000000..1fc097e
--- /dev/null
+++ b/template/en/default/pages/bug-writing.html.tmpl
@@ -0,0 +1,162 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% INCLUDE global/header.html.tmpl title = "$terms.Bug Writing Guidelines" %]
+
+ <p>Effective [% terms.bug %] reports are the most likely to be fixed.
+ These guidelines explain how to write such reports.
+
+<h3>Principles</h3>
+
+ <ul>
+ <li>Be precise</li>
+ <li>Be clear - explain it so others can reproduce the [% terms.bug %]</li>
+ <li>One [% terms.bug %] per report</li>
+ <li>No [% terms.bug %] is too trivial to report -
+ small [% terms.bugs %] may hide big [% terms.bugs %]</li>
+ <li>Clearly separate fact from speculation</li>
+ </ul>
+
+<h3>Preliminaries</h3>
+
+<ol>
+ <li>Reproduce your [% terms.bug %] using a recent build of the
+ software, to see whether it has already been fixed.
+ </li>
+
+ <li><a href="query.cgi?format=specific">Search</a>
+ [% terms.Bugzilla %], to see whether your [% terms.bug %] has
+ already been reported.</li>
+</ol>
+
+<h3>Reporting a New [% terms.Bug %]</h3>
+
+<p>If you have reproduced the [% terms.bug %] in a recent build and
+no-one else appears to have reported it, then:</p>
+
+<ol>
+ <li>Choose
+ "<a href="enter_bug.cgi">Enter a new [% terms.bug %]</a>"</li>
+ <li>Select the product in which you've found the [% terms.bug %]</li>
+ <li>Fill out the form. Here is some help understanding it:</li>
+</ol>
+
+ <blockquote>
+ <p><b>Component:</b> In which sub-part of the software does it
+ exist?<br>
+ This field is required.
+ Click the word "Component" to see a description of each
+ component. If none seems appropriate, look for a "General" component.</p>
+
+ <p><b>[% field_descs.op_sys FILTER html %]:</b> On which operating system (OS) did you find
+ it?
+ (e.g. Linux, Windows XP, Mac OS X.)<br>
+ If you know the [% terms.bug %] happens on more than one type of
+ operating system, choose <em>[% display_value("op_sys", "All") FILTER html %]</em>.
+ If your [% field_descs.op_sys FILTER html %] isn't listed, choose
+ <em>[% display_value("op_sys", "Other") FILTER html %]</em>.</p>
+
+ <p><b>Summary:</b> How would you describe the [% terms.bug %], in
+ approximately 60 or fewer characters?<br>
+ A good summary should <b>quickly and uniquely identify [% terms.abug %]
+ report</b>. It should explain the problem, not your suggested solution.<br>
+ <ul>
+ <li>Good: "<tt>Cancelling a File Copy dialog crashes
+ File Manager</tt>"</li>
+ <li>Bad: "<tt>Software crashes</tt>"</li>
+ <li>Bad: "<tt>Browser should work with my web site</tt>"</li>
+ </ul>
+
+ <b>Description:</b>
+ The details of your problem report, including:</p>
+
+ <blockquote>
+ <p><b>Overview:</b> More detailed restatement of
+ summary.</p>
+
+ <blockquote>
+<pre>
+Drag-selecting any page crashes Mac builds in the NSGetFactory function.
+</pre>
+ </blockquote>
+
+ <p><b>Steps to Reproduce:</b> Minimized, easy-to-follow steps that
+ will trigger the [% terms.bug %]. Include any special setup steps.</p>
+
+ <blockquote>
+<pre>
+1) View any web page. (I used the default sample page,
+resource:/res/samples/test0.html)
+
+2) Drag-select the page. (Specifically, while holding down
+the mouse button, drag the mouse pointer downwards from any
+point in the browser's content region to the bottom of the
+browser's content region.)
+</pre>
+ </blockquote>
+
+ <p><b>Actual Results:</b> What the application did after performing
+ the above steps.</p>
+
+ <blockquote>
+<pre>
+The application crashed.
+</pre>
+ </blockquote>
+
+ <p><b>Expected Results:</b> What the application should have done,
+ were the [% terms.bug %] not present.</p>
+
+ <blockquote>
+<pre>
+The window should scroll downwards. Scrolled content should be selected.
+(Or, at least, the application should not crash.)
+</pre>
+ </blockquote>
+
+ <p><b>Build Date &amp; [% field_descs.rep_platform FILTER html %]:</b>
+ Date and [% field_descs.rep_platform FILTER lower FILTER html %] of the build
+ in which you first encountered the [% terms.bug %].</p>
+
+ <blockquote>
+<pre>
+Build 2006-08-10 on Mac OS 10.4.3
+</pre>
+ </blockquote>
+
+ <p><b>Additional Builds and Platforms:</b> Whether or not
+ the [% terms.bug %] takes place on other platforms (or browsers,
+ if applicable).</p>
+
+ <blockquote>
+<pre>
+Doesn't Occur On Build 2006-08-10 on Windows XP Home (Service Pack 2)
+</pre>
+ </blockquote>
+
+ <p><b>Additional Information:</b> Any other useful information.
+ <br><br>For crashing [% terms.bugs %]:</p>
+
+ <ul>
+ <li><b>Windows:</b> Note the type of the crash, and the module that the
+ application crashed in (e.g. access violation in apprunner.exe).</li>
+
+ <li><b>Mac OS X:</b> Attach the "Crash Reporter" log that appears
+ upon crash.
+ Only include the section directly below the crashing thread, usually
+ titled "Thread 0 Crashed". Please do not paste the entire log!</li>
+ </ul>
+ </blockquote>
+
+ <p>Double-check your report for errors and omissions, then press "Commit".
+ Your [% terms.bug %] report will now be in
+ the [% terms.Bugzilla %] database.<br>
+ </p>
+</blockquote>
+
+[% INCLUDE global/footer.html.tmpl %]
diff --git a/template/en/default/pages/bugzilla.dtd.tmpl b/template/en/default/pages/bugzilla.dtd.tmpl
new file mode 100644
index 0000000..ee4492c
--- /dev/null
+++ b/template/en/default/pages/bugzilla.dtd.tmpl
@@ -0,0 +1,162 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[% USE Bugzilla %]
+<!ELEMENT [% "bugzilla" %] (bug+)>
+<!ATTLIST [% "bugzilla" %]
+ version CDATA #REQUIRED
+ urlbase CDATA #REQUIRED
+ maintainer CDATA #REQUIRED
+ exporter CDATA #IMPLIED
+>
+<!ELEMENT [% "bug" %] (bug_id,
+ (alias?,
+ creation_ts,
+ short_desc,
+ delta_ts,
+ reporter_accessible,
+ cclist_accessible,
+ classification_id,
+ classification,
+ product,
+ component,
+ version,
+ rep_platform,
+ op_sys,
+ bug_status,
+ resolution?,
+ dup_id?,
+ see_also*,
+ bug_file_loc?,
+ status_whiteboard?,
+ keywords*,
+ priority,
+ bug_severity,
+ target_milestone?,
+ dependson*,
+ blocked*,
+ everconfirmed,
+ reporter,
+ assigned_to,
+ cc*,
+ (estimated_time,
+ remaining_time,
+ actual_time,
+ deadline?)?,
+ qa_contact?,
+[% FOREACH field = Bugzilla.active_custom_fields %]
+ [%+ field.name FILTER xml -%]
+ [%- IF field.type == constants.FIELD_TYPE_MULTI_SELECT %]*[% ELSE %]?[% END %],
+[% END %]
+ votes?,
+ token?,
+ group*,
+ flag*,
+ comment_sort_order*,
+ long_desc*,
+ attachment*)?)>
+<!ATTLIST [% "bug" %]
+ error (NotFound | NotPermitted | InvalidBugId) #IMPLIED
+>
+<!ELEMENT bug_id (#PCDATA)>
+<!ELEMENT alias (#PCDATA)>
+<!ELEMENT reporter_accessible (#PCDATA)>
+<!ELEMENT cclist_accessible (#PCDATA)>
+<!ELEMENT exporter (#PCDATA)>
+<!ELEMENT urlbase (#PCDATA)>
+<!ELEMENT bug_status (#PCDATA)>
+<!ELEMENT classification_id (#PCDATA)>
+<!ELEMENT classification (#PCDATA)>
+<!ELEMENT product (#PCDATA)>
+<!ELEMENT priority (#PCDATA)>
+<!ELEMENT version (#PCDATA)>
+<!ELEMENT rep_platform (#PCDATA)>
+<!ELEMENT assigned_to (#PCDATA)>
+<!ATTLIST assigned_to
+ name CDATA #REQUIRED
+>
+<!ELEMENT delta_ts (#PCDATA)>
+<!ELEMENT component (#PCDATA)>
+<!ELEMENT reporter (#PCDATA)>
+<!ATTLIST reporter
+ name CDATA #REQUIRED
+>
+<!ELEMENT target_milestone (#PCDATA)>
+<!ELEMENT bug_severity (#PCDATA)>
+<!ELEMENT creation_ts (#PCDATA)>
+<!ELEMENT qa_contact (#PCDATA)>
+<!ATTLIST qa_contact
+ name CDATA #REQUIRED
+>
+<!ELEMENT status_whiteboard (#PCDATA)>
+<!ELEMENT op_sys (#PCDATA)>
+<!ELEMENT resolution (#PCDATA)>
+<!ELEMENT dup_id (#PCDATA)>
+<!ELEMENT bug_file_loc (#PCDATA)>
+<!ELEMENT short_desc (#PCDATA)>
+<!ELEMENT keywords (#PCDATA)>
+<!ELEMENT dependson (#PCDATA)>
+<!ELEMENT blocked (#PCDATA)>
+<!ELEMENT everconfirmed (#PCDATA)>
+<!ELEMENT cc (#PCDATA)>
+<!ELEMENT see_also (#PCDATA)>
+<!ELEMENT votes (#PCDATA)>
+<!ELEMENT token (#PCDATA)>
+<!ELEMENT group (#PCDATA)>
+<!ATTLIST group
+ id CDATA #REQUIRED
+>
+<!ELEMENT estimated_time (#PCDATA)>
+<!ELEMENT remaining_time (#PCDATA)>
+<!ELEMENT actual_time (#PCDATA)>
+<!ELEMENT deadline (#PCDATA)>
+[% FOREACH field = Bugzilla.active_custom_fields %]
+<!ELEMENT [% field.name FILTER xml %] (#PCDATA)>
+[% END %]
+<!ELEMENT comment_sort_order (#PCDATA)>
+<!ELEMENT long_desc (commentid, comment_count, attachid?, who, bug_when, work_time?, thetext)>
+<!ATTLIST long_desc
+ isprivate (0|1) #REQUIRED
+>
+<!ELEMENT commentid (#PCDATA)>
+<!ELEMENT comment_count (#PCDATA)>
+<!ELEMENT who (#PCDATA)>
+<!ATTLIST who
+ name CDATA #REQUIRED
+>
+<!ELEMENT bug_when (#PCDATA)>
+<!ELEMENT work_time (#PCDATA)>
+<!ELEMENT thetext (#PCDATA)>
+<!ELEMENT attachment (attachid, date, delta_ts, desc, filename, type, size, attacher, token?, data?, flag*)>
+<!ATTLIST attachment
+ isobsolete (0|1) #REQUIRED
+ ispatch (0|1) #REQUIRED
+ isprivate (0|1) #REQUIRED
+>
+<!ELEMENT attacher (#PCDATA)>
+<!ATTLIST attacher
+ name CDATA #REQUIRED
+>
+<!ELEMENT attachid (#PCDATA)>
+<!ELEMENT date (#PCDATA)>
+<!ELEMENT desc (#PCDATA)>
+<!ELEMENT filename (#PCDATA)>
+<!ELEMENT type (#PCDATA)>
+<!ELEMENT size (#PCDATA)>
+<!ELEMENT data (#PCDATA)>
+<!ATTLIST data
+ encoding (base64) #IMPLIED
+>
+<!ELEMENT flag EMPTY>
+<!ATTLIST flag
+ name CDATA #REQUIRED
+ id CDATA #REQUIRED
+ type_id CDATA #REQUIRED
+ status CDATA #REQUIRED
+ setter CDATA #REQUIRED
+ requestee CDATA #IMPLIED
+>
diff --git a/template/en/default/pages/fields.html.tmpl b/template/en/default/pages/fields.html.tmpl
new file mode 100644
index 0000000..48b09ae
--- /dev/null
+++ b/template/en/default/pages/fields.html.tmpl
@@ -0,0 +1,227 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "$terms.Bug Fields"
+ style_urls = ['skins/standard/page.css']
+%]
+
+<p>This page describes the various fields that you see
+ on [% terms.abug %].</p>
+
+<table class="field_value_explanation">
+ <thead>
+ <tr>
+ <td id="bug_status">
+ <h2>[% field_descs.bug_status FILTER upper FILTER html %]</h2>
+ </td>
+
+ <td id="resolution">
+ <h2>[% field_descs.resolution FILTER upper FILTER html %]</h2>
+ </td>
+ </tr>
+
+ <tr>
+ <td>The [% field_descs.bug_status FILTER html %] field indicates the
+ current state of a [% terms.bug %]. Only certain status transitions
+ are allowed.</td>
+
+ <td>The [% field_descs.resolution FILTER html %] field indicates what
+ happened to this [%+ terms.bug %].</td>
+ </tr>
+ </thead>
+
+ <tbody>
+ <tr class="header_row">
+ <td colspan="2">Open [% terms.Bugs %]</td>
+ </tr>
+ <tr>
+ <td>
+ <dl>
+ <dt class="unconfirmed">
+ [% display_value("bug_status", "UNCONFIRMED") FILTER html %]
+ </dt>
+ <dd class="unconfirmed">
+ This [% terms.bug %] has recently been added to the database.
+ Nobody has confirmed that this [% terms.bug %] is valid. Users
+ who have the "canconfirm" permission set may confirm
+ this [% terms.bug %], changing its state to
+ <b>[% display_value("bug_status", "CONFIRMED") FILTER html %]</b>.
+ Or, it may be directly resolved and marked
+ <b>[% display_value("bug_status", "RESOLVED") FILTER html %]</b>.
+ </dd>
+
+ <dt class="confirmed">
+ [% display_value("bug_status", "CONFIRMED") FILTER html %]
+ </dt>
+ <dd class="confirmed">
+ This [% terms.bug %] is valid and has recently been filed.
+ [%+ terms.Bugs %] in this state become
+ <b>[% display_value("bug_status", "IN_PROGRESS") FILTER html %]</b>
+ when somebody is working on them, or become resolved and marked
+ <b>[% display_value("bug_status", "RESOLVED") FILTER html %]</b>.
+ </dd>
+
+ <dt class="in_progress">
+ [% display_value("bug_status", "IN_PROGRESS") FILTER html %]
+ </dt>
+ <dd class="in_progress">
+ This [% terms.bug %] is not yet resolved, but is assigned to the
+ proper person who is working on the [% terms.bug %]. From here,
+ [%+ terms.bugs %] can be given to another person and become
+ <b>[% display_value("bug_status", "CONFIRMED") FILTER html %]</b>, or
+ resolved and become
+ <b>[% display_value("bug_status", "RESOLVED") FILTER html %]</b>.
+ </dd>
+
+ [% Hook.process('open-status') %]
+ </dl>
+ </td>
+
+ <td>
+ No resolution yet. All [% terms.bugs %] which are in one of
+ these "open" states have no resolution set.
+ </td>
+ </tr>
+
+ <tr class="header_row">
+ <td colspan="2">Closed [% terms.Bugs %]</td>
+ </tr>
+
+ <tr>
+ <td>
+ <dl>
+ <dt class="resolved">
+ [% display_value("bug_status", "RESOLVED") FILTER html %]
+ </dt>
+ <dd class="resolved">
+ A resolution has been performed, and it is awaiting verification by
+ QA. From here [% terms.bugs %] are either reopened and given some
+ open status, or are verified by QA and marked
+ <b>[% display_value("bug_status", "VERIFIED") FILTER html %]</b>.
+ </dd>
+
+ <dt class="verified">
+ [% display_value("bug_status", "VERIFIED") FILTER html %]
+ </dt>
+ <dd class="verified">
+ QA has looked at the [% terms.bug %] and the resolution and
+ agrees that the appropriate resolution has been taken. This is
+ the final status for [% terms.bugs %].
+ </dd>
+
+ [% Hook.process('closed-status') %]
+ </dl>
+ </td>
+
+ <td>
+ <dl>
+ <dt class="fixed">
+ [% display_value("resolution", "FIXED") FILTER html %]
+ </dt>
+ <dd class="fixed">
+ A fix for this [% terms.bug %] is checked into the tree and
+ tested.
+ </dd>
+
+ <dt class="invalid">
+ [% display_value("resolution", "INVALID") FILTER html %]
+ </dt>
+ <dd class="invalid">
+ The problem described is not [% terms.abug %].
+ </dd>
+
+ <dt class="wontfix">
+ [% display_value("resolution", "WONTFIX") FILTER html %]
+ </dt>
+ <dd class="wontfix">
+ The problem described is [% terms.abug %] which will never be
+ fixed.
+ </dd>
+
+ <dt class="duplicate">
+ [% display_value("resolution", "DUPLICATE") FILTER html %]
+ </dt>
+ <dd class="duplicate">
+ The problem is a duplicate of an existing [% terms.bug %].
+ When [% terms.abug %] is marked as a
+ <b>[% display_value("resolution", "DUPLICATE") FILTER html %]</b>,
+ you will see which [% terms.bug %] it is a duplicate of,
+ next to the resolution.
+ </dd>
+
+ <dt class="worksforme">
+ [% display_value("resolution", "WORKSFORME") FILTER html %]
+ </dt>
+ <dd class="worksforme">
+ All attempts at reproducing this [% terms.bug %] were futile,
+ and reading the code produces no clues as to why the described
+ behavior would occur. If more information appears later,
+ the [% terms.bug %] can be reopened.
+ </dd>
+
+ [% Hook.process('resolution') %]
+ </dl>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2>Other Fields</h2>
+
+[% SET field_help_map = {} %]
+[% FOREACH field = bug_fields.keys %]
+ [% SET field_desc = field_descs.$field %]
+ [% field_help_map.$field_desc = { help => help_html.$field,
+ field => field } %]
+[% END %]
+
+[%# This field is not a real one, but its label is visible in bugs. %]
+
+[% field_help_map.Importance = { help => help_html.importance,
+ field => "importance" } %]
+
+[%# These are fields that don't need to be documented, either because
+ # they have docs somewhere else in the UI, or they don't show up on bugs.
+ # %]
+[% SET skip_fields = [
+ 'days_elapsed',
+ 'everconfirmed',
+ 'reporter_accessible',
+ 'cclist_accessible',
+ 'bug_group',
+ 'commenter',
+ 'owner_idle_time',
+ 'bug_status',
+ 'resolution',
+] %]
+
+<dl class="field_descriptions">
+[% FOREACH field_desc = field_help_map.keys.sort %]
+ [% SET field = field_help_map.${field_desc}.field %]
+ [% SET field_object = bug_fields.$field %]
+
+ [% NEXT IF field_object.obsolete %]
+ [% NEXT IF !user.is_timetracker AND field_object.is_timetracking %]
+
+ [% NEXT IF field == 'status_whiteboard' AND !Param('usestatuswhiteboard') %]
+ [% NEXT IF field == 'target_milestone' AND !Param('usetargetmilestone') %]
+
+ [%# For now we don't have help for attachment fields and so on. %]
+ [% NEXT IF field.match('\.') %]
+
+ [% NEXT IF skip_fields.contains(field) %]
+
+ <dt id="[% field FILTER html %]">[% field_desc FILTER html %]</dt>
+ <dd>
+ [% field_help_map.${field_desc}.help FILTER html_light %]
+ </dd>
+[% END %]
+</dl>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/pages/linked.html.tmpl b/template/en/default/pages/linked.html.tmpl
new file mode 100644
index 0000000..92d0f59
--- /dev/null
+++ b/template/en/default/pages/linked.html.tmpl
@@ -0,0 +1,42 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% INCLUDE global/header.html.tmpl title = "Your Linkified Text" %]
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+<p>
+ Copy and paste the text below:
+</p>
+
+<hr>
+
+<p>
+<pre class="bz_comment_text">
+[%- cgi.param("text") FILTER quoteUrls FILTER html -%]
+</pre>
+</p>
+
+<hr>
+
+<p>
+ If you place it in <tt>&lt;pre&gt;</tt> tags,
+ the text will end up looking like this:
+</p>
+
+<hr>
+
+<p>
+<pre class="bz_comment_text">
+[%- cgi.param("text") FILTER quoteUrls -%]
+</pre>
+</p>
+
+<hr>
+
+[% INCLUDE global/footer.html.tmpl %]
diff --git a/template/en/default/pages/linkify.html.tmpl b/template/en/default/pages/linkify.html.tmpl
new file mode 100644
index 0000000..e02ca8d
--- /dev/null
+++ b/template/en/default/pages/linkify.html.tmpl
@@ -0,0 +1,28 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% INCLUDE global/header.html.tmpl title = "Linkify Text" %]
+
+<p>
+ If you enter some text, this form will return it marked up like a
+ standard [% terms.Bugzilla %] comment. That is, valid [% terms.bug %] numbers,
+ URLs, email addresses and so on will be replaced with appropriate HTML links.
+</p>
+
+<form action="page.cgi" method="post">
+ [% INCLUDE global/textarea.html.tmpl
+ name = 'text'
+ minrows = 20
+ cols = constants.COMMENT_COLS
+ %]
+ <br>
+ <input type="hidden" name="id" value="linked.html">
+ <input type="submit" id="linkify" value="Linkify">
+</form>
+
+[% INCLUDE global/footer.html.tmpl %]
diff --git a/template/en/default/pages/quicksearch.html.tmpl b/template/en/default/pages/quicksearch.html.tmpl
new file mode 100644
index 0000000..f3794e1
--- /dev/null
+++ b/template/en/default/pages/quicksearch.html.tmpl
@@ -0,0 +1,325 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% INCLUDE global/header.html.tmpl
+ title = "$terms.Bugzilla QuickSearch",
+ style_urls = ['skins/standard/page.css']
+ onload = 'document.forms[\'f\'].quicksearch.focus()'
+ %]
+
+[% USE Bugzilla %]
+
+<p><label for="quicksearch">Type in one or more words (or pieces of words)
+ to search for:</label></p>
+
+<form name="f" action="buglist.cgi" method="get"
+ onsubmit="if (this.quicksearch.value == '')
+ { alert('Please enter one or more search terms first.');
+ return false; } return true;">
+ <input type="text" size="40" name="quicksearch" id="quicksearch">
+ <input type="submit" value="Search" id="find">
+</form>
+
+<ul>
+ <li><a href="#basics">The Basics</a></li>
+ <li><a href="#basic_examples">Examples of Simple Queries</a></li>
+ <li><a href="#fields">Fields You Can Search On</a></li>
+ <li><a href="#advanced_features">Advanced Features</a></li>
+ <li><a href="#shortcuts">Advanced Shortcuts</a></li>
+ <li><a href="#advanced_examples">Examples of Complex Queries</a></li>
+</ul>
+
+<h2 id="basics">The Basics</h2>
+
+<ul class="qs_help">
+ <li>If you just put a word or series of words in the search box,
+ [%+ terms.Bugzilla %] will search the
+ [%+ field_descs.product FILTER html %],
+ [%+ field_descs.component FILTER html %],
+ [%+ IF use_keywords %][%+ field_descs.keywords FILTER html %],[% END %]
+ [%+ field_descs.alias FILTER html %],
+ [%+ field_descs.short_desc FILTER html %],
+ [%+ IF Param('usestatuswhiteboard') %][% field_descs.status_whiteboard FILTER html %],[% END %]
+ and [% field_descs.longdesc FILTER html %] fields for your word or words.</li>
+
+ <li>Typing just a <strong>number</strong> in the search box will take
+ you directly to the [% terms.bug %] with that ID. Also, just typing the
+ <strong>alias</strong> of [% terms.abug %] will take you to that [% terms.bug %].
+ </li>
+
+ <li>Adding more terms <strong>narrows down</strong> the search, it does not
+ expand it. (In other words, [% terms.Bugzilla %] searches for
+ [%+ terms.bugs %] that match <em>all</em> your criteria, not
+ [%+ terms.bugs %] that match <em>any</em> of your criteria.)</li>
+
+ <li>Searching is <strong>case-insensitive</strong>. So <kbd>table</kbd>,
+ <kbd>Table</kbd>, and <kbd>TABLE</kbd> are all the same.</li>
+
+ <li>[% terms.Bugzilla %] does not just search for the exact word you put in,
+ but also for any word that <strong>contains</strong> that word.
+ So, for example, searching for "cat" would also find [% terms.bugs %]
+ that contain it as part of other words&mdash;for example, [% terms.abug %]
+ mentioning "<strong>cat</strong>ch" or "certifi<strong>cat</strong>e". It
+ will not find partial words in the [% field_descs.longdesc FILTER html %]
+ or [% field_descs.keywords FILTER html %] fields,
+ though&mdash;only full words are matched, there.</li>
+
+ <li>By default, only <strong>open</strong> [% terms.bugs %] are
+ searched. If you want to know how to also search closed [% terms.bugs %],
+ see the <a href="#shortcuts">Advanced Shortcuts</a> section.</li>
+
+ <li>If you want to search <strong>specific fields</strong>, you do it like
+ <kbd>field:value</kbd>, where <kbd>field</kbd> is one of the
+ <a href="#fields">field names</a> lower down in this
+ document and <kbd>value</kbd> is the value you want to search for
+ in that field. If you put commas in the <kbd>value</kbd>, then it is
+ interpreted as a list of values, and [% terms.bugs %] that match
+ <em>any</em> of those values will be searched for.</li>
+</ul>
+
+<h2 id="basic_examples">Examples of Simple Queries</h2>
+
+<p>Here are some examples of how to write some simple queries.
+ <a href="#advanced_examples">Examples for more complex queries</a> can be
+ found lower in this page.</p>
+
+<ul class="qs_help">
+ <li>All open [% terms.bugs %] where userA@company.com is in the CC list
+ (no need to mention open [% terms.bugs %], this is the default):<br>
+ <kbd>cc:userA@company.com</kbd></li>
+ <li>All unconfirmed [% terms.bugs %] in product productA (putting the
+ [%+ terms.bug %] status at the first position make it being automagically
+ considered as [% terms.abug %] status):<br>
+ <kbd>UNCONFIRMED product:productA</kbd>
+ <li>All open and closed [% terms.bugs %] reported by userB@company.com
+ (we must specify ALL as the first word, else only open [% terms.bugs %]
+ are taken into account):<br>
+ <kbd>ALL reporter:userB@company.com</kbd>
+ <li>All open [% terms.bugs %] with severity blocker or critical with the
+ target milestone set to 2.5:<br>
+ <kbd>severity:blocker,critical milestone:2.5</kbd>
+ <li>All open [% terms.bugs %] in the component Research & Development
+ with priority P1 or P2 (we must use quotes for the component as its name
+ contains whitespaces):<br>
+ <kbd>component:"Research & Development" priority:P1,P2</kbd></li>
+</ul>
+
+<h2 id="fields">Fields You Can Search On</h2>
+
+<p>You can specify any of these fields like <kbd>field:value</kbd>
+ in the search box, to search on them. You can also abbreviate
+ the field name, as long as your abbreviation matches only one field name.
+ So, for example, searching on <kbd>stat:VERIFIED</kbd> will find all
+ [%+ terms.bugs %] in the <kbd>VERIFIED</kbd> status. Some fields have
+ multiple names, and you can use any of those names to search for them.</p>
+
+[% IF Bugzilla.active_custom_fields.size %]
+ [% SET first_field = Bugzilla.active_custom_fields.0 %]
+ <p>For custom fields, they can be used and abbreviated
+ based on the part of their name <em>after</em> the <kbd>cf_</kbd>
+ if you'd like, in addition to their standard name starting with
+ <kbd>cf_</kbd>. So for example,
+ <kbd>[% first_field.name FILTER html %]</kbd> can be
+ referred to as
+ <kbd>[% first_field.name.replace('^cf_') FILTER html %]</kbd>,
+ also. However, if this causes a conflict between the standard
+ [%+ terms.Bugzilla %] field names and the custom field names, the
+ standard field names always take precedence.</p>
+[% END %]
+
+[% SET field_table = {} %]
+[% FOREACH field = quicksearch_field_names.keys %]
+ [% description = field_descs.$field %]
+ [% field_table.$description = quicksearch_field_names.${field} %]
+[% END %]
+
+
+<table cellspacing="0" cellpadding="0" border="0" class="qs_fields">
+ <thead>
+ <tr>
+ <th class="field_name">Field</th>
+ <th class="field_nickname">Field Name(s) For Search</th>
+ </tr>
+ </thead>
+ <tbody>
+ [% FOREACH desc = field_table.keys.sort %]
+ <tr>
+ <td class="field_name">[% desc FILTER html %]</td>
+ <td class="field_nickname">
+ [% FOREACH nickname = field_table.$desc %]
+ <kbd>[% nickname FILTER html %]</kbd>
+ [% ",&nbsp; " UNLESS loop.last %]
+ [% END %]
+ </tr>
+ [% END %]
+ </tbody>
+</table>
+
+<h2 id="advanced_features">Advanced Features</h2>
+
+<ul class="qs_help">
+ <li>If you want to search for a <strong>phrase</strong> or something that
+ contains spaces, commas, colons or quotes, you must put it in quotes, like:
+ <kbd>"yes, this is a phrase"</kbd>. You must also use quotes to search for
+ characters that would otherwise be interpreted specially by quicksearch.
+ For example, <kbd>"this|that"</kbd> would search for the literal string
+ <em>this|that</em> and would not be parsed as <kbd>"this OR that"</kbd>.
+ Also, <kbd>"-field:value"</kbd> would search for the literal phrase
+ <em>-field:value</em> and would not be parsed as
+ <kbd>"NOT field:value"</kbd>.</li>
+
+ <li>You can use <strong>AND</strong>, <strong>NOT</strong>,
+ and <strong>OR</strong> in searches.
+
+ You can also use <kbd>-</kbd> to mean "NOT", and <kbd>|</kbd> to mean "OR".
+ There is no special character for "AND", because by default any search
+ terms that are separated by a space are joined by an "AND".
+ Examples:
+ <ul>
+ <li>
+ <strong>NOT</strong>:<br>
+ Use <kbd><strong>-</strong><em>summary:foo</em></kbd> to exclude
+ [%+ terms.bugs %] with <kbd>foo</kbd> in the summary.<br>
+ <kbd><em>NOT summary:foo</em></kbd> would have the same effect.
+ </li>
+ <li>
+ <strong>AND</strong>:<br>
+ <kbd><em>foo bar</em></kbd> searches for [% terms.bugs %] that contains
+ both <kbd>foo</kbd> and <kbd>bar</kbd>.<br>
+ <kbd><em>foo AND bar</em></kbd> would have the same effect.
+ </li>
+ <li>
+ <strong>OR</strong>:<br>
+ <kbd><em>foo<strong>|</strong>bar</em></kbd> would search
+ for [% terms.bugs %] that contain <kbd>foo</kbd> OR <kbd>bar</kbd>.<br>
+ <kbd><em>foo OR bar</em></kbd> would have the same effect.<br>
+ </li>
+ </ul>
+
+ <p>You cannot use | nor OR to enumerate possible values for a given field.
+ You must use commas instead. So <kbd>field:value1,value2</kbd> does what
+ you expect, but <kbd>field:value1|value2</kbd> would be treated as
+ <kbd>field:value1 OR value2</kbd>, which means value2 is not bound to
+ the given field.</p>
+
+ <p>OR has higher precedence than AND; AND is the top level operation.
+ For example:</p>
+ <p>Searching for <em><kbd>url|location bar|field -focus</kbd></em> means
+ (<kbd>url</kbd> OR <kbd>location</kbd>) AND (<kbd>bar</kbd> OR
+ <kbd>field</kbd>) AND (NOT <kbd>focus</kbd>)</p>
+ </li>
+</ul>
+
+<h2 id="shortcuts">Advanced Shortcuts</h2>
+
+<p>In addition to using <a href="#fields">field names</a> to search
+ specific fields, there are certain characters or words that you can
+ use as a "shortcut" for searching certain fields:</p>
+
+<table cellspacing="0" cellpadding="0" border="0" class="qs_fields">
+ <thead>
+ <tr>
+ <th class="field_name">Field</th>
+ <th class="field_nickname">Shortcut(s)</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td class="field_name">[% field_descs.bug_status FILTER html %]</td>
+ <td class="field_nickname">
+ Make the <strong>first word</strong> of your search the name of any
+ status, or even an abbreviation of any status, and [% terms.bugs %]
+ in that status will be searched. <strong><kbd>ALL</kbd></strong>
+ is a special shortcut that means "all statuses".
+ <strong><kbd>OPEN</kbd></strong> is a special shortcut that means
+ "all open statuses".
+ </td>
+ </tr>
+ <tr>
+ <td class="field_name">[% field_descs.resolution FILTER html %]</td>
+ <td class="field_nickname">
+ Make the <strong>first word</strong> of your search the name of any
+ resolution, or even an abbreviation of any resolution, and
+ [%+ terms.bugs %] with that resolution will be searched. For example,
+ making <kbd>FIX</kbd> the first word of your search will find all
+ [%+ terms.bugs %] with a resolution of <kbd>FIXED</kbd> .
+ </tr>
+ <tr>
+ <td class="field_name">[% field_descs.priority FILTER html %]</td>
+ <td class="field_nickname">"<strong>P1</strong>" (as a word anywhere in
+ the search) means "find [% terms.bugs %] with the highest priority.
+ "P2" means the second-highest priority, and so on.
+ <p>Searching for "<strong>P1-3</strong>" will find [% terms.bugs %] in
+ any of the three highest priorities, and so on.</p>
+ </td>
+ </tr>
+ <tr>
+ <td class="field_name">[% field_descs.assigned_to FILTER html %]</td>
+ <td class="field_nickname"><strong>@</strong><em>value</em></td>
+ </tr>
+ <tr>
+ <td class="field_name">[% field_descs.product FILTER html %] or
+ [%+ field_descs.component FILTER html %]</td>
+ <td class="field_nickname"><strong>:</strong><em>value</em></td>
+ </tr>
+ [% IF use_keywords %]
+ <tr>
+ <td class="field_name">[% field_descs.keywords FILTER html %]</td>
+ <td class="field_nickname"><strong>!</strong><em>value</em></td>
+ </tr>
+ [% END %]
+ <tr>
+ [% SET key = "flagtypes.name" %]
+ <td class="field_name">[% field_descs.$key FILTER html %]</td>
+ <td class="field_nickname">
+ <em>flag</em><strong>?</strong><em>requestee</em>
+ </td>
+ </tr>
+ <tr>
+ <td class="field_name">[% field_descs.longdesc FILTER html %]
+ or [% field_descs.short_desc FILTER html %]</td>
+ <td class="field_nickname">
+ <strong>#</strong><em>value</em>
+ </td>
+ </tr>
+ [% IF Param('usestatuswhiteboard') %]
+ <tr>
+ <td class="field_name">[% field_descs.short_desc FILTER html %]
+ or [% field_descs.status_whiteboard FILTER html %]</td>
+ <td class="field_nickname"><strong>[</strong><em>value</em></td>
+ </tr>
+ [% END %]
+ </tbody>
+</table>
+
+<h2 id="advanced_examples">Examples of Complex Queries</h2>
+
+<p>It is pretty easy to write rather complex queries without too much effort.
+ For very complex queries, you have to use the
+ <a href="query.cgi?format=advanced">Advanced Search</a> form.</p>
+
+<ul class="qs_help">
+ <li>All [% terms.bugs %] reported by userA@company.com or assigned to him
+ (the initial @ is a shortcut for the assignee, see the
+ <a href="#shortcuts">Advanced Shortcuts</a> section above):<br>
+ <kbd>ALL @userA@company.com OR reporter:userA@company.com</kbd></li>
+ <li>All open [% terms.bugs %] in product productA with either severity
+ blocker, critical or major, or with priority P1, or with the blocker+
+ flag set, and which are neither assigned to userB@company.com nor to
+ userC@company.com (we make the assumption that there are only two users
+ matching userB and userC, else we would write the whole login name):<br>
+ <kbd>:productA sev:blocker,critical,major OR pri:P1 OR flag:blocker+ -assign:userB,userC</kbd></li>
+ <li>All FIXED [% terms.bugs %] with the blocker+ flag set, but without
+ the approval+ nor approval? flags set:<br>
+ <kbd>FIXED flag:blocker+ -flag:approval+ -flag:approval?</kbd></li>
+ <li>[% terms.Bugs %] with <em>That's a "unusual" issue</em> in the
+ [%+ terms.bug %] summary (double quotes are escaped using <em>\"</em>):<br>
+ <kbd>summary:"That's a \"unusual\" issue"</kbd></li>
+</ul>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/pages/release-notes.html.tmpl b/template/en/default/pages/release-notes.html.tmpl
new file mode 100644
index 0000000..dfd5c64
--- /dev/null
+++ b/template/en/default/pages/release-notes.html.tmpl
@@ -0,0 +1,2349 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% SET title = "$terms.Bugzilla 4.4 Release Notes" %]
+[% INCLUDE global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/page.css']
+%]
+
+<h1>[% title FILTER html %]</h1>
+
+<ul class="bz_toc">
+ <li><a href="#v44_introduction">Introduction</a></li>
+ <li><a href="#v44_point">Updates in this 4.4.x Release</a></li>
+ <li><a href="#v44_req">Minimum Requirements</a></li>
+ <li><a href="#v44_feat">New Features and Improvements</a></li>
+ <li><a href="#v44_issues">Outstanding Issues</a></li>
+ <li><a href="#v44_upgrading">Notes On Upgrading From a Previous Version</a></li>
+ <li><a href="#v44_code_changes">Code Changes Which May Affect
+ Customizations and Extensions</a></li>
+ <li><a href="#v44_previous">Release Notes for Previous Versions</a></li>
+</ul>
+
+<h2 id="v44_introduction">Introduction</h2>
+
+<p>Welcome to [% terms.Bugzilla %] 4.4! It has been over a year since we
+ released [% terms.Bugzilla %] 4.2 on February 2012, and this new major
+ release comes with several new features and improvements. This release
+ contains major improvements to WebServices, which were our main target in
+ this release, a rewritten tagging system, a real MIME type auto-detection for
+ attachments, improved support for Oracle, performance improvements and lots
+ of other enhancements.</p>
+
+<p>If you're upgrading, make sure to read <a href="#v44_upgrading">Notes On
+ Upgrading From a Previous Version</a>. If you are upgrading from a release
+ before 4.2, make sure to read the release notes for all the
+ <a href="#v44_previous">previous versions</a> in between your version and
+ this one, <strong>particularly the Upgrading section of each version's
+ release notes</strong>.</p>
+
+<h2 id="v44_point">Updates in this 4.4.x Release</h2>
+
+<h3>4.4.4</h3>
+
+<p>This release fixes one regression introduced in [% terms.Bugzilla %] 4.4.3 by
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=968576">security [% terms.bug %] 968576</a>:
+ URLs in [% terms.bug %] comments are displayed correctly again.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=998323">[% terms.Bug %] 998323</a>)</p>
+
+<h3>4.4.3</h3>
+
+<p>This release fixes two security issues. See the
+ <a href="http://www.bugzilla.org/security/4.0.11/">Security Advisory</a>
+ for details.</p>
+
+<p>In addition, the following important fixes/changes have been made in this release:</p>
+
+<ul>
+ <li>The <kbd>User.login</kbd> WebService method now also returns a
+ <kbd>token</kbd> argument containing a login token which you can use in
+ subsequent calls to authenticate. For security reasons, this method
+ no longer generates login cookies.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=893195">[% terms.Bug %] 893195</a>)</li>
+ <li>The <kbd>User.get</kbd> WebService method now correctly takes the
+ <kbd>maxusermatches</kbd> parameter into account when the <kbd>match</kbd>
+ argument is passed. Previously, it was returning all matching accounts.
+ To further limit the number of accounts returned by <kbd>User.get</kbd>,
+ you can now pass the <kbd>limit</kbd> argument.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=962060">[% terms.Bug %] 962060</a>)</li>
+ <li>The sudo cookie is no longer accessible from JavaScript.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=966676">[% terms.Bug %] 966676</a>)</li>
+ <li>Large dependency trees with lots of resolved [% terms.bugs %] now load
+ much faster.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=961789">[% terms.Bug %] 961789</a>)</li>
+</ul>
+
+<h3>4.4.2</h3>
+
+<p>The following [% terms.bugs %] have been fixed in this release:</p>
+
+<ul>
+ <li><kbd>checksetup.pl</kbd> was incorrectly reporting DBI 1.630 (1.63) as
+ being older than 1.614, preventing the upgrade to complete.
+ If you still use Perl 5.10.0 or older, make sure you have the
+ <a href="http://search.cpan.org/~jpeacock/version/lib/version.pod">version</a>
+ module installed before running <kbd>checksetup.pl</kbd>.
+ If you use Perl 5.10.1 or newer, this module is already available and
+ no special action is required.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=938300">[% terms.Bug %] 938300</a>)</li>
+ <li>An error about <kbd>longdescs.comment_id</kbd> was thrown by MySQL 5.0
+ and 5.1 when upgrading to [% terms.Bugzilla %] 4.4 or 4.4.1.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=870369">[% terms.Bug %] 870369</a>)</li>
+ <li>Saved searches containing Unicode characters in their name could not
+ be run if Digest::SHA 5.82 or newer is installed.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=964113">[% terms.Bug %] 964113</a>)</li>
+ <li>A regression in [% terms.Bugzilla %] 4.4.1 caused <kbd>email_in.pl</kbd>
+ to fail with an "invalid token" error message.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=928331">[% terms.Bug %] 928331</a> and
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=930013">[% terms.bug %] 930013</a>)</li>
+ <li>The PROJECT environment variable is now correctly taken into account
+ when mod_perl is enabled (this variable allows several installations to
+ share the same codebase).
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=843457">[% terms.Bug %] 843457</a>)</li>
+ <li>Mandatory custom fields whose visibility depends on a component are now
+ correctly required on [% terms.bug %] creation.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=895813">[% terms.Bug %] 895813</a>)</li>
+ <li>Windows 8.1 is now recognized when reporting new [% terms.bugs %].
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=928092">[% terms.Bug %] 928092</a>)</li>
+ <li>[% terms.Bugzilla %] no longer crashes when the <kbd>shutdownhtml</kbd>
+ parameter is set and using a non-cookie based authentication method.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=748095">[% terms.Bug %] 748095</a>)</li>
+ <li><kbd>importxml.pl</kbd> no longer ignores the <kbd>maxattachmentsize</kbd>
+ and <kbd>maxlocalattachment</kbd> parameters when importing [% terms.bugs %].
+ This means that large attachments are now stored locally in
+ <kbd>data/attachments/</kbd> if parameters are configured this way.
+ The script must now be run as the webserver user (e.g. apache) to make these
+ attachments readable from web browsers.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=360231">[% terms.Bug %] 360231</a>)</li>
+ <li>The default date and time format used for SQLite has been fixed.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=938161">[% terms.Bug %] 938161</a>)</li>
+</ul>
+
+<h3>4.4.1</h3>
+
+<p>This release fixes several security issues. See the
+ <a href="http://www.bugzilla.org/security/4.0.10/">Security Advisory</a>
+ for details.</p>
+
+<p>In addition, the following [% terms.bugs %] have been fixed in this release:</p>
+
+<ul>
+ <li><kbd>checksetup.pl</kbd> no longer fails with "Invalid version format (non-numeric data)"
+ when a Perl module contains an invalid version number.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=781672">[% terms.Bug %] 781672</a>)</li>
+ <li>Internet Explorer 11 and KHTML-based browsers such as Konqueror can now
+ display buglists correctly.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=902515">[% terms.Bug %] 902515</a> and
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=914262">[% terms.bug %] 914262</a>)</li>
+ <li>When editing several [% terms.bugs %] at once and moving them into a new
+ product, [% terms.bugs %] restricted to a group in the old product could
+ loose these group restrictions in the new product.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=769134">[% terms.Bug %] 769134</a>)</li>
+ <li>When the <kbd>password_complexity</kbd> parameter was set to
+ 'letters_numbers_specialchars', passwords containing numbers and special
+ characters only were accepted. Now it makes sure that a letter is also present.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=897264">[% terms.Bug %] 897264</a>)</li>
+ <li>Large dependency trees are now displayed much faster.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=917370">[% terms.Bug %] 917370</a>)</li>
+ <li>When a user has set many votes, the "Votes" page is now displayed much faster.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=851267">[% terms.Bug %] 851267</a>)</li>
+ <li>The "My Requests" page now correctly uses the AND/OR operator for the
+ requester and requestee fields only instead of using it for all fields.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=891311">[% terms.Bug %] 891311</a>)</li>
+ <li>With DB servers doing case-insensitive comparisons, such as MySQL, tokens
+ and login cookies were not correctly validated as the case was ignored.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=906745">[% terms.Bug %] 906745</a> and
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=907438">[% terms.bug %] 907438</a>)</li>
+ <li>All security headers (such as X-Frame-Options) are now returned when using XML-RPC.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=787328">[% terms.Bug %] 787328</a>)</li>
+ <li>Oracle crashed when reporting a new [% terms.bug %] if a custom free-text field
+ was non-mandatory and left empty.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=919475">[% terms.Bug %] 919475</a>)</li>
+ <li>It was not possible to import [% terms.bugs %] using <kbd>importxml.pl</kbd> with Oracle.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=848063">[% terms.Bug %] 848063</a>)</li>
+</ul>
+
+<h2 id="v44_req">Minimum Requirements</h2>
+
+<p>Any requirements that are new since 4.2 will look like
+ <span class="req_new">this</span>.</p>
+
+<ul>
+ <li><a href="#v44_req_perl">Perl</a></li>
+ <li><a href="#v44_req_mysql">For MySQL Users</a></li>
+ <li><a href="#v44_req_pg">For PostgreSQL Users</a></li>
+ <li><a href="#v44_req_oracle">For Oracle Users</a></li>
+ <li><a href="#v44_req_sqlite">For SQLite Users</a></li>
+ <li><a href="#v44_req_modules">Required Perl Modules</a></li>
+ <li><a href="#v44_req_optional_mod">Optional Perl Modules</a></li>
+ <li><a href="#v44_req_apache">Optional Apache Modules</a></li>
+</ul>
+
+<h3 id="v44_req_perl">Perl</h3>
+
+<p>Perl v5.8.1</p>
+
+<p><strong>IMPORTANT:</strong> This is the last major release to support
+ Perl 5.8.x! The next major release, [% terms.Bugzilla %] 5.0, will require
+ Perl 5.10.1 as a minimum.</p>
+
+[% INCLUDE db_req db='mysql' %]
+
+[% INCLUDE db_req db='pg' dbd_new => 1 %]
+
+[% INCLUDE db_req db='oracle' %]
+
+[% INCLUDE db_req db='sqlite' %]
+
+<h3 id="v44_req_modules">Required Perl Modules</h3>
+
+[% INCLUDE req_table reqs = REQUIRED_MODULES
+ updated = ['TimeDate', 'DBI', 'Email-Send', 'List-MoreUtils'] %]
+
+<h3 id="v44_req_optional_mod">Optional Perl Modules</h3>
+
+<p>The following perl modules, if installed, enable various
+ features of [% terms.Bugzilla %]:</p>
+
+[% INCLUDE req_table reqs = OPTIONAL_MODULES
+ new = ['Net-SMTP-SSL', 'HTML-FormatText-WithLinks',
+ 'File-MimeInfo', 'IO-stringy']
+ updated = ['TheSchwartz']
+ include_feature = 1 %]
+
+<h3 id="v44_req_apache">Optional Apache Modules</h3>
+
+<p>If you are using Apache as your webserver, [% terms.Bugzilla %] can
+ take advantage of some Apache features if you have the below Apache
+ modules installed and enabled. Currently,
+ <a href="#v40_feat_js_css_update">certain [% terms.Bugzilla %] features</a>
+ are enabled only if you have all of the following modules installed
+ and enabled:</p>
+
+<ul>
+ <li>mod_headers</li>
+ <li>mod_expires</li>
+ <li>mod_env</li>
+</ul>
+
+<p>On most systems (but not on Windows), <kbd>checksetup.pl</kbd> is able to
+ tell whether or not you have these modules installed, and it will tell
+ you.</p>
+
+
+<h2 id="v44_feat">New Features and Improvements</h2>
+
+<ul>
+ <li><a href="#v44_feat_search">Allow Multiple Search Criteria to Match one Field</a></li>
+ <li><a href="#v44_feat_search_perf">Improved Performance for Searches</a></li>
+ <li><a href="#v44_feat_bug_tags">Overhaul of the Tagging System</a></li>
+ <li><a href="#v44_feat_mimetype_autodetect">Auto-Detection of the Attachment MIME Type</a></li>
+ <li><a href="#v44_feat_saved_reports">Saving Tabular and Graphical Reports</a></li>
+ <li><a href="#v44_feat_whining">Custom Columns in Whine Emails</a></li>
+ <li><a href="#v44_feat_webservices">Improved WebServices</a></li>
+ <li><a href="#v44_feat_apache_config">New Apache Configuration</a></li>
+ <li><a href="#v44_feat_other">Other Enhancements and Changes</a></li>
+</ul>
+
+<h3 id="v44_feat_search">Allow Multiple Search Criteria to Match one Field</h3>
+
+<p>
+ In the "Advanced Search" page, it is now possible to build queries using
+ multiple custom search criteria against the same field. In [% terms.Bugzilla %]
+ 4.2 and older, queries of the form
+ <br><br>
+ <kbd>"Status changed to VERIFIED" AND "Status changed by foo@bar.com"</kbd>
+ <br><br>
+ were returning all [% terms.bugs %] which had their status changed to VERIFIED
+ by some user and which were edited by foo@bar.com once, but both actions could
+ be independent. In [% terms.Bugzilla %] 4.4, you can now decide if both
+ criteria must match the exact same action or not, i.e. if you want
+ [%+ terms.bugs %] whose status has been set to VERIFIED by foo@bar.com himself.
+ In the same way, queries of the form
+ <br><br>
+ <kbd>"Flags changed to approval+" AND "Flags changed by foo@bar.com"</kbd>
+ <br><br>
+ can now return [% terms.bugs %] for which the approval flag has been set to
+ "+" by foo@bar.com himself. In previous versions, both actions were treated
+ independently and [% terms.bugs %] for which foo@bar.com set the approval flag
+ to "?" and which is then set to "+" by someone else were also returned.
+</p>
+<p>
+ This new feature gives you the ability to build more accurate queries and to
+ get more relevant results.
+</p>
+
+<h3 id="v44_feat_search_perf">Improved Performance for Searches</h3>
+
+<p>
+ The search system got a performance boost which in some cases decreases the
+ time spent to run queries from several minutes to a few seconds only.
+ The more complex your queries are, the more visible the performance win
+ should be.
+</p>
+
+<h3 id="v44_feat_bug_tags">Overhaul of the Tagging System</h3>
+
+<p>
+ The old tagging system which was in the footer of all pages had severe design
+ and usability limitations and has been replaced by a shiny new one which lets
+ you tag [% terms.bugs %] from the [% terms.bug %] report directly. Tags now
+ mostly work like keywords, but with two major differences. First of all, they
+ are personal, meaning that tags you set on [% terms.bugs %] are only visible
+ by you, and nobody else is notified nor can see which tags you set. This
+ behavior is the same as the old tagging system and so this feature didn't
+ change. The second major difference is that the list of available tags is
+ unlimited and is in no way hardcoded by administrators. You can type either
+ a new tag of your choice, or you can select one from an auto-generated list
+ of tags which you already used in other [% terms.bugs %]. Again, this feature
+ was already present in the old tagging system, but its usability has been
+ greatly improved. In particular, this means that tags are now displayed in
+ [%+ terms.bug %] reports directly, so that you immediately know which tags
+ you already set for that [% terms.bug %]. This feature is new in this release.
+</p>
+<p>
+ Another new feature is that your personal tags can now be listed in buglists.
+ They can also be used as search criteria in your queries. If you decide to
+ share a saved search which uses tags as criteria, this will work too! Note
+ that when you add a new tag, no saved search based on this tag is created
+ anymore, as you can easily create it yourself if you really need it.
+</p>
+<p>
+ The tags set with the old tagging system are automatically migrated to the
+ new system.
+</p>
+
+<h3 id="v44_feat_mimetype_autodetect">Auto-Detection of the Attachment MIME Type</h3>
+
+<p>
+ When a user uploads a new attachment and lets the "Content Type" field set to
+ "auto-detect", [% terms.Bugzilla %] now does its own MIME type detection
+ if the web browser tells him that the attachment is of type
+ "application/octet-stream", in an attempt to make a better guess than the web
+ browser. In all other cases, [% terms.Bugzilla %] still trusts what the browser
+ tells him.
+</p>
+<p>
+ Check the <a href="#v44_req_optional_mod">list of optional Perl modules</a> to
+ know which modules to install in order to enable MIME type sniffing.
+</p>
+
+<h3 id="v44_feat_saved_reports">Saving Tabular and Graphical Reports</h3>
+
+<p>
+ It is now possible to save tabular and graphical reports in the same way as
+ you save searches. Saved reports will appear in the footer of pages, below
+ saved searches.
+</p>
+<p>
+ Unlike saved searches, it is not yet possible to share saved reports with
+ other users.
+</p>
+
+<h3 id="v44_feat_whining">Custom Columns in Whine Emails</h3>
+
+<p>
+ The list of columns to display in buglists contained in emails sent by the
+ whining system on a regular basis is no longer hardcoded. If the saved
+ search used for whining emails contains a list of columns, these columns are
+ used to be displayed in the emails. If no custom list is found, the default
+ column list is used instead.
+</p>
+<p>
+ This means that depending on the kind of email notifications you want, you
+ can fully customize data to return, on a per saved search basis!
+</p>
+
+<h3 id="v44_feat_webservices">Improved WebServices</h3>
+
+<p>
+ This release got major improvements in its WebServices interface. Many new
+ methods have been implemented to let third-party applications interact with
+ [%+ terms.Bugzilla %] even more closely. For instance, it is now possible to
+ know what parameters are set to using <kbd>B[%%]ugzilla.parameters</kbd>.
+ It is now also possible to update tags, products, groups or user accounts
+ using our API.
+<p>
+<p>
+ Several existing methods have also been improved to return data which
+ weren't available till now, such as [% terms.bug %] and attachment flags
+ using <kbd>B[%%]ug.get</kbd>, <kbd>B[%%]ug.attachments</kbd> or
+ <kbd>Product.get</kbd>. Users can also get their saved searches and reports
+ using <kbd>User.get</kbd>; and much more, see the
+ <a href="#v44_feat_webservices_details">detailed list</a> below.
+</p>
+
+<h3 id="v44_feat_apache_config">New Apache Configuration</h3>
+
+<p>
+ For improved security, [% terms.Bugzilla %] now prevents directory browsing
+ by default. If you run [% terms.Bugzilla %] under Apache (as most people do),
+ you most likely require a <strong>new Apache configuration</strong> for this
+ version of [% terms.Bugzilla %]. See the
+ <a href="#v44_upgrading">Notes On Upgrading From a Previous Version</a>
+ section for details.
+</p>
+
+<h3 id="v44_feat_other">Other Enhancements and Changes</h3>
+
+<h4>Enhancements for Users</h4>
+
+<ul>
+ <li><strong>[% terms.Bugs %]:</strong> It is now possible to add yourself to
+ the CC list when uploading an attachment and when editing an existing one.</li>
+ <li><strong>[% terms.Bugs %]:</strong> There is a new user preference to be
+ automatically added to the CC list of [% terms.bugs %] for which a flag
+ request is addressed to you (the flag has you as the requestee).</li>
+ <li><strong>[% terms.Bugs %]:</strong> Changes to the CC list no longer
+ causes midair collisions.</li>
+ <li><strong>[% terms.Bugs %]:</strong> There is now a <em>(take)</em> link
+ besides the QA Contact field to easily set yourself as QA contact.</li>
+ <li><strong>[% terms.Bugs %]:</strong> [% terms.Bugs %] are no longer
+ reassigned to the default assignee when moving the [% terms.bug %] into
+ another product or component if the current assignee is not the default
+ one. Same goes for the QA contact.</li>
+ <li><strong>[% terms.Bugs %]:</strong> When reporting a new [% terms.bug %],
+ flags which are not available for the selected component and those which
+ the reporter cannot edit are now hidden instead of being disabled. For
+ existing [% terms.bugs %], unset flags are also hidden by default. Clicking
+ the <em>(set flags)</em> or <em>(more flags)</em> link will make them
+ appear.</li>
+ <li><strong>[% terms.Bugs %]:</strong> When viewing [% terms.abug %], the list
+ of duplicated [% terms.bugs %] is now listed near the top of the page.</li>
+ <li><strong>[% terms.Bugs %]:</strong> Private comments now always remain
+ visible to their author. Previously, the author of a comment couldn't see
+ it anymore if the comment was marked private and the author isn't in the
+ insider group.</li>
+ <li><strong>[% terms.Bugs %]:</strong> The See Also field now supports URLs
+ pointing to GitHub by default. If the new MoreBugUrl extension included in
+ this release is enabled, then you can also add URLs pointing to:
+ b[%%]ugs.php.net, RT, appspot.com (Rietveld), Review Board, and
+ getsatisfaction.com.</li>
+ <li><strong>Searches:</strong> The alias of [% terms.bugs %] you cannot see
+ are no longer resolved to their [% terms.bug %] ID, meaning that it is no
+ longer possible to connect an alias with its ID unless you can see the
+ [%+ terms.bug %].</li>
+ <li><strong>Searches:</strong> Custom multi-select fields are now available
+ in the "Search By Change History" section of the query page.</li>
+ <li><strong>Searches:</strong> The <em>changed by</em> operator in boolean
+ charts now accepts pronouns.</li>
+ <li><strong>Searches:</strong> The requester and requestee fields in boolean
+ charts now accept pronouns.</li>
+ <li><strong>Searches:</strong> It is now possible to hide the description of
+ queries appearing at the top of buglists.</li>
+ <li><strong>Requests:</strong> The "My Requests" page now displays an AND/OR
+ radio button to define the interaction between the requester and requestee
+ fields.</li>
+ <li><strong>Email Notifications:</strong> There is a new user preference to
+ not prepend "New:" to the subject of [% terms.bug %]mails when reporting
+ a new [% terms.bug %]. Some email clients couldn't thread emails correctly
+ due to this.</li>
+ <li><strong>Email Notifications:</strong> There is a new email event to get
+ notifications when the product or component of [% terms.abug %] changes.</li>
+ <li><strong>Email Notifications:</strong> All [% terms.bug %]mails now have
+ a <em>X-Bugzilla-Flags</em> email header, listing currently set flags.</li>
+ <li><strong>Email Notifications:</strong> All [% terms.bug %]mails now have
+ a <em>X-Bugzilla-Version</em> email header with the current product
+ version.</li>
+ <li><strong>Whining:</strong> The sort order of the saved search is used to
+ sort [% terms.bugs %] in the emails.</li>
+ <li><strong>User Accounts:</strong> To confirm an email address change, the
+ password is now requested instead of the old email address.</li>
+ <li><strong>Graphical Reports:</strong> The size of graphical reports is now
+ set dynamically to fit within the window of the web browser.
+ The Taller/Thinner/Fatter/Shorter links are now gone.</li>
+ <li><strong>Incoming Emails:</strong> <kbd>email_in.pl</kbd> now accepts
+ HTML-only emails to create and edit [% terms.bugs %] by email.</li>
+ <li><strong>Incoming Emails:</strong> When creating a new [% terms.bug %],
+ <kbd>email_in.pl</kbd> will look at the <em>Importance</em> and
+ <em>X-Priority</em> email headers to increase or decrease the initial
+ priority of the [% terms.bug %], unless the priority is already explicitly
+ set in the email itself.</li>
+ <li><strong>Skins:</strong> [% terms.Bugzilla %] no longer fetches all skins
+ available when viewing a page. It only loads the skin selected by the user
+ in his preferences, which results in less requests to the server.</li>
+</ul>
+
+<h4>Enhancements for Administrators and Developers</h4>
+
+<ul>
+ <li><strong>License:</strong> The [% terms.Bugzilla %] code is now released
+ under the MPL 2.0 license (previously was MPL 1.1).</li>
+ <li><strong>Installation:</strong> On mod_perl, templates now remain in
+ memory for one hour, which can cause an increase in memory requirements.
+ This also means that it can take up to one hour before changes in templates
+ become active (unless you restart Apache).</li>
+ <li><strong>Installation:</strong> Running
+ <kbd>checksetup.pl --make-admin=foo@bar.com</kbd> now automatically
+ re-enables the user account if it was disabled.</li>
+ <li><strong>Configuration:</strong> A new parameter <em>smtp_ssl</em> can be
+ turned on to enable SSL connections to the SMTP server to send email
+ notifications.</li>
+ <li><strong>Administration:</strong> Custom fields now have a new <em>Long
+ description</em> attribute to better describe what the custom field is
+ about. This description then appears as a tooltip when hovering the custom
+ field in [% terms.bug %] reports.</li>
+ <li><strong>Administration:</strong> When creating a new product, the form
+ lets you add a component at the same time.</li>
+ <li><strong>Administration:</strong> When viewing a user account in
+ <kbd>editusers.cgi</kbd>, the date of the last login is displayed. Users
+ who did not log in since you upgraded to 4.4 will have this field empty.</li>
+ <li><strong>Administration:</strong> It is now possible to exclude disabled
+ user accounts when running a query in <kbd>editusers.cgi</kbd>.</li>
+ <li><strong>Administration:</strong> The default CC list is now also displayed
+ when listing components in <kbd>editcomponents.cgi</kbd>.</li>
+ <li><strong>Administration:</strong> Target milestones can now be 64 characters
+ long, for consistency with versions (previously was limited to 20 characters
+ only).</li>
+ <li><strong>Administration:</strong> The result code returned by
+ <kbd>contrib/bugzilla-queue.rhel</kbd> when it's not running is now 2
+ instead of 0.</li>
+ <li><strong>Database:</strong> Support for MySQL 5.6 has been added.</li>
+ <li><strong>Database:</strong> Support for Oracle has been greatly improved.</li>
+ <li><strong>Security:</strong> For improved security, the
+ "X-Content-Type-Options:&nbsp;nosniff" and "X-XSS-Protection:&nbsp;block"
+ headers are now sent with every response.</li>
+ <li><strong>Security:</strong> Tokens are now generated using HMAC SHA-256
+ instead of MD5.</li>
+ <li><strong>Documentation:</strong> The documentation is now generated with
+ <kbd>xmlto</kbd> and <kbd>dblatex</kbd> instead of <kbd>jade</kbd>.</li>
+</ul>
+
+<h4 id="v44_feat_webservices_details">WebService Changes</h4>
+
+<ul>
+ <li>Several new methods have been added: <kbd>B[%%]ug.update_tags</kbd>,
+ <kbd>B[%%]ugzilla.parameters</kbd>, <kbd>B[%%]ugzilla.last_audit_time</kbd>,
+ <kbd>Classification.get</kbd>, <kbd>Group.update</kbd>,
+ <kbd>Product.update</kbd>, <kbd>User.update</kbd>.</li>
+ <li><kbd>B[%%]ug.add_attachment</kbd> now only returns the ID of the newly
+ created attachments instead of all the attachment data.</li>
+ <li><kbd>B[%%]ug.attachments</kbd> now also returns the <kbd>size</kbd> field
+ containing the size of the attachment.</li>
+ <li><kbd>B[%%]ug.attachments</kbd> and <kbd>B[%%]ug.get</kbd> now return
+ data about flags.</li>
+ <li><kbd>B[%%]ug.comments</kbd> now also returns <kbd>creation_time</kbd>
+ which is exactly the same as <kbd>time</kbd>, but is provided for
+ consistency with <kbd>B[%%]ug.get</kbd> and <kbd>B[%%]ug.attachments</kbd>.
+ The <kbd>time</kbd> field may be deprecated and removed in a future release,
+ so you should use <kbd>creation_time</kbd> instead.</li>
+ <li><kbd>B[%%]ug.comments</kbd> now also returns the <kbd>count</kbd> field
+ containing the comment ID relative to the [% terms.bug %] it belongs to.
+ This is the same comment ID as the one you can see in [% terms.bug %]
+ reports.</li>
+ <li>It is now possible to create new [% terms.bugs %] with a closed status with
+ <kbd>B[%%]ug.create</kbd>.</li>
+ <li>The <kbd>bug_status</kbd> field returned by <kbd>B[%%]ug.fields</kbd> now
+ also includes [% terms.bug %] statuses available on [% terms.bug %] creation.</li>
+ <li><kbd>B[%%]ug.fields</kbd> now also returns keyword descriptions, not only
+ their names.</li>
+ <li><kbd>B[%%]ug.fields</kbd> now also returns the <kbd>is_active</kbd> field
+ for product-specific fields.</li>
+ <li>For users in the timetracking group, <kbd>B[%%]ug.get</kbd> now also
+ returns the <kbd>actual_time</kbd> field with the total number of hours
+ spent in the [% terms.bug %].</li>
+ <li>Field names returned in the <kbd>field_name</kbd> field of the
+ <kbd>B[%%]ug.history</kbd> method have changed to be consistent with other
+ methods.</li>
+ <li>The <kbd>B[%%]ug.search</kbd> method was returning all visible [% terms.bugs %]
+ when called with no arguments, ignoring the <kbd>max_search_results</kbd>
+ and <kbd>search_allow_no_criteria</kbd> parameters. This has been fixed.</li>
+ <li><kbd>Product.get</kbd> now also returns the <kbd>flag_types</kbd> field
+ containing all the relevant data for attachment and [% terms.bug %] flag types.</li>
+ <li><kbd>Product.get</kbd> now throws an error if neither <kbd>ids</kbd> nor
+ <kbd>names</kbd> is passed to the method.</li>
+ <li>When requesting data for your own account using <kbd>User.get</kbd>,
+ this method now returns two additional fields: <kbd>saved_searches</kbd>
+ and <kbd>saved_reports</kbd> containing all your saved searches and
+ graphical and tabular reports.</li>
+ <li><kbd>User.get</kbd> now also returns the <kbd>groups</kbd> field
+ containing the list of groups the user belongs to. The list is filtered
+ based on your privileges.</li>
+</ul>
+
+
+<h2 id="v44_issues">Outstanding Issues</h2>
+
+<ul>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=89822">
+ [%- terms.Bug %] 89822</a>: When changing multiple [% terms.bugs %] at
+ the same time, there is no "mid-air collision" protection.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=276230">
+ [%- terms.Bug %] 276230</a>: The support for restricting access to
+ particular Categories of New Charts is not complete. You should treat the
+ <em>chartgroup</em> parameter as the only access mechanism available.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=584742">
+ [%- terms.Bug %] 584742</a>: When viewing [% terms.abug %], WebKit-based
+ browsers can automatically reset a field's selected value when the field
+ has disabled values.</li>
+</ul>
+
+
+<h2 id="v44_upgrading">Notes On Upgrading From a Previous Version</h2>
+
+<h3>IMPORTANT: Apache Configuration Change</h3>
+
+<p>
+ For improved security, [% terms.Bugzilla %] now prevents directory browsing
+ by default. In order to do that, the root <kbd>bugzilla/.htaccess</kbd> file
+ now contains the <kbd>Options -Indexes</kbd> directive. By default, this
+ directive is not allowed in <kbd>.htaccess</kbd> and so you must configure
+ Apache to allow it. To do that, add <kbd>Options</kbd> to the
+ <kbd>AllowOverride</kbd> directive in <kbd>httpd.conf</kbd>. This means you
+ should now have something like this:
+ <p>
+ <kbd>AllowOverride Limit FileInfo Indexes Options</kbd>
+ </p>
+ Check the
+ <a href="http://www.bugzilla.org/docs/4.4/en/html/configuration.html#http-apache">documentation</a>
+ for more information about how to configure Apache.
+</p>
+
+<h2 id="v44_code_changes">Code Changes Which May Affect Customizations and Extensions</h2>
+
+<ul>
+ <li>The <em>usebugaliases</em> parameter has been removed. Aliases are now
+ always available.</li>
+ <li>There is a new code hook <kbd>admin_editusers_action</kbd> to alter the
+ way <kbd>editusers.cgi</kbd> works.</li>
+ <li>There is a new code hook <kbd>buglist_column_joins</kbd> to alter the way
+ tables and columns are joined in queries. In combination with the
+ <kbd>buglist_columns</kbd> hook, this permits to customize the list of
+ columns to display in buglists.</li>
+ <li>There is a new code hook <kbd>bug_start_of_update</kbd> which is called
+ after <kbd>object_end_of_update</kbd> but before <kbd>bug_end_of_update</kbd>
+ for a better control on how to update [% terms.bugs %].</li>
+ <li>There is a new code hook <kbd>bug_url_sub_classes</kbd> to support
+ additional URLs in the See Also field.</li>
+ <li>There is a new code hook <kbd>error_catch</kbd> to catch errors thrown
+ by [% terms.Bugzilla %] and to take the appropriate actions.</li>
+ <li>There is a new code hook <kbd>path_info_whitelist</kbd> to whitelist
+ scripts which should still get the Path-Info information from URLs. By
+ default, Path-Info is now removed before being passed to CGI scripts.</li>
+ <li>It is now illegal to have a product with no components and no versions.
+ Trying to delete the last component or version of a product is now
+ rejected.</li>
+ <li>Trying to set the component, target milestone or version of [% terms.abug %]
+ to a disabled value is no longer accepted. The change will be rejected.</li>
+ <li>The comment box now checks the returned value of check_can_change_field()
+ to determine if it should be displayed or not. This means its visibility
+ can now be controlled by the <kbd>bug_check_can_change_field</kbd> hook.</li>
+ <li>Flags now checks the returned value of check_can_change_field() to
+ determine if they should appear as editable or not. This means their
+ visibility can now be controlled by the <kbd>bug_check_can_change_field</kbd>
+ hook.</li>
+ <li>Quips can no longer exceed 512 characters. Existing quips longer than
+ that are automatically truncated when upgrading.</li>
+ <li>The static <kbd>bugzilla.dtd</kbd> file has been replaced by a dynamic
+ one to take custom fields into account. The old
+ <em>&lt;urlbase&gt;/bugzilla.dtd</em> URL is now
+ <em>&lt;urlbase&gt;/page.cgi?id=bugzilla.dtd</em>.</li>
+ <li>There is a new extension located at <kbd>extensions/MoreBugUrl/</kbd>
+ which permits to add new classes of URLs in the See Also field. It uses
+ the <kbd>bug_url_sub_classes</kbd> hook mentioned above.</li>
+ <li>There is a new <kbd>B[%%]ugzilla->process_cache</kbd> method to store
+ data which should remain available for the lifetime of the worker process,
+ on mod_perl. On mod_cgi, it behaves the same way as
+ <kbd>B[%%]ugzilla->request_cache</kbd>.</li>
+ <li>In the RDF output of <kbd>config.cgi</kbd>, URIs used to identify
+ versions and target milestones have been changed to be unique across
+ products.</li>
+ <li>The RDF output of <kbd>config.cgi</kbd> now also returns data about
+ classifications.</li>
+ <li>It is now legal to call <kbd>B[%%]ugzilla::Version->check({ id => $id })</kbd>
+ and <kbd>B[%%]ugzilla::Milestone->check({ id => $id })</kbd> to validate
+ and get an object using its ID.</li>
+ <li>Rows in the <kbd>dependencies</kbd>, <kbd>flaginclusions</kbd> and
+ <kbd>flagexclusions</kbd> DB tables are now enforced to be unique.</li>
+ <li>The <kbd>b[%%]ugs_activity</kbd> and <kbd>profiles_activity</kbd> DB
+ tables now have an auto-incremented primary key named <kbd>id</kbd>.</li>
+ <li>A custom <kbd>B[%%]ugzilla.pm</kbd> module has been added into
+ <kbd>contrib/</kbd> to help packagers to package B[%%]ugzilla in their
+ Linux distros.</li>
+</ul>
+
+
+<h1 id="v44_previous">[% terms.Bugzilla %] 4.2 Release Notes</h1>
+
+<ul class="bz_toc">
+ <li><a href="#v42_introduction">Introduction</a></li>
+ <li><a href="#v42_point">Updates in this 4.2.x Release</a></li>
+ <li><a href="#v42_req">Minimum Requirements</a></li>
+ <li><a href="#v42_feat">New Features and Improvements</a></li>
+ <li><a href="#v42_issues">Outstanding Issues</a></li>
+ <li><a href="#v42_code_changes">Code Changes Which May Affect
+ Customizations and Extensions</a></li>
+ <li><a href="#v42_previous">Release Notes for Previous Versions</a></li>
+</ul>
+
+<h2 id="v42_introduction">Introduction</h2>
+
+<p>Welcome to [% terms.Bugzilla %] 4.2! It has been almost a year since we
+ released [% terms.Bugzilla %] 4.0 on February 2011, and this new major
+ release comes with several new features and improvements. This release
+ contains major improvements to search, support for SQLite, improved
+ WebServices, and lots of other enhancements.</p>
+
+<p>If you are upgrading from a release before 4.0, make sure to read the
+ release notes for all the <a href="#v42_previous">previous versions</a>
+ in between your version and this one, <strong>particularly the Upgrading
+ section of each version's release notes</strong>.</p>
+
+<h2 id="v42_point">Updates in this 4.2.x Release</h2>
+
+<h3>4.2.3</h3>
+
+<p>This release fixes two security issues. See the
+ <a href="http://www.bugzilla.org/security/3.6.10/">Security Advisory</a>
+ for details.</p>
+
+<p>In addition, the following important fixes/changes have been made in this
+ release:</p>
+
+<ul>
+ <li>Attaching a file to [% terms.abug %] was broken due to a change in
+ Perl 5.16.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=771100">[% terms.Bug %] 771100</a>)</li>
+ <li>A regression in [% terms.Bugzilla %] 4.2.2 made Oracle crash when
+ displaying a buglist.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=780028">[% terms.Bug %] 780028</a>)</li>
+ <li>It was possible to search on history for comments and attachments you
+ cannot see (though these private comments and attachments are never disclosed).
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=779709">[% terms.Bug %] 779709</a>)</li>
+ <li>PostgreSQL databases could be created with the wrong encoding despite
+ the utf8 parameter being enabled.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=783786">[% terms.Bug %] 783786</a>)</li>
+ <li>Scheduled whines could be sent at the wrong time on Oracle.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=559539">[% terms.Bug %] 559539</a>)</li>
+ <li>Tokens are no longer included in saved queries.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=772953">[% terms.Bug %] 772953</a>)</li>
+ <li>An admin could unintentionally break the display of buglists if a custom
+ field description contains a &lt; or &gt; character, because these characters
+ were not filtered.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=785917">[% terms.Bug %] 785917</a>)</li>
+ <li>Adding or removing a DB column in Oracle didn't handle SERIAL columns
+ correctly.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=731156">[% terms.Bug %] 731156</a>)</li>
+ <li>A minor CSRF vulnerability in token.cgi allowed possible unauthorized
+ password reset e-mail requests.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=706271">[% terms.Bug %] 706271</a>)</li>
+</ul>
+
+<h3>4.2.2</h3>
+
+<p>This release fixes two security issues. See the
+ <a href="http://www.bugzilla.org/security/3.6.9/">Security Advisory</a>
+ for details.</p>
+
+<p>In addition, the following important fixes/changes have been made in this
+ release:</p>
+
+<ul>
+ <li>A regression introduced in [% terms.Bugzilla %] 4.0 caused some login
+ names to be ignored when entered in the CC list of [% terms.bugs %].
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=756314">[% terms.Bug %] 756314</a>)</li>
+ <li>Some queries could trigger an invalid SQL query if strings entered by
+ the user contained leading or trailing whitespaces.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=760075">[% terms.Bug %] 760075</a>)</li>
+ <li>The auto-completion form for keywords no longer automatically selects
+ the first keyword in the list when the field is empty.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=764517">[% terms.Bug %] 764517</a>)</li>
+ <li>A regression in [% terms.Bugzilla %] 4.2 prevented classifications
+ from being used in graphical and tabular reports in the "Multiple Tables"
+ field.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=753688">[% terms.Bug %] 753688</a>)</li>
+ <li>Attachments created by the <kbd>email_in.pl</kbd> script were associated
+ to the wrong comment.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=762785">[% terms.Bug %] 762785</a>)</li>
+ <li>Very long dependency lists can now be viewed correctly.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=762783">[% terms.Bug %] 762783</a>)</li>
+ <li>Keywords are now correctly escaped in the auto-completion form to prevent
+ any XSS abuse.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=754561">[% terms.Bug %] 754561</a>)</li>
+ <li>A regression introduced in [% terms.Bugzilla %] 4.0rc2 when fixing
+ CVE-2011-0046 caused the "Un-forget the search" link to not work correctly
+ anymore when restoring a deleted saved search, because this link was
+ lacking a valid token.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=768870">[% terms.Bug %] 768870</a>)</li>
+ <li>Two minor CSRF vulnerabilities have been fixed which could let an attacker
+ alter your default search criteria in the Advanced Search page.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=754672">[% terms.Bugs %] 754672</a>
+ and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=754673">754673</a>)</li>
+</ul>
+
+<h3>4.2.1</h3>
+
+<p>This release fixes one security issue. See the
+ <a href="http://www.bugzilla.org/security/3.6.8/">Security Advisory</a>
+ for details.</p>
+
+<p>In addition, the following important fixes/changes have been made in this
+ release:</p>
+
+<ul>
+ <li>Due to a regression introduced when fixing CVE-2012-0453, if an XML-RPC
+ client sets the charset as part of its Content-Type header, we were
+ incorrectly rejecting the request. The header is now correctly parsed.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=731219">[% terms.Bug %] 731219</a>)</li>
+ <li>Email notifications about status changes in blockers were incorrectly
+ formatted. Several pieces of text were missing in the emails.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=731586">[% terms.Bug %] 731586</a>)</li>
+ <li>Many [% terms.bugs %] related to the searching system have been fixed.
+ (<a href="https://bugzilla.mozilla.org/buglist.cgi?bug_id=58179,715270,730984,731163,737436">
+ [% terms.Bugs %] 58179, 715270, 730984, 731163 and 737436</a>)</li>
+ <li>When using the QuickSearch box, complex queries are now parsed correctly.
+ It also behaves correctly with non-ASCII characters (such as é, ä, ü, etc.).
+ (<a href="https://bugzilla.mozilla.org/buglist.cgi?bug_id=554819,663377,730207">
+ [% terms.Bugs %] 554819, 663377 and 730207</a>)</li>
+ <li>The 'take' link besides the assignee field now works correctly when
+ the <kbd>usemenuforusers</kbd> parameter is turned on.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=734997">[% terms.Bug %] 734997</a>)</li>
+ <li>URLs in the 'Total' row at the bottom of tabular reports were broken
+ when JavaScript was enabled and a user field was used for the vertical
+ axis.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=731323">[% terms.Bug %] 731323</a>)</li>
+ <li>Some performance problems have been fixed for installations with many
+ products, components or versions.
+ (<a href="https://bugzilla.mozilla.org/buglist.cgi?bug_id=695514,731055">
+ [% terms.Bugs %] 695514 and 731055</a>)</li>
+ <li>A new hook named <kbd>buglist_column_joins</kbd> has been added to let
+ extensions alter the <kbd>Bugzilla::Search::COLUMN_JOINS</kbd> hash.
+ Now more fields can be displayed as columns in buglists, in combination
+ with the already existing <kbd>buglist_columns</kbd> hook.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=743991">[% terms.Bug %] 743991</a>)</li>
+ <li>A new hook named <kbd>admin_editusers_action</kbd> has been added to let
+ extensions alter the behavior of <kbd>editusers.cgi</kbd>. This lets you add
+ new features to this script very easily.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=730794">[% terms.Bug %] 730794</a>)</li>
+</ul>
+
+<h2 id="v42_req">Minimum Requirements</h2>
+
+<p>Any requirements that are new since 4.0.2 will look like
+ <span class="req_new">this</span>.</p>
+
+<ul>
+ <li><a href="#v42_req_perl">Perl</a></li>
+ <li><a href="#v42_req_mysql">For MySQL Users</a></li>
+ <li><a href="#v42_req_pg">For PostgreSQL Users</a></li>
+ <li><a href="#v42_req_oracle">For Oracle Users</a></li>
+ <li><a href="#v42_req_sqlite">For SQLite Users</a></li>
+ <li><a href="#v42_req_modules">Required Perl Modules</a></li>
+ <li><a href="#v42_req_optional_mod">Optional Perl Modules</a></li>
+ <li><a href="#v42_req_apache">Optional Apache Modules</a></li>
+</ul>
+
+<h3 id="v42_req_perl">Perl</h3>
+
+<p>Perl v5.8.1</p>
+
+<h3 id="v42_req_mysql">For MySQL Users</h3>
+
+<ul>
+ <li>MySQL <span class="req_new">v5.0.15</span></li>
+ <li><strong>perl module:</strong> DBD::mysql <span class="req_new">v4.001</span></li>
+</ul>
+
+<h3 id="v42_req_pg">For PostgreSQL Users</h3>
+
+<ul>
+ <li>PostgreSQL <span class="req_new">v8.03.0000</span></li>
+ <li><strong>perl module:</strong> DBD::Pg v1.45</li>
+</ul>
+
+<h3 id="v42_req_oracle">For Oracle Users</h3>
+
+<ul>
+ <li>Oracle v10.02.0</li>
+ <li><strong>perl module:</strong> DBD::Oracle v1.19</li>
+</ul>
+
+<h3 id="v42_req_sqlite">For SQLite Users</h3>
+
+<ul>
+ <li>SQLite v3.6.22</li>
+ <li><strong>perl module:</strong> DBD::SQLite v1.29</li>
+</ul>
+
+<h3 id="v42_req_modules">Required Perl Modules</h3>
+
+
+<table class="req_table" border="0" cellpadding="0" cellspacing="0">
+ <tbody>
+ <tr>
+ <th>Module</th>
+ <th>Version</th>
+ </tr>
+ <tr>
+ <td>CGI</td>
+ <td>3.51</td>
+ </tr>
+ <tr>
+ <td>Digest::SHA</td>
+ <td>(Any)</td>
+ </tr>
+ <tr>
+ <td>Date::Format</td>
+ <td>2.21</td>
+ </tr>
+ <tr>
+ <td>DateTime</td>
+ <td>0.28</td>
+ </tr>
+ <tr>
+ <td>DateTime::TimeZone</td>
+ <td>0.71</td>
+ </tr>
+ <tr>
+ <td>DBI</td>
+ <td>1.614</td>
+ </tr>
+ <tr>
+ <td>Template</td>
+ <td>2.22</td>
+ </tr>
+ <tr>
+ <td>Email::Send</td>
+ <td>2.00</td>
+ </tr>
+ <tr>
+ <td>Email::MIME</td>
+ <td>1.904</td>
+ </tr>
+ <tr>
+ <td>URI</td>
+ <td class="req_new">1.37</td>
+ </tr>
+ <tr>
+ <td>List::MoreUtils</td>
+ <td>0.22</td>
+ </tr>
+ <tr>
+ <td class="req_new">Math::Random::ISAAC</td>
+ <td class="req_new">1.0.1</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="v42_req_optional_mod">Optional Perl Modules</h3>
+
+<p>The following perl modules, if installed, enable various
+ features of [% terms.Bugzilla %]:</p>
+
+
+<table class="req_table" border="0" cellpadding="0" cellspacing="0">
+ <tbody>
+ <tr>
+ <th>Module</th>
+ <th>Version</th>
+ <th>Enables Feature</th>
+ </tr>
+ <tr>
+ <td>GD</td>
+ <td>1.20</td>
+ <td>Graphical Reports, New Charts, Old Charts</td>
+ </tr>
+ <tr>
+ <td>Chart::Lines</td>
+ <td>2.1</td>
+ <td>New Charts, Old Charts</td>
+ </tr>
+ <tr>
+ <td>Template::Plugin::GD::Image</td>
+ <td>(Any)</td>
+ <td>Graphical Reports</td>
+ </tr>
+ <tr>
+ <td>GD::Text</td>
+ <td>(Any)</td>
+ <td>Graphical Reports</td>
+ </tr>
+ <tr>
+ <td>GD::Graph</td>
+ <td>(Any)</td>
+ <td>Graphical Reports</td>
+ </tr>
+ <tr>
+ <td>MIME::Parser</td>
+ <td>5.406</td>
+ <td>Move [% terms.Bugs %] Between Installations</td>
+ </tr>
+ <tr>
+ <td>LWP::UserAgent</td>
+ <td>(Any)</td>
+ <td>Automatic Update Notifications</td>
+ </tr>
+ <tr>
+ <td>XML::Twig</td>
+ <td>(Any)</td>
+ <td>Move [% terms.Bugs %] Between Installations, Automatic Update Notifications</td>
+ </tr>
+ <tr>
+ <td>PatchReader</td>
+ <td class="req_new">0.9.6</td>
+ <td>Patch Viewer</td>
+ </tr>
+ <tr>
+ <td>Net::LDAP</td>
+ <td>(Any)</td>
+ <td>LDAP Authentication</td>
+ </tr>
+ <tr>
+ <td>Authen::SASL</td>
+ <td>(Any)</td>
+ <td>SMTP Authentication</td>
+ </tr>
+ <tr>
+ <td>Authen::Radius</td>
+ <td>(Any)</td>
+ <td>RADIUS Authentication</td>
+ </tr>
+ <tr>
+ <td>SOAP::Lite</td>
+ <td>0.712</td>
+ <td>XML-RPC Interface</td>
+ </tr>
+ <tr>
+ <td>JSON::RPC</td>
+ <td>(Any)</td>
+ <td>JSON-RPC Interface</td>
+ </tr>
+ <tr>
+ <td>JSON::XS</td>
+ <td>2.0</td>
+ <td>Make JSON-RPC Faster</td>
+ </tr>
+ <tr>
+ <td>Test::Taint</td>
+ <td>(Any)</td>
+ <td>JSON-RPC Interface, XML-RPC Interface</td>
+ </tr>
+ <tr>
+ <td>HTML::Parser</td>
+ <td>3.67</td>
+ <td>More HTML in Product/Group Descriptions</td>
+ </tr>
+ <tr>
+ <td>HTML::Scrubber</td>
+ <td>(Any)</td>
+ <td>More HTML in Product/Group Descriptions</td>
+ </tr>
+ <tr>
+ <td class="req_new">Encode</td>
+ <td class="req_new">2.21</td>
+ <td>Automatic charset detection for text attachments</td>
+ </tr>
+ <tr>
+ <td class="req_new">Encode::Detect</td>
+ <td class="req_new">(Any)</td>
+ <td>Automatic charset detection for text attachments</td>
+ </tr>
+ <tr>
+ <td>Email::MIME::Attachment::Stripper</td>
+ <td>(Any)</td>
+ <td>Inbound Email</td>
+ </tr>
+ <tr>
+ <td>Email::Reply</td>
+ <td>(Any)</td>
+ <td>Inbound Email</td>
+ </tr>
+ <tr>
+ <td>TheSchwartz</td>
+ <td>(Any)</td>
+ <td>Mail Queueing</td>
+ </tr>
+ <tr>
+ <td>Daemon::Generic</td>
+ <td>(Any)</td>
+ <td>Mail Queueing</td>
+ </tr>
+ <tr>
+ <td>mod_perl2</td>
+ <td>1.999022</td>
+ <td>mod_perl</td>
+ </tr>
+ <tr>
+ <td>Apache2::SizeLimit</td>
+ <td class="req_new">0.96</td>
+ <td>mod_perl</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="v42_req_apache">Optional Apache Modules</h3>
+
+<p>If you are using Apache as your webserver, [% terms.Bugzilla %] can
+ take advantage of some Apache features if you have the below Apache
+ modules installed and enabled. Currently,
+ <a href="#v40_feat_js_css_update">certain [% terms.Bugzilla %] features</a>
+ are enabled only if you have all of the following modules installed
+ and enabled:</p>
+
+<ul>
+ <li>mod_headers</li>
+ <li>mod_expires</li>
+ <li>mod_env</li>
+</ul>
+
+<p>On most systems (but not on Windows), <kbd>checksetup.pl</kbd> is able to
+ tell whether or not you have these modules installed, and it will tell
+ you.</p>
+
+
+<h2 id="v42_feat">New Features and Improvements</h2>
+
+<ul>
+ <li><a href="#v42_feat_sqlite">Experimental SQLite Support</a></li>
+ <li><a href="#v42_feat_attach">Creating an Attachment by Pasting Text Into
+ a Text Field</a></li>
+ <li><a href="#v42_feat_email">HTML [% terms.Bug %]mail</a></li>
+ <li><a href="#v42_feat_search">Improved Searching System</a></li>
+ <li><a href="#v42_feat_product">Disabling Old Components, Versions and Milestones</a></li>
+ <li><a href="#v42_feat_custom">Displaying a Custom Field Value Based on Multiple
+ Values of Another Field</a></li>
+ <li><a href="#v42_feat_audit">Auditing of All Changes Within [% terms.Bugzilla %]</a></li>
+ <li><a href="#v42_feat_wai">Accessibility Improvements</a></li>
+ <li><a href="#v42_feat_other">Other Enhancements and Changes</a></li>
+</ul>
+
+<h3 id="v42_feat_sqlite">Experimental SQLite Support</h3>
+
+<p>SQLite is now supported by [% terms.Bugzilla %] and becomes the 4th supported
+ database besides MySQL, PostgreSQL and Oracle. SQLite support must be considered
+ as experimental, at least till the next major release.</p>
+
+<p>Note that use of SQLite is only recommended for small installations. Larger
+ installations should use MySQL, PostgreSQL, or Oracle.</p>
+
+<h3 id="v42_feat_attach">Creating an Attachment by Pasting Text Into a Text Field</h3>
+
+<p>You can now create a new attachment simply by pasting some text into a text
+ field, in addition to the normal upload process for attachments.</p>
+
+<h3 id="v42_feat_email">HTML [% terms.Bug %]mail</h3>
+
+<p>By default, [% terms.bug %]mails (email notifications about changes to
+ [%+ terms.bugs %]) are now sent in an HTML format that is more readable than
+ the old text format. Those who prefer the old text format can still choose it
+ in their Preferences, however.</p>
+
+<h3 id="v42_feat_search">Improved Searching System</h3>
+
+<p>The Custom Search section in the Advanced Search page has been redesigned
+ to work in a more sensible way. Complex queries are easier to build and have
+ more sensible results, as they are built using a more intuitive logic.
+ Some very complicated queries are still impossible to generate, though.
+ Things should improve in future releases.</p>
+
+<h3 id="v42_feat_product">Disabling Old Components, Versions and Milestones</h3>
+
+<p>Older components, versions and milestones can now be disabled. [% terms.Bugs %]
+ already using them are not affected, but these values will no longer be
+ available for new [% terms.bugs %].</p>
+
+<h3 id="v42_feat_custom">Displaying a Custom Field Value Based on Multiple Values
+ of Another Field</h3>
+
+<p>A custom field can now be displayed based on multiple values of another field.
+ (For example, one custom field could now appear in multiple products.)
+ Previously, you could only display a custom field based on a single value of
+ another field.</p>
+
+<h3 id="v42_feat_audit">Auditing of All Changes Within [% terms.Bugzilla %]</h3>
+
+<p>Most changes made through the admin interface are now logged to the database,
+ in the <kbd>audit_log</kbd> table. There is no UI to access this table yet,
+ but developers are free to create their own tools to track changes made into
+ their installation. This is only a first step, and improvements are expected
+ in future releases.</p>
+
+<h3 id="v42_feat_wai">Accessibility Improvements</h3>
+
+<p>A project has started thanks to Francisco Donalisio from IBM to make
+ [%+ terms.Bugzilla %] compliant with the W3C Web Accessibility Initiative
+ standards. A lot more work still needs to be done, but we expect a much
+ better compatibility for the next major release.</p>
+
+<h3 id="v42_feat_other">Other Enhancements and Changes</h3>
+
+<h4>Enhancements for Users</h4>
+
+<ul>
+ <li><strong>[% terms.Bugs %]:</strong> Users without editbugs privileges can
+ no longer remove other users from the CC list of [% terms.bugs %].</li>
+ <li><strong>[% terms.Bugs %]:</strong> Local [% terms.bug %] IDs are now valid
+ in the See Also field. Adding such an ID will also add a reciprocal link in
+ the other [% terms.bug %].</li>
+ <li><strong>[% terms.Bugs %]:</strong> After editing [% terms.abug %] or an
+ attachment, the URL is automatically changed to <kbd>show_bug.cgi</kbd>
+ instead of <kbd>post_bug.cgi</kbd>, <kbd>process_bug.cgi</kbd> or
+ <kbd>attachment.cgi</kbd> so that reloading the page (for instance when
+ restarting the web browser) displays the right page. This feature is supported
+ by Firefox, Chrome and Safari, but not by Internet Explorer 9.</li>
+ <li><strong>[% terms.Bugs %]:</strong> Inactive accounts are no longer
+ displayed in user fields when user-autocompletion is enabled.</li>
+ <li><strong>[% terms.Bugs %]:</strong> User-autocompletion is now much faster
+ on installations with many user accounts.</li>
+ <li><strong>[% terms.Bugs %]:</strong> The See Also field now accepts URLs
+ pointing to MantisBT, Trac, JIRA and the sourceforge.net b[%%]ug trackers.</li>
+ <li><strong>[% terms.Bugs %]:</strong> Displaying [% terms.abug %] with many
+ dependencies is now much faster.</li>
+ <li><strong>Attachments:</strong> The encoding of text files can be automatically
+ detected when uploading them as attachments.</li>
+ <li><strong>Attachments:</strong> Clickjacking could possibly occur in an attachment
+ Details page if a user attached a specially formatted HTML file. To fix this
+ potential problem, the Details page always displays the HTML source instead and
+ users can see rendered page by clicking on View.</li>
+ <li><strong>Flags:</strong> Changing the requestee of a flag no longer changes
+ the requester.</li>
+ <li><strong>Reports:</strong> If JavaScript is enabled in your web browser,
+ tabular reports are now sortable based on any displayed column.</li>
+ <li><strong>Dependency graphs:</strong> The <em>Show every [% terms.bug %] in
+ the system with dependencies</em> option has been removed.</li>
+ <li><strong>Searches:</strong> The columns displayed by default in
+ [%+ terms.bug %]lists have changed. These columns are now displayed by default
+ unless otherwise specified:<br>
+ <kbd>product | component | assignee | [% terms.bug %] status | resolution |
+ [%+ terms.bug %] summary | last change date</kbd><br>
+ This means that the priority, severity and operating system columns are no
+ longer displayed by default.</li>
+ <li><strong>Searches:</strong> [% terms.Bug %]lists will now only display the
+ first 500 [% terms.bugs %] by default. It is still possible to display the
+ whole list, though.</li>
+ <li><strong>Searches:</strong> When using relative dates and times, <kbd>-1w</kbd>
+ is now a synonym for <kbd>-7d</kbd> and means exactly 7 days. Previously,
+ <kbd>-1w</kbd> meant the beginning of the week, which was confusing some users.
+ The same confusion existed for <kbd>-1d</kbd> which was different from
+ <kbd>-24h</kbd>, and for <kbd>-1m</kbd> which was different from <kbd>-30d</kbd>.
+ Now if you really want the beginning of the day, week or month, you must use
+ <kbd>-1ds</kbd>, <kbd>-1ws</kbd>, and <kbd>-1ms</kbd> respectively, where
+ "s" means "start of". This change will affect existing saved searches using
+ relative dates.</li>
+ <li><strong>Searches:</strong> A new <em>Include fulltext when performing quick
+ searches</em> user preference has been added which permits users to include
+ or exclude comments when using quicksearches.</li>
+ <li><strong>Searches:</strong> It is now possible to query for [% terms.bugs %]
+ based on personal tags in the Custom Search section in the Advanced Search
+ page.</li>
+ <li><strong>Email notifications: </strong> The date and time of comments are no
+ longer displayed in the comment header in [% terms.bug%]mails. This information
+ is already available in the email header itself.</li>
+</ul>
+
+<h4>Enhancements for Administrators and Developers</h4>
+
+<ul>
+ <li><strong>Installation:</strong> <kbd>checksetup.pl</kbd> is now much quieter
+ when creating a new database.</li>
+ <li><strong>Security:</strong> [% terms.Bugzilla %] 4.0 is using
+ <kbd>Math::Random::Secure</kbd> to generate cryptographically secure
+ pseudorandom numbers, but it appeared that installing this Perl module from
+ CPAN caused a lot of trouble for some people due to its numerous dependencies.
+ So the RNG code has been rewritten to only depend on <kbd>Math::Random::ISAAC</kbd>,
+ which was already in use in previous versions of [% terms.Bugzilla %].</li>
+ <li><strong>Security:</strong> <kbd>X-Frame-Options = SAMEORIGIN</kbd> is now
+ passed to all page headers (except when viewing attachments, as they can be
+ on a different host) to protect users from framing and subsequent possible
+ clickjacking problems.</li>
+ <li><strong>Configuration:</strong> A new parameter <em>password_complexity</em>
+ has been added (default: no_constraints) which allows admins to force users
+ to use passwords with a higher complexity, such as a combination of uppercase
+ and lowercase letters, numbers and special characters, or a subset of them.</li>
+ <li><strong>Configuration:</strong> A new parameter <em>search_allow_no_criteria</em>
+ has been added (default: on) which allows admins to forbid queries with no
+ criteria. This is particularly useful for large installations with several
+ tens of thousands [% terms.bugs %] where returning all [% terms.bugs %]
+ doesn't make sense and would have a performance impact on the database.</li>
+ <li><strong>Configuration:</strong> A new parameter <em>default_search_limit</em>
+ has been added (default: 500) which limits the number of [% terms.bugs %]
+ displayed by default in a [% terms.bug%]list. The user can ask to see a larger
+ list, though.</li>
+ <li><strong>Configuration:</strong> A new parameter <em>max_search_results</em>
+ has been added (default: 10000) which limits the number of [% terms.bugs %]
+ a user can request at once in a [% terms.bug%]list. This is a hard limit and
+ a user cannot bypass this value.</li>
+ <li><strong>Configuration:</strong> A new parameter <em>ajax_user_autocompletion</em>
+ has been added (default: on) to allow administrators to disable auto-completion
+ when typing characters in user fields. This parameter should only be disabled
+ if your installation is unable to support the load generated by this feature.</li>
+ <li><strong>Configuration:</strong> The <em>config_modify_panels</em> hook now
+ lets you add additional parameters to existing parameters panels.</li>
+ <li><strong>Flags:</strong> Users with local editcomponents privileges can now
+ edit flag types for products they can administer.</li>
+ <li><strong>Quips:</strong> A new system group <em>bz_quip_moderators</em> has
+ been created to moderate quips. Till now, you had to be in the <em>admin</em>
+ group to do that.</li>
+ <li><kbd>importxml.pl</kbd> now inserts each comment separately into the imported
+ [%+ terms.bug %] instead of concatenating them all into a single comment.</li>
+ <li><kbd>email_in.pl</kbd> now ignores auto-submitted incoming emails (for
+ instance, all these "out of office" emails).</li>
+ <li>New code hooks: email_in_before_parse, email_in_after_parse,
+ install_filesystem, install_update_db_fielddefs, job_map, object_end_of_create,
+ quicksearch_map, user_preferences.</li>
+</ul>
+
+<h4>WebService Changes</h4>
+
+<ul>
+ <li>Two new methods have been added: <kbd>Product.create</kbd> and
+ <kbd>Group.create</kbd>.</li>
+ <li><kbd>B[%%]ug.update</kbd> no longer throws an error when passing an empty
+ string to <kbd>see_also</kbd>. It now simply ignores this empty value.</li>
+ <li><kbd>Product.get</kbd> now also returns data about the classification it
+ belongs to as well as its components, milestones and versions. It also
+ returns the <kbd>default_milestone</kbd> and <kbd>has_unconfirmed</kbd>
+ attributes.</li>
+ <li>In <kbd>B[%%]ug.fields</kbd>, the <kbd>sortkey</kbd> attribute used in
+ <kbd>values</kbd> has been renamed to <kbd>sort_key</kbd>.</li>
+ <li>In <kbd>B[%%]ug.attachments</kbd> and <kbd>B[%%]ug.add_attachment</kbd>,
+ the <kbd>is_url</kbd> attribute no longer exists.</li>
+</ul>
+
+
+<h2 id="v42_issues">Outstanding Issues</h2>
+
+<ul>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=89822">
+ [%- terms.Bug %] 89822</a>: When changing multiple [% terms.bugs %] at
+ the same time, there is no "mid-air collision" protection.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=276230">
+ [%- terms.Bug %] 276230</a>: The support for restricting access to
+ particular Categories of New Charts is not complete. You should treat the
+ <em>chartgroup</em> parameter as the only access mechanism available.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=584742">
+ [%- terms.Bug %] 584742</a>: When viewing [% terms.abug %], WebKit-based
+ browsers can automatically reset a field's selected value when the field
+ has disabled values.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=780053">
+ [%- terms.Bug %] 780053</a>: Oracle crashes when listing keywords, tags
+ or flags in buglists.</li>
+</ul>
+
+
+<h2 id="v42_code_changes">Code Changes Which May Affect Customizations and Extensions</h2>
+
+<ul>
+ <li>The <kbd>email/newchangedmail.txt.tmpl</kbd> template is now fully templatized,
+ meaning that the diff table displaying changes in [% terms.bug %] fields is
+ now generated in the template itself. This means [% terms.bug %]mails are now
+ fully localizable.</li>
+ <li>The bugmail_recipients hook has been modified to pass <kbd>diffs</kbd> with
+ changes made to the [% terms.bug %] as well as <kbd>users</kbd> including
+ recipients of the email notification.</li>
+ <li>YUI has been upgraded to 2.9.0.</li>
+ <li>Due to the major code refactor of <kbd>B[%%]ugzilla/Search.pm</kbd>, any
+ customization made against this file will probably need to be rewritten.</li>
+ <li>The [% terms.Bugzilla %]-specific <kbd>url_quote</kbd> filter used in templates
+ has been removed and replaced by the <kbd>uri</kbd> filter from Template::Toolkit
+ as they are now similar.</li>
+ <li><kbd>long_list.cgi</kbd>, <kbd>showattachment.cgi</kbd> and <kbd>xml.cgi</kbd>
+ have been removed from the codebase. As <a href="#v40_code_changes">announced</a>
+ in the release notes of [% terms.Bugzilla %] 4.0, these scripts were deprecated
+ since [% terms.Bugzilla %] 2.19.</li>
+ <li><kbd>sidebar.cgi</kbd> has been removed, because Gecko-based browsers no
+ longer support remote XUL, and its popularity is very low.</li>
+ <li><kbd>contrib/yp_nomail.sh</kbd> has been removed. This script is no longer
+ useful since [% terms.Bugzilla %] 3.0.</li>
+ <li><kbd>contrib/bugzilla_ldapsync.rb</kbd> has been removed. This script didn't
+ work for a long time.</li>
+</ul>
+
+
+<h1 id="v42_previous">[% terms.Bugzilla %] 4.0 Release Notes</h1>
+
+<ul class="bz_toc">
+ <li><a href="#v40_introduction">Introduction</a></li>
+ <li><a href="#v40_point">Updates in this 4.0.x Release</a></li>
+ <li><a href="#v40_req">Minimum Requirements</a></li>
+ <li><a href="#v40_feat">New Features and Improvements</a></li>
+ <li><a href="#v40_issues">Outstanding Issues</a></li>
+ <li><a href="#v40_upgrading">Notes On Upgrading From a Previous Version</a></li>
+ <li><a href="#v40_code_changes">Code Changes Which May Affect
+ Customizations and Extensions</a></li>
+ <li><a href="#v40_previous">Release Notes for Previous Versions</a></li>
+</ul>
+
+<h2 id="v40_introduction">Introduction</h2>
+
+<p>This is [% terms.Bugzilla %] 4.0! Since 3.6 (our previous major
+ release) we've come a long way, and we've come even further compared to
+ 3.0 in 2007! Since [% terms.Bugzilla %] 3.0, almost every major user
+ interface in [% terms.Bugzilla %] has been redesigned, the WebServices have
+ evolved enormously, there's a great new Extensions system, and there
+ are hundreds of other new features. With the major redesigns that come
+ particularly in this release compared to 3.6, we felt that it was time to
+ call this release 4.0.</p>
+
+<p>It's not just major WebService and UI enhancements that are new in
+ [%+ terms.Bugzilla %] 4.0&mdash;there are many other exciting new features,
+ including automatic duplicate detection, enhanced custom field
+ functionality, autocomplete for users, search improvements, and much
+ more. Overall, 4.0 is far and away the best version of [% terms.Bugzilla %]
+ we've ever released.</p>
+
+<p>If you're upgrading, make sure to read <a href="#v40_upgrading">Notes
+ On Upgrading From a Previous Version</a>. If you are upgrading from a release
+ before 3.6, make sure to read the release notes for all the
+ <a href="#v40_previous">previous versions</a> in between your version
+ and this one, <strong>particularly the Upgrading section of each
+ version's release notes</strong>.</p>
+
+<p>We would like to thank
+ <a href="http://www.itasoftware.com/">ITA Software</a>,
+ the <a href="http://www.ibm.com/linux/ltc/">IBM Linux Technology Center</a>,
+ and <a href="http://www.redhat.com/">Red Hat</a> for funding the development
+ of certain features and improvements in this release of
+ [%+ terms.Bugzilla %].</p>
+
+<h2 id="v40_point">Updates in this 4.0.x Release</h2>
+
+<h3>4.0.2</h3>
+
+<p>This release fixes several security issues. See the
+ <a href="http://www.bugzilla.org/security/3.4.11/">Security Advisory</a>
+ for details.</p>
+
+<p>In addition, the following important fixes/changes have been made in this
+ release:</p>
+
+<ul>
+ <li>The <kbd>B[% %]ug.create</kbd> WebService method now throws an error if you
+ pass a group name which doesn't exist. In [% terms.Bugzilla %] 4.0 and 4.0.1,
+ this group name was silently ignored, leaving your [% terms.bug %] unsecure
+ if no other group applied.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=653341">[% terms.Bug %] 653341</a>)</li>
+ <li>Moving several [% terms.bugs %] at once into another product displayed the
+ same confirmation page again and again, and changes were never committed
+ (regressed in 4.0).
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=663208">[% terms.Bug %] 663208</a>)</li>
+ <li>Marking [% terms.abug %] as a duplicate now works in Internet Explorer 9.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=656769">[% terms.Bug %] 656769</a>)</li>
+ <li><kbd>importxml.pl</kbd> no longer crashes when importing keywords (regressed
+ in 4.0).
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=657707">[% terms.Bug %] 657707</a>)</li>
+ <li>Data entered while reporting a new [% terms.bug %] could be lost if you had
+ to click the "Back" button of your web browser.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=652427">[% terms.Bug %] 652427</a>)</li>
+ <li>WebServices methods will return undefined [% terms.bug %] fields as undefined
+ instead of as an empty string. This change is consistent with how
+ [%+ terms.Bugzilla %] 4.2 behaves.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=657561">[% terms.Bug %] 657561</a>)</li>
+ <li>The XML-RPC interface now works with SOAP::Lite 0.711 and 0.712 under mod_perl.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=600810">[% terms.Bug %] 600810</a>)</li>
+ <li>LWP 6.00 and newer require Perl 5.8.8 and above. When installing this module
+ using <kbd>install-module.pl</kbd> on a Perl installation older than 5.8.8,
+ LWP 5.837 will be installed instead.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=655912">[% terms.Bug %] 655912</a>)</li>
+ <li>Viewing [% terms.abug %] report should be significantly faster when your
+ installation has many custom fields.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=634812">[% terms.Bug %] 634812</a>)</li>
+</ul>
+
+<h3>4.0.1</h3>
+
+<ul>
+ <li>During installation, the CPAN module Math::Random::Secure would
+ sometimes fail to install properly and give an error about
+ <kbd>Math::Random::Secure::irand</kbd>. Now, when using
+ <kbd>install-module.pl</kbd> to install Math::Random::Secure, this
+ will no longer happen. If you are currently experiencing this b[% %]ug
+ and it prevented you from installing 4.0, remove Math::Random::Secure
+ from your <kbd>lib/</kbd> directory, like:
+ <p><kbd>rm -rf lib/Math/Random/Secure*</kbd></p>
+ <p>(<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=646578">[% terms.Bug %] 646578</a>)</p></li>
+ <li>The "Remember values as bookmarkable template" button on the
+ [%+ terms.bug %] entry page will now work even when some required fields
+ are empty.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=640719">[% terms.Bug %] 640719</a>)</li>
+ <li>Email notifications about dependencies and flags had the wrong
+ timestamp.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=643910">[% terms.Bug %] 643910</a>
+ and (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=652165">[% terms.Bug %] 652165</a>)</li>
+ <li>You can now select "UTC" as a valid timezone in General Preferences.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=646209">[% terms.Bug %] 646209</a>)</li>
+ <li>Automatic duplicate detection now works on PostgreSQL (although
+ it is not as high-quality as on other DB platforms).
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=634144">[% terms.Bug %] 634144</a>)</li>
+ <li>Autcomplete for users now works even if you are using the
+ "emailsuffix" option.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=641519">[% terms.Bug %] 641519</a>)</li>
+ <li>Javascript errors during series creation in New Charts have been
+ fixed.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=644285">[% terms.Bug %] 644285</a>)</li>
+ <li>The "Show Votes" page now works, for installations using the Voting
+ extension.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=652381">[% terms.Bug %] 652381</a>)</li>
+</ul>
+
+<h2 id="v40_req">Minimum Requirements</h2>
+
+<p>Any requirements that are new since 3.6.3 will look like
+ <span class="req_new">this</span>.</p>
+
+<ul>
+ <li><a href="#v40_req_perl">Perl</a></li>
+ <li><a href="#v40_req_mysql">For MySQL Users</a></li>
+ <li><a href="#v40_req_pg">For PostgreSQL Users</a></li>
+ <li><a href="#v40_req_oracle">For Oracle Users</a></li>
+ <li><a href="#v40_req_modules">Required Perl Modules</a></li>
+ <li><a href="#v40_req_optional_mod">Optional Perl Modules</a></li>
+ <li><a href="#v40_req_apache">Optional Apache Modules</a></li>
+</ul>
+
+<h3 id="v40_req_perl">Perl</h3>
+
+<p>Perl v5.8.1</p>
+<h3 id="v40_req_mysql">For MySQL Users</h3>
+
+ <ul>
+ <li>MySQL v4.1.2</li>
+ <li><strong>perl module:</strong> DBD::mysql v4.00</li>
+ </ul>
+
+<h3 id="v40_req_pg">For PostgreSQL Users</h3>
+
+ <ul>
+ <li>PostgreSQL v8.00.0000</li>
+ <li><strong>perl module:</strong> DBD::Pg v1.45</li>
+ </ul>
+
+<h3 id="v40_req_oracle">For Oracle Users</h3>
+
+ <ul>
+ <li>Oracle v10.02.0</li>
+ <li><strong>perl module:</strong> DBD::Oracle v1.19</li>
+ </ul>
+
+<h3 id="v40_req_modules">Required Perl Modules</h3>
+
+ <table cellspacing="0" cellpadding="0" border="0" class="req_table">
+ <tbody>
+ <tr>
+ <th>Module</th><th>Version</th>
+ </tr>
+ <tr>
+ <td>CGI</td>
+ <td class="req_new">3.51</td>
+ </tr>
+ <tr>
+ <td>Digest::SHA</td>
+ <td>(Any)</td>
+ </tr>
+ <tr>
+ <td>Date::Format</td>
+ <td>2.21</td>
+ </tr>
+ <tr>
+ <td>DateTime</td>
+ <td>0.28</td>
+ </tr>
+ <tr>
+ <td>DateTime::TimeZone</td>
+ <td>0.71</td>
+ </tr>
+ <tr>
+ <td>DBI</td>
+ <td>1.41</td>
+ </tr>
+ <tr>
+ <td>Template</td>
+ <td>2.22</td>
+ </tr>
+ <tr>
+ <td>Email::Send</td>
+ <td>2.00</td>
+ </tr>
+
+ <tr>
+ <td>Email::MIME</td>
+ <td class="req_new">1.904</td>
+ </tr>
+ <tr>
+ <td>URI</td>
+ <td>(Any)</td>
+ </tr>
+ <tr>
+ <td class="req_new">List::MoreUtils</td>
+ <td class="req_new">0.22</td>
+ </tr>
+ </tbody>
+ </table>
+
+<h3 id="v40_req_optional_mod">Optional Perl Modules</h3>
+
+<p>The following perl modules, if installed, enable various
+ features of [% terms.Bugzilla %]:</p>
+
+ <table cellspacing="0" cellpadding="0" border="0" class="req_table">
+ <tbody>
+ <tr>
+ <th>Module</th><th>Version</th><th>Enables Feature</th>
+ </tr>
+ <tr>
+ <td>GD</td>
+ <td>1.20</td>
+ <td>Graphical Reports, New Charts, Old Charts</td>
+ </tr>
+ <tr>
+ <td>Chart::Lines</td>
+ <td>2.1</td>
+ <td>New Charts, Old Charts</td>
+ </tr>
+ <tr>
+ <td>Template::Plugin::GD::Image</td>
+ <td>(Any)</td>
+ <td>Graphical Reports</td>
+ </tr>
+ <tr>
+ <td>GD::Text</td>
+ <td>(Any)</td>
+ <td>Graphical Reports</td>
+ </tr>
+ <tr>
+ <td>GD::Graph</td>
+ <td>(Any)</td>
+ <td>Graphical Reports</td>
+ </tr>
+ <tr>
+ <td>MIME::Parser</td>
+ <td>5.406</td>
+ <td>Move [% terms.Bugs %] Between Installations</td>
+ </tr>
+ <tr>
+ <td>LWP::UserAgent</td>
+ <td>(Any)</td>
+ <td>Automatic Update Notifications</td>
+ </tr>
+ <tr>
+ <td>XML::Twig</td>
+ <td>(Any)</td>
+ <td>Move [% terms.Bugs %] Between Installations, Automatic Update
+ Notifications</td>
+ </tr>
+ <tr>
+ <td>PatchReader</td>
+ <td>0.9.4</td>
+ <td>Patch Viewer</td>
+ </tr>
+ <tr>
+ <td>Net::LDAP</td>
+ <td>(Any)</td>
+ <td>LDAP Authentication</td>
+ </tr>
+ <tr>
+ <td>Authen::SASL</td>
+ <td>(Any)</td>
+ <td>SMTP Authentication</td>
+ </tr>
+ <tr>
+ <td>Authen::Radius</td>
+ <td>(Any)</td>
+ <td>RADIUS Authentication</td>
+ </tr>
+ <tr>
+ <td>SOAP::Lite</td>
+ <td class="req_new">0.712</td>
+ <td>XML-RPC Interface</td>
+ </tr>
+ <tr>
+ <td>JSON::RPC</td>
+ <td>(Any)</td>
+ <td>JSON-RPC Interface</td>
+ </tr>
+ <tr>
+ <td class="req_new">JSON::XS</td>
+ <td class="req_new">2.0</td>
+ <td>Make JSON-RPC Faster</td>
+ </tr>
+ <tr>
+ <td>Test::Taint</td>
+ <td>(Any)</td>
+ <td>JSON-RPC Interface, XML-RPC Interface</td>
+ </tr>
+ <tr>
+ <td>HTML::Parser</td>
+ <td>3.40</td>
+ <td>More HTML in Product/Group Descriptions</td>
+ </tr>
+ <tr>
+ <td>HTML::Scrubber</td>
+ <td>(Any)</td>
+ <td>More HTML in Product/Group Descriptions</td>
+ </tr>
+ <tr>
+ <td>Email::MIME::Attachment::Stripper</td>
+ <td>(Any)</td>
+ <td>Inbound Email</td>
+ </tr>
+ <tr>
+ <td>Email::Reply</td>
+ <td>(Any)</td>
+ <td>Inbound Email</td>
+ </tr>
+ <tr>
+ <td>TheSchwartz</td>
+ <td>(Any)</td>
+ <td>Mail Queueing</td>
+ </tr>
+ <tr>
+ <td>Daemon::Generic</td>
+ <td>(Any)</td>
+ <td>Mail Queueing</td>
+ </tr>
+ <tr>
+ <td>mod_perl2</td>
+ <td>1.999022</td>
+ <td>mod_perl</td>
+ </tr>
+ <tr>
+ <td>Apache2::SizeLimit</td>
+ <td class="req_new">0.93</td>
+ <td>mod_perl</td>
+ </tr>
+ <tr>
+ <td class="req_new">Math::Random::Secure</td>
+ <td class="req_new">0.05</td>
+ <td>Improve cookie and token security</td>
+ </tr>
+ </tbody>
+ </table>
+
+<h3 id="v40_req_apache">Optional Apache Modules</h3>
+
+<p>If you are using Apache as your webserver, [% terms.Bugzilla %] can
+ now take advantage of some Apache features if you have the below Apache
+ modules installed and enabled. Currently,
+ <a href="#v40_feat_js_css_update">certain [% terms.Bugzilla %] features</a>
+ are enabled only if you have all of the following modules installed
+ and enabled:</p>
+
+<ul>
+ <li>mod_headers</li>
+ <li>mod_expires</li>
+ <li>mod_env</li>
+</ul>
+
+<p>On most systems (but not on Windows), <kbd>checksetup.pl</kbd> is able to
+ tell whether or not you have these modules installed, and it will tell
+ you.</p>
+
+<h2 id="v40_feat">New Features and Improvements</h2>
+
+<ul>
+ <li><a href="#v40_feat_dup">Automatic Duplicate Detection When Filing
+ [%+ terms.Bugs %]</a></li>
+ <li><a href="#v40_feat_search_ui">New Advanced Search UI</a></li>
+ <li><a href="#v40_feat_attach_ui">New Attachment Details UI</a></li>
+ <li><a href="#v40_feat_autocomplete">Autocomplete for Users and
+ Keywords</a></li>
+ <li><a href="#v40_feat_ui">General Usability Improvements</a></li>
+ <li><a href="#v40_feat_workflow">New Default Status Workflow</a></li>
+ <li><a href="#v40_feat_lists">"Last Search" Now Remembers Multiple
+ Searches</a></li>
+ <li><a href="#v40_feat_jsonp">Cross-Domain WebServices with JSONP</a></li>
+ <li><a href="#v40_feat_ws">Major WebService Enhancements</a></li>
+ <li><a href="#v40_feat_mandatory">Mandatory Custom Fields</a></li>
+ <li><a href="#v40_feat_vot_ext">Voting Is Now An Extension</a></li>
+ <li><a href="#v40_feat_js_css_update">Users Get New CSS and Javascript
+ Automatically</a></li>
+ <li><a href="#v40_feat_hooks">Many New Hooks</a></li>
+ <li><a href="#v40_feat_apache_config">New Apache Configuration</a></li>
+ <li><a href="#v40_feat_other">Other Enhancements and Changes</a></li>
+</ul>
+
+<h3 id="v40_feat_dup">Automatic Duplicate Detection When Filing
+ [%+ terms.Bugs %]</h3>
+
+<p>When filing [% terms.abug %], as soon as you start typing in the summary
+ field, [% terms.Bugzilla %] will suggest possible duplicates of the
+ [%+ terms.bug %] you are filing.</p>
+
+<p>In order for this feature to work, all pre-requisites for JSON-RPC
+ support must be installed on your [% terms.Bugzilla %]. It will be
+ much faster on installations that run under mod_perl than it will
+ be on other installations.</p>
+
+<h3 id="v40_feat_search_ui">New Advanced Search UI</h3>
+
+<p>Thanks to the UI work of <a href="http://guy-pyrzak.blogspot.com/">Guy
+ Pyrzak</a>, the Advanced Search UI has been completely redesigned.
+ It is now much simpler, and far more approachable for new users, while
+ still retaining all of the features that power users are used to.</p>
+
+<h3 id="v40_feat_attach_ui">New Attachment Details UI</h3>
+
+<p>The UI used for editing attachment details has been completely
+ redesigned, allowing for a normally-size comment box to be used
+ when commenting on attachments, and allowing nearly the entire screen
+ width to be used when doing code reviews or editing an attachment as
+ a comment.</p>
+
+<p>Thanks to <a href="http://guy-pyrzak.blogspot.com/">Guy Pyrzak</a> for
+ his excellent work on this UI redesign.</p>
+
+<h3 id="v40_feat_autocomplete">Autocomplete for Users and Keywords</h3>
+
+<p>Once you type at least three characters in any field that can contain a user
+ (including the [% field_descs.cc FILTER html %],
+ [%+ field_descs.qa_contact FILTER html %], or
+ [%+ field_descs.assigned_to FILTER html %] fields), a list will appear
+ containing all of the users whose real names or usernames match what you are
+ typing. Your [% terms.Bugzilla %] must have all of the optional Perl
+ modules required for JSON-RPC support installed, though, in order for
+ this feature to work. Also, this feature will be <strong>much</strong>
+ faster on installations that run under mod_perl than it will be on
+ other installations.</p>
+
+<p>There is also a similar autocomplete for the Keywords field. The
+ Keywords autocomplete does not require JSON-RPC.</p>
+
+<h3 id="v40_feat_ui">General Usability Improvements</h3>
+
+<p>In addition to the enhancements listed above, there have been
+ <strong>many</strong> improvements made across the [% terms.Bugzilla %]
+ user interface. For a list of specific enhancements that were significant,
+ see the <a href="#v40_feat_other">Other Enhancements and Changes</a>
+ section.</p>
+
+<h3 id="v40_feat_workflow">New Default Status Workflow</h3>
+
+<p>For new installations of [% terms.Bugzilla %], the default set of
+ statuses will now be:</p>
+
+<ul>
+ <li>UNCONFIRMED</li>
+ <li>CONFIRMED</li>
+ <li>IN_PROGRESS</li>
+ <li>RESOLVED</li>
+ <li>VERIFIED</li>
+</ul>
+
+<p>And the UNCONFIRMED status will be enabled by default in all products.</p>
+
+<p>On upgrade, existing installations will not be affected--you will retain
+ your existing status workflow. However, we strongly recommend that you
+ update your existing workflow to the new one, using a special tool
+ we've included, <kbd>contrib/convert-workflow.pl</kbd>, which you
+ can run after you use <kbd>checksetup.pl</kbd> to upgrade. The
+ <kbd>whineatnews.pl</kbd> and <kbd>bugzilla-submit</kbd> scripts
+ will probably not work properly if you continue to use the old workflow
+ (though most other parts of [% terms.Bugzilla %] will still function
+ normally).</p>
+
+<p>For more information about the workflow and our rationale for changing
+ it, see the
+ <a href="http://bugzillaupdate.wordpress.com/2010/07/06/bugzilla-4-0-has-a-new-default-status-workflow/">blog
+ post about it</a> and the
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=486292">[% terms.bug %]
+ where the change was made</a>.</p>
+
+<h3 id="v40_feat_lists">"Last Search" Now Remembers Multiple Searches</h3>
+
+<p>At the top of every [% terms.bug %] in [% terms.Bugzilla %], there are
+ links that look like: "First", "Last", "Prev", "Next", and
+ "Show last search results". In earlier versions of [% terms.Bugzilla %],
+ if you did two separate searches in separate windows, these links would
+ only work for the <em>last</em> search you did. Now, [% terms.Bugzilla %]
+ will "remember" which search result you came from and give you the right
+ "last search results" or "next [% terms.bug %]" from <em>that</em> list,
+ instead of always using your most recent search.</p>
+
+<p>There are still some situations where [% terms.Bugzilla %] will have to
+ "guess" which search you are trying to navigate through, but it does its
+ best to get it right.</p>
+
+<h3 id="v40_feat_jsonp">Cross-Domain WebServices with JSONP</h3>
+
+<p>[% terms.Bugzilla %] now supports making WebService calls from
+ another domain, inside of a web browser, thanks to support for
+ <a href="http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/">JSONP</a>.
+ This will allow for web "mash-ups" to use [% terms.Bugzilla %] data.
+ When using JSONP, you may only call functions that <em>get</em> data,
+ you may not call functions that <em>change</em> data.</p>
+
+<p>For more details, see the
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/Server/JSONRPC.html#JSONP">JSONP
+ section</a> of the JSON-RPC WebService documentation.</p>
+
+<h3 id="v40_feat_ws">Major WebService Enhancements</h3>
+
+<p>The WebService has been expanded considerably. The WebService should now be
+ able to do everything with [% terms.bugs %] that you can do via the
+ web interface, including updating [% terms.bugs %], adding attachments,
+ and getting attachment data. For specifics, see the
+ <a href="#v40_feat_ws_changes">WebService Changes</a> section of these
+ release notes.</p>
+
+<h3 id="v40_feat_mandatory">Mandatory Custom Fields</h3>
+
+<p>You can now specify that certain custom fields are "mandatory",
+ meaning that they must have a value when [% terms.abug %] is filed,
+ and they can never be empty after that.</p>
+
+<h3 id="v40_feat_vot_ext">Voting Is Now An Extension</h3>
+
+<p>All of the code for voting in [% terms.Bugzilla %] has been moved
+ into an extension, called "Voting", in the <kbd>extensions/Voting/</kbd>
+ directory. To enable it, you must remove the <kbd>disabled</kbd> file
+ from that directory, and run <kbd>checksetup.pl</kbd>.</p>
+
+<p>In a future version of [% terms.Bugzilla %], the Voting extension will
+ be moved outside of the [% terms.Bugzilla %] core code, so we are looking
+ for somebody who has an interest in the Voting system and would like to
+ maintain it as a separate extension. There are many enhancement requests
+ that have been made against the Voting system, and the best way for those
+ to get addressed is for somebody to step up and offer to maintain the
+ system outside of [% terms.Bugzilla %]'s core code.</p>
+
+<h3 id="v40_feat_js_css_update">Users Get New CSS and Javascript
+ Automatically</h3>
+
+<p>In past versions of [% terms.Bugzilla %], if you changed
+ [%+ terms.Bugzilla %]'s CSS or Javascript files, then every user of
+ [%+ terms.Bugzilla %] would have to clear their cache in order to get
+ the updated files. Now, if you are using Apache as your webserver and
+ you have the <a href="#v40_req_apache">optional Apache modules</a>
+ installed and enabled, users will automatically get every new version of
+ [%+ terms.Bugzilla %]'s Javascript and CSS without having to clear
+ their caches.</p>
+
+<p>This feature also gives a slight performance speedup to
+ [%+ terms.Bugzilla %] in some cases, and so we recommend that all
+ administrators install and enable the optional Apache modules if possible.</p>
+
+<h3 id="v40_feat_hooks">Many New Hooks</h3>
+
+<p>Many new code hooks have been added for use by Extensions,
+ in [% terms.Bugzilla %] 4.0. Now Extensions can access and modify
+ nearly every part of [% terms.Bugzilla %].</p>
+
+<h3 id="v40_feat_apache_config">New Apache Configuration</h3>
+
+<p>If you run [% terms.Bugzilla %] under Apache (as most people do),
+ you most likely require a <strong>new Apache configuration</strong>
+ for this version of [% terms.Bugzilla %]. See the
+ <a href="#v40_upgrading">Notes On Upgrading From a Previous Version</a>
+ section for details.</p>
+
+<h3 id="v40_feat_other">Other Enhancements and Changes</h3>
+
+<h4>Enhancements for Users</h4>
+
+<ul>
+ <li>Now, everywhere in [% terms.Bugzilla %] where you can enter a date,
+ there is a Calendar widget where you can select the date on a
+ calendar.</li>
+ <li>The big icons on the front page have been replaced with much nicer
+ icons, thanks to Jon Pink of <a href="http://www.jpink.co.uk/">J.&nbsp;Pink&nbsp;Design</a>!</li>
+ <li><strong>[% terms.Bugs %]:</strong> When filing [% terms.bugs %],
+ you will now be warned if you forgot to fill in any mandatory fields,
+ <em>before</em> the page is submitted.</li>
+ <li><strong>[% terms.Bugs %]:</strong> When filing [% terms.abug %],
+ you can hover your mouse over any of the field labels on the page
+ to get a brief description of what that field is and what its purpose
+ is.</li>
+ <li><strong>[% terms.Bugs %]:</strong> When adding Hours Worked to [% terms.abug %],
+ you are no longer required to comment.</li>
+ <li><strong>[% terms.Bugs %]:</strong> There is now a user preference
+ for whether the comment box appears above or below the existing
+ comments.</li>
+ <li><strong>[% terms.Bugs %]:</strong> [% terms.Bugzilla %] will now
+ send an email for every comment that you mark or un-mark as being
+ private. (Previous versions of [% terms.Bugzilla %] did not send emails
+ to users about this change.) The state of comments being made private
+ is also now stored in [% terms.abug %]'s history.</li>
+ <li><strong>[% terms.Bugs %]:</strong> The box to "Add [% terms.Bug %] URLs"
+ in the See Also field is now hidden behind an "(add)" link that you
+ have to click to see the box.</li>
+
+ <li><strong>Searches:</strong> You can now properly search for field values
+ that have commas in their name, when using the Advanced Search form.</li>
+ <li><strong>Searches:</strong> The "URL" field can now be shown as a column
+ in search results.</li>
+ <li><strong>Searches:</strong> When viewing a search result, you can now
+ click on the Summary of the [% terms.bug %] in order to go to the
+ [%+ terms.bug %]-view page, in addition to being able to click on the
+ [%+ terms.bug %] ID.</li>
+ <li><strong>Searches:</strong> When doing a search using the "quicksearch"
+ box in the header or footer, the box will still contain what you searched
+ for when viewing the search results page.</li>
+ <li><strong>Searches:</strong> Multi-select custom fields can now be
+ shown as columns in the search results.</li>
+ <li><strong>Searches:</strong> When using the Boolean Charts (now called
+ "Custom Search"), if you specify both a criterion for an attachment
+ and a criteron for a flag, then only [% terms.bugs %] that have
+ attachments with that flag will be found.</li>
+ <li><strong>Searches:</strong> If you hover your mouse over the field labels
+ on the Advanced Search page, you will get a description of what that
+ field is.</li>
+ <li><strong>Searches:</strong> When searching via a saved search, if you
+ accidentally click on "Forget Search", there is a link to undo it.</li>
+ <li><strong>Searches:</strong> When using the Boolean Charts (now called
+ "Custom Search"), you can search for values "greater than or equal to"
+ or "less than or equal to" some value.</li>
+
+ <li><strong>Flags:</strong> If you hover your mouse over the name of
+ a flag setter when viewing [% terms.abug %], you can see that
+ flag setter's full name and complete username.</li>
+ <li><strong>Flags:</strong> When setting a flag on [% terms.abug %],
+ the box for entering a requestee does not appear until you set the flag
+ to "?", now.</li>
+ <li><strong>Flags:</strong> On the "My Requests" page, [% terms.bugs %]
+ that are restricted to certain groups now properly have the "padlock"
+ icon shown next to them to indicate that they may contain confidential
+ information.</li>
+
+ <li>When using the Reports interface, you can now choose many more fields
+ as the X, Y, or Z axis of a report, including custom fields.</li>
+ <li>[% terms.Bugzilla %] now prevents
+ Internet Explorer 8 and later from attempting to render
+ <kbd>text/plain</kbd> attachments as HTML.</li>
+ <li>If you receive a Whine mail that is empty, there will now be a brief
+ message explaining that your search found no results.</li>
+ <li>The <a href="page.cgi?id=fields.html">Field Help Page</a> now
+ contains a description of every single field that can be on
+ [%+ terms.abug %] in [% terms.Bugzilla %].</li>
+</ul>
+
+<h4>Enhancements for Administrators and Developers</h4>
+
+<ul>
+ <li>The system for moving [% terms.bugs %] between installations has been
+ moved into an extension called <kbd>OldBugMove</kbd>. This system was used
+ by very few [% terms.Bugzilla %] installations--if you aren't certain
+ whether or not you are using it, you're not using it. To enable the system,
+ you have to remove the file <kbd>extensions/OldBugMove/disabled</kbd>
+ and then run <kbd>checksetup.pl</kbd>. In a future version of [% terms.Bugzilla %],
+ this extension may be moved outside of the core [% terms.Bugzilla %] code,
+ so if you are interested in maintaining it, please let us know.</li>
+ <li><strong>Custom Fields: </strong> "[% terms.Bug %] ID" custom fields can
+ now represent relationships between [% terms.bugs %], similarly to how the
+ [%+ field_descs.blocked FILTER html %] and
+ [%+ field_descs.dependson FILTER html %] fields work now.</li>
+ <li><strong>Custom Fields:</strong> You can now restrict the visibility
+ of custom fields and their values to a specific Component or
+ Classification.</li>
+ <li>The "keyword cache" has been removed. When you edit keywords, you no
+ longer will have to "rebuild the keyword cache" after you are done.</li>
+ <li>Running <kbd>./collectstats.pl --regenerate</kbd> will now take
+ minutes or hours, instead of days.</li>
+ <li>When using <kbd>email_in.pl</kbd>, there are two new switches,
+ <kbd>--default</kbd> and <kbd>--override</kbd>, which allow you to
+ specify certain default values or override specified values for
+ <kbd>@field</kbd> values sent in emails. (This also allows you to specify
+ defaults for everything so that people do not have to specify any field
+ values when filing [% terms.abug %] via email.)</li>
+ <li><strong>Installation:</strong> If you are using a localized version of
+ [%+ terms.Bugzilla %] and your terminal does not understand Unicode,
+ <kbd>checksetup.pl</kbd> will now attempt to output its messages in your
+ terminal's character set.</li>
+ <li><strong>Installation:</strong> [% terms.Bugzilla %] no longer needs empty
+ "placeholder" CSS in the <kbd>skins/custom</kbd> directory and other
+ directories. When you update, <kbd>checksetup.pl</kbd> will remove these.
+ This also significantly reduces the number of HTTP requests required to
+ load a page for the first time in [% terms.Bugzilla %].</li>
+ <li><strong>Installation:</strong> For Windows users, [% terms.Bugzilla %]
+ now supports Strawberry Perl fully.</li>
+ <li><strong>Installation:</strong> Now, whenever <kbd>checksetup.pl</kbd>
+ throws an error, it will be printed in the color red, to make it
+ obvious that something is wrong.</li>
+ <li><strong>Installation:</strong> Some actions of <kbd>checksetup.pl</kbd> were
+ silent, in the past. Now, <kbd>checksetup.pl</kbd> will print a message for
+ almost anything it does.</li>
+ <li><strong>Installation:</strong> The process of adding foreign keys
+ to a table is now much faster. This will particularly improve the speed
+ of upgrading from [% terms.Bugzilla %] 3.4 or earlier.</li>
+ <li>If you are using <kbd>jobqueue.pl</kbd> and email gets heavily delayed
+ for some reason, those emails will now have a Date header reflecting the
+ time they were <em>supposed</em> to be sent, instead of when they actually
+ <em>were</em> sent.</li>
+ <li><kbd>./jobqueue.pl install</kbd> now works on SuSE Linux.</li>
+ <li>[% terms.Bugzilla %] now runs much better in Apache's suexec mode
+ than it used to. As part of this, <kbd>checksetup.pl</kbd> sets
+ much stricter permissions on all the files in [% terms.Bugzilla %]
+ than it used to. In particular, any files that [% terms.Bugzilla %]
+ does not know about will not be readable by the webserver.</li>
+ <li>The <kbd>sendmailnow</kbd> parameter has been removed, as it was
+ not necessary for any modern version of Sendmail or other Mail Transfer
+ Agent.</li>
+ <li>When editing a user via the Users administration panel, you can now
+ see if they are a Default CC on any component.</li>
+ <li>For new installations of [% terms.Bugzilla %], all users will be
+ able to see and use the Whining system by default.</li>
+ <li>When you are using SSL with [% terms.Bugzilla %], you can now
+ turn on the <kbd>strict_transport_security</kbd> parameter to
+ send the
+ <a href="https://developer.mozilla.org/en/Security/HTTP_Strict_Transport_Security">Strict-Transport-Security</a>
+ header with every HTTPS connection, for additional security.</li>
+ <li>New code hooks (see their documentation in
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/Hook.html">Bugzilla::Hook</a>):
+ bug_check_can_change_field, search_operator_field_override,
+ bugmail_relationships, object_columns, object_update_columns,
+ and object_validators. The colchange_columns hook has been removed,
+ as it is no longer necessary (buglist_columns will be used for data
+ about which columns can be on the [% terms.bug %] list).</li>
+ <li>When [% terms.Bugzilla %] throws certain types of errors, it will
+ now include a "traceback" of where exactly the error occurred in the
+ code, to help administrators and developers debug problems.</li>
+ <li>There is now a test, <kbd>xt/search.t</kbd>, that assures that all
+ of the functionality of <kbd>Bugzilla::Search</kbd> is working properly.
+ If you customize the search functionality of [% terms.Bugzilla %],
+ you may wish to run this test to assure that your changes are correct.
+ You can see more information about running this test by doing
+ <kbd>perldoc xt/search.t</kbd> at the command line.</li>
+ <li>[% terms.Bugzilla %] now sends the
+ <a href="https://developer.mozilla.org/en/the_x-frame-options_response_header"><code>X-Frame-Options: SAMEORIGIN</code></a> header
+ with every page request in order to prevent "clickjacking" attacks. Note
+ that this prevents other domains from displaying [% terms.Bugzilla %]
+ in an HTML frame.</li>
+</ul>
+
+<h4 id="v40_feat_ws_changes">WebService Changes</h4>
+
+<ul>
+ <li>You can now call some JSON-RPC methods using HTTP GET, in addition to
+ using HTTP POST. See the
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/Server/JSONRPC.html#Connecting_via_GET">JSON-RPC
+ documentation</a> for details.</li>
+ <li>You can now update existing [% terms.bugs %] using the
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/Bug.html#update">B[% %]ug.update</a>
+ function.</li>
+ <li>You can now add attachments to [% terms.bugs %] using the
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/Bug.html#add_attachment">B[% %]ug.add_attachment</a>
+ function.</li>
+ <li>The <kbd>B[% %]ug.get</kbd> function now returns all of [% terms.abug %]'s
+ information other than comments and attachments.</li>
+ <li><kbd>B[% %]ug.get</kbd> no longer returns the <kbd>internals</kbd> hash.</li>
+ <li>The <kbd>B[% %]ug.attachments</kbd> function now also returns attachment
+ data.</li>
+ <li>The following functions now support the <kbd>include_fields</kbd>
+ and <kbd>exclude_fields</kbd> arguments: <kbd>B[% %]ug.get</kbd>,
+ <kbd>B[% %]ug.search</kbd>, and <kbd>B[% %]ug.attachments</kbd>. Also,
+ server-side performance of the WebService is actually increased when
+ using these arguments, now, as [% terms.Bugzilla %] will no longer
+ get data from the database for fields you haven't asked for.</li>
+ <li>You can now mark the initial description of [% terms.abug %] as
+ private when filing [% terms.abug %] via the <kbd>B[% %]ug.create</kbd>
+ function.</li>
+ <li>You can now specify groups to put [% terms.abug %] in, in the
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/Bug.html#create">B[% %]ug.create</a>
+ function. (This also means that you can specify groups when filing
+ [%+ terms.abug %] via email_in.pl.)</li>
+ <li>The <kbd>User.get</kbd> function now accepts <kbd>groups</kbd>
+ and <kbd>group_ids</kbd> arguments, to limit the returned values to
+ only users in the specified groups.</li>
+ <li>There is a new, undocumented B[% %]ug.possible_duplicates
+ function that helps implement the automatic duplicate detection
+ system. Because this function is not documented, its API may change
+ between releases of [% terms.Bugzilla %].</li>
+ <li>You can no longer search using the <kbd>votes</kbd> argument in
+ <kbd>B[% %]ug.search</kbd>.</li>
+ <li><kbd>B[% %]ug.attachments</kbd> now returns the attachment's description
+ using the name "summary" instead of the name "description", to be
+ consistent with the fact that [% terms.bug %] summaries are called
+ "summary". The value is still <em>also</em> returned as "description",
+ for backwards compatibility, but this backwards compatibility will go
+ away in [% terms.Bugzilla %] 5.0.</li>
+ <li>In the return values of various <kbd>B[% %]ug</kbd> functions, the author
+ of comments, [% terms.bugs %], and attachments is now called "creator",
+ instead of sometimes being called "reporter", "author", or "attacher".
+ The old names are retained for backwards-compatibility, and will stay
+ around until [% terms.Bugzilla %] 5.0.</li>
+</ul>
+
+<h2 id="v40_issues">Outstanding Issues</h2>
+
+<ul>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=423439">
+ [%- terms.Bug %] 423439</a>: Tabs in comments will be converted
+ to four spaces, due to a b<!-- -->ug in Perl as of Perl 5.8.8.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=89822">
+ [%- terms.Bug %] 89822</a>: When changing multiple [% terms.bugs %] at
+ the same time, there is no "mid-air collision" protection.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=276230">
+ [%- terms.Bug %] 276230</a>: The support for restricting access to
+ particular Categories of New Charts is not complete. You should treat
+ the 'chartgroup' Param as the only access mechanism available.<br>
+ However, charts migrated from Old Charts will be restricted to
+ the groups that are marked MANDATORY for the corresponding Product.
+ There is currently no way to change this restriction, and the
+ groupings will not be updated if the group configuration
+ for the Product changes.</li>
+</ul>
+
+<h2 id="v40_upgrading">Notes On Upgrading From a Previous Version</h2>
+
+<h3>IMPORTANT: Apache Configuration Change</h3>
+
+<h4>mod_cgi</h4>
+
+<p>If you run [% terms.Bugzilla %] under mod_cgi (this is the most common
+ configuration, involving a &lt;Directory&gt; block in your Apache config
+ file), you will need to update the configuration of Apache for
+ [%+ terms.Bugzilla %]. In particular, this line in the [% terms.Bugzilla %]
+ <kbd>&lt;Directory&gt;</kbd> block:</p>
+
+<blockquote><code>AllowOverride Limit</code></blockquote>
+
+<p>needs to become:</p>
+
+<blockquote><code>AllowOverride Limit FileInfo Indexes</code></blockquote>
+
+<p>For full details on how to configure Apache for [% terms.Bugzilla %],
+ see the
+ <a href="[% docs_urlbase FILTER html %]configuration.html#http-apache">Configuration</a>
+ section of the [% terms.Bugzilla %] Guide.</p>
+
+<h4>mod_perl</h4>
+
+<p>If your [% terms.Bugzilla %] runs under mod_perl, the required Apache
+ configuration is now simpler. The line that used to look like:</p>
+
+<blockquote><code>PerlSwitches -w -T -I/var/www/html/bugzilla
+ -I/var/www/html/bugzilla/lib</code></blockquote>
+
+<p>Now should be only:</p>
+
+<blockquote><code>PerlSwitches -w -T</code></blockquote>
+
+<p>The <code>PerlConfigRequire</code> line should stay the same, however.</p>
+
+<h3>New .htaccess file</h3>
+
+<p>In previous versions of [% terms.Bugzilla %], there was a file
+ in [% terms.Bugzilla %]'s root directory called ".htaccess" that was
+ generated by <kbd>checksetup.pl</kbd>. This file is now shipped with
+ [%+ terms.Bugzilla %] instead of being generated during installation.</p>
+
+<p>If you update via CVS or bzr, you will get a message that your existing
+ .htaccess file conflicts with the new one. You must
+ <strong>remove your existing .htaccess file</strong> and use the new one
+ instead. Continuing to use your old .htaccess file will cause certain new
+ features of [% terms.Bugzilla %] to not work properly, and may also lead
+ to security issues for your system in the future.</p>
+
+<h2 id="v40_code_changes">Code Changes Which May Affect Customizations and
+ Extensions</h2>
+
+<ul>
+ <li>In Extensions, if you want to serve files to the user via the web,
+ they must now be in a <kbd>web/</kbd> subdirectory of your Extension.
+ (For example, <kbd>extensions/Foo/web/</kbd>). <kbd>checksetup.pl</kbd>
+ sets permissions on extensions much more strictly now, and files in
+ other locations (such as your base <kbd>extensions/Foo/</kbd> directory)
+ will no longer be available to [% terms.Bugzilla %] users via the web
+ under certain configurations.</li>
+ <li>Previous versions of [% terms.Bugzilla %] used to allow putting a
+ single file into the "skins" directory and having that be an entire
+ skin. That is no longer allowed, and on upgrade, <kbd>checksetup.pl</kbd>
+ will convert any such skins into a directory with a single
+ <kbd>global.css</kbd> file in them.</li>
+ <li>When updating [% terms.bugs %], you should now use
+ <code>$bug-&gt;set_all</code> instead of using the individual
+ <kbd>set_</kbd> methods. In particular, <kbd>set_all</kbd> is now the
+ <em>only</em> way to set the product of [% terms.abug %]. See
+ <kbd>process_bug.cgi</kbd> for an example of how <kbd>set_all</kbd>
+ should be used.</li>
+ <li>You should not insert &lt;script&gt; tags and &lt;link&gt; CSS tags
+ into HTML anymore, in Extensions or in your customizations. Instead,
+ you should push new values into the <kbd>style_urls</kbd> or
+ <kbd>javascript_urls</kbd> parameters. If you have to insert manual
+ tags for some reason, be sure to call "FILTER mtime" on the URL. (Search
+ for other uses of "FILTER mtime" in the templates to see how it is
+ used.)</li>
+ <li>When calling <kbd>Bugzilla::BugMail::Send</kbd>, the "changer"
+ argument must now be a <kbd>Bugzilla::User</kbd> object, not just
+ a login name. The "owner" and "qacontact" arguments are still
+ just login names.</li>
+ <li>When creating a new subclass of Bugzilla::Object, you should no
+ longer use <kbd>UPDATE_VALIDATORS</kbd>. Also, in most cases you will
+ no longer need to override <kbd>run_create_validators</kbd>. Instead,
+ there is a new constant called
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/Object.html#VALIDATOR_DEPENDENCIES">VALIDATOR_DEPENDENCIES</a>,
+ that specifies that certain fields have to be validated before other fields.
+ Then, all validators receive each already-validated value in a hash
+ as their fourth argument, so each validator can know the other values
+ that were passed in, while an object is being created. For an example of
+ how to use <kbd>VALIDATOR_DEPENDENCIES</kbd>, see
+ <kbd>Bugzilla/Field.pm</kbd>.</li>
+ <li>In previous versions of [% terms.Bugzilla %], you had to call
+ <code>Bugzilla-&gt;template_inner("")</code> after any time
+ that you called <kbd>template_inner</kbd> for a specific language.
+ It is no longer necessary to do this second <kbd>template_inner</kbd>
+ call.</li>
+ <li><kbd>post_bug.cgi</kbd> and <kbd>Bugzilla::Bug-&gt;create</kbd> now take
+ the <em>names</em> of groups instead of group ids.</li>
+ <li>Bugzilla::Bugmail now uses Bugzilla::Bug objects internally instead of
+ a lot of direct SQL.</li>
+ <li>For sending changes about [% terms.bugs %], there is now a method
+ called <kbd>send_changes</kbd> that you can call on Bugzilla::Bug
+ objects. For an example of its use, see <kbd>process_bug.cgi</kbd>.</li>
+ <li>The <kbd>Bugzilla::Search</kbd> class has been refactored, and should
+ now be easier to customize.</li>
+ <li>The <kbd>Bugzilla::Util::lsearch</kbd> function is gone. Use
+ <kbd>firstidx</kbd> from <kbd>List::MoreUtils</kbd>, instead.</li>
+ <li>[% terms.Bugzilla %] now includes YUI 2.8.2.</li>
+ <li><kbd>long_list.cgi</kbd>, <kbd>showattachment.cgi</kbd> and
+ <kbd>xml.cgi</kbd> are deprecated scripts which are no longer actively
+ used since [% terms.Bugzilla %] 2.19. These scripts will be removed in
+ [%+ terms.Bugzilla %] 4.2.</li>
+</ul>
+
+<h2 id="v40_previous">Release Notes For Previous Versions</h2>
+
+<p><a href="page.cgi?id=release-notes3.html">Release Notes for
+ [%+ terms.Bugzilla %] 3.x and Earlier</a></p>
+
+[% INCLUDE global/footer.html.tmpl %]
+
+[% BLOCK db_req %]
+ [% SET m = DB_MODULE.$db %]
+ <h3 id="v40_req_[% db FILTER html %]">For [% m.name FILTER html %] Users</h3>
+
+ <ul>
+ <li>[% m.name FILTER html %]
+ [%+ '<span class="req_new">' IF db_new %]v[% m.db_version FILTER html %]
+ [% '</span>' IF db_new %]
+ </li>
+ <li><strong>perl module:</strong>
+ [%+ m.dbd.module FILTER html %]
+ [% '<span class="req_new">' IF dbd_new %]v[% m.dbd.version FILTER html %]
+ [% '</span>' IF dbd_new %]</li>
+ </ul>
+[% END %]
+
+
+[% BLOCK req_table %]
+ <table class="req_table" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <th>Module</th> <th>Version</th>
+ [% IF include_feature %]
+ <th>Enables Feature</th>
+ [% END %]
+ </tr>
+ [% FOREACH req = reqs %]
+ <tr>
+ <td [% ' class="req_new"' IF new.contains(req.package) %]>
+ [%- req.module FILTER html %]</td>
+ <td [% ' class="req_new"' IF updated.contains(req.package)
+ OR new.contains(req.package) %]>
+ [%- IF req.version == 0 %]
+ (Any)
+ [% ELSE %]
+ [%- req.version FILTER html %]
+ [% END %]
+ </td>
+ [% IF include_feature %]
+ <td>[% req.feature.join(', ') FILTER html %]</td>
+ [% END %]
+ </tr>
+ [% END %]
+</table>
+[% END %]
diff --git a/template/en/default/pages/release-notes3.html.tmpl b/template/en/default/pages/release-notes3.html.tmpl
new file mode 100644
index 0000000..8d6ada5
--- /dev/null
+++ b/template/en/default/pages/release-notes3.html.tmpl
@@ -0,0 +1,3474 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% SET title = "$terms.Bugzilla 3.6 Release Notes" %]
+[% INCLUDE global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/page.css']
+%]
+
+<h3>Release Notes For Newer Versions</h3>
+
+<p>Release notes for versions of [% terms.Bugzilla %] of the 4.x series are
+ available <a href="page.cgi?id=release-notes.html">here</a>.</p>
+
+<h1>[% title FILTER html %]</h1>
+
+<ul class="bz_toc">
+ <li><a href="#v36_introduction">Introduction</a></li>
+ <li><a href="#v36_point">Updates in this 3.6.x Release</a></li>
+ <li><a href="#v36_req">Minimum Requirements</a></li>
+ <li><a href="#v36_feat">New Features and Improvements</a></li>
+ <li><a href="#v36_issues">Outstanding Issues</a></li>
+ <li><a href="#v36_upgrading">Notes On Upgrading From a Previous Version</a></li>
+ <li><a href="#v36_code_changes">Code Changes Which May Affect
+ Customizations</a></li>
+ <li><a href="#v36_previous">Release Notes for Previous Versions</a></li>
+</ul>
+
+<h2 id="v36_introduction">Introduction</h2>
+
+<p>Welcome to [% terms.Bugzilla %] 3.6! The focus of the 3.6 release is
+ on improving usability and "polishing up" all our features (by adding
+ some pieces that were "missing" or always wanted), although we
+ also have a few great new features for you, as well!</p>
+
+<p>If you're upgrading, make sure to read <a href="#v36_upgrading">Notes
+ On Upgrading From a Previous Version</a>. If you are upgrading from a release
+ before 3.4, make sure to read the release notes for all the
+ <a href="#v36_previous">previous versions</a> in between your version
+ and this one, <strong>particularly the Upgrading section of each
+ version's release notes</strong>.</p>
+
+<p>We would like to thank <a href="http://www.canonical.com/">Canonical
+ Ltd.</a>, <a href="http://www.itasoftware.com/">ITA Software</a>,
+ the <a href="http://www.ibm.com/linux/ltc/">IBM Linux Technology Center</a>,
+ <a href="http://www.redhat.com/">Red Hat</a>, and
+ <a href="http://www.novell.com/">Novell</a> for funding the development
+ of various features and improvements in this release of
+ [%+ terms.Bugzilla %].</p>
+
+<h2 id="v36_point">Updates in this 3.6.x Release</h2>
+
+<h3>3.6.2</h3>
+
+<p>This release fixes various security issues. See the
+ <a href="http://www.bugzilla.org/security/3.2.7/">Security Advisory</a>
+ for details.</p>
+
+<p>In addition, the following important fixes/changes have been made in
+ this release:</p>
+
+<ul>
+ <li>[% terms.Bugzilla %] installations running on older versions of IIS
+ will no longer experience the "Undef to trick_taint" errors that would
+ sometimes occur.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=521416">[% terms.Bug %] 521416</a>)
+ </li>
+ <li>Email notifications were missing the dates that comments were made.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=578003">[% terms.Bug %] 578003</a>)
+ </li>
+ <li>Putting a phrase in quotes in the Quicksearch box now works properly,
+ again.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=578494">[% terms.Bug %] 578494</a>
+ and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=553884">[% terms.Bug %] 553884</a>)
+ </li>
+ <li>Quicksearch was usually (incorrectly) being limited to 200 results.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=581622">[% terms.Bug %] 581622</a>)
+ </li>
+ <li>On Windows, <kbd>install-module.pl</kbd> can now properly install
+ DateTime and certain other Perl modules that didn't install properly
+ before.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=576105">[% terms.Bug %] 576105</a>)
+ </li>
+ <li>Searching "keywords" for "contains none of the words" or "does not
+ match regular expression" now works properly.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=562014">[% terms.Bug %] 562014</a>)
+ </li>
+ <li>Doing <kbd>collectstats.pl --regenerate</kbd> now works on installations
+ using PostgreSQL.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=577058">[% terms.Bug %] 577058</a>)
+ </li>
+ <li>The "Field Values" administrative control panel was sometimes denying
+ admins the ability to delete field values when there was no reason
+ to deny the deletion.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=577054">[% terms.Bug %] 577054</a>)
+ </li>
+ <li>Eliminate the "uninitialized value" warnings that would happen when
+ editing a product's components.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=576911">[% terms.Bug %] 576911</a>)
+ </li>
+ <li>The updating of bugs_fulltext that happens during
+ <kbd>checksetup.pl</kbd> for upgrades to 3.6 should now be MUCH faster.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=577754">[% terms.Bug %] 577754</a>)
+ </li>
+ <li><kbd>email_in.pl</kbd> was not allowing the setting of time-tracking
+ fields via inbound emails.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=583622">[% terms.Bug %] 583622</a>)
+ </li>
+</ul>
+
+<h3>3.6.1</h3>
+
+<p>This release fixes two security issues. See the
+ <a href="http://www.bugzilla.org/security/3.2.6/">Security Advisory</a>
+ for details.</p>
+
+<p>In addition, the following important fixes/changes have been made in
+ this release:</p>
+
+<ul>
+ <li>Using the "Change Columns" page would sometimes result in a
+ plain-text page instead of HTML.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=376044">[% terms.Bug %] 376044</a>)
+ </li>
+ <li>Extensions that have only templates and no code are now working.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=562551">[% terms.Bug %] 562551</a>)
+ </li>
+ <li><kbd>install-module.pl</kbd> has been fixed so that it installs
+ modules properly on both new and old versions of Perl.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=560318">[% terms.Bug %] 560318</a>
+ and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=560330">[% terms.Bug %] 560330</a>)
+ </li>
+ <li>It is now possible to upgrade from 3.4 to 3.6 when using Oracle.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=561379">[% terms.Bug %] 561379</a>)
+ </li>
+ <li>Editing a field value's name (using the Field Values admin control
+ panel) wasn't working if the value was set as the default for that
+ field.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=561296">[% terms.Bug %] 561296</a>)
+ </li>
+ <li>If you had the <kbd>noresolveonopenblockers</kbd> parameter set,
+ [%+ terms.bugs %] couldn't be edited at all if they were marked FIXED
+ and had any open blockers. (The parameter is only supposed to prevent
+ <em>changing</em> [% terms.bugs %] to FIXED, not modifying already-FIXED
+ [%+ terms.bugs %].)
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=565314">[% terms.Bug %] 565314</a>)
+ </li>
+ <li>Some minor issues with Perl 5.12 were fixed (mostly warnings that Perl
+ 5.12 was throwing). [% terms.Bugzilla %] now supports Perl 5.12.</li>
+</ul>
+
+<h2 id="v36_req">Minimum Requirements</h2>
+
+<p>Any requirements that are new since 3.4.5 will look like
+ <span class="req_new">this</span>.</p>
+
+<ul>
+ <li><a href="#v36_req_perl">Perl</a></li>
+ <li><a href="#v36_req_mysql">For MySQL Users</a></li>
+ <li><a href="#v36_req_pg">For PostgreSQL Users</a></li>
+ <li><a href="#v36_req_oracle">For Oracle Users</a></li>
+ <li><a href="#v36_req_modules">Required Perl Modules</a></li>
+ <li><a href="#v36_req_optional_mod">Optional Perl Modules</a></li>
+</ul>
+
+<h3 id="v36_req_perl">Perl</h3>
+
+<p>Perl v5.8.1</p>
+
+<h3 id="v36_req_mysql">For MySQL Users</h3>
+
+ <ul>
+ <li>MySQL
+ v4.1.2
+ </li>
+ <li><strong>perl module:</strong>
+ DBD::mysql v4.00</li>
+ </ul>
+
+<h3 id="v36_req_pg">For PostgreSQL Users</h3>
+
+ <ul>
+ <li>PostgreSQL
+ v8.00.0000
+ </li>
+ <li><strong>perl module:</strong>
+ DBD::Pg v1.45</li>
+ </ul>
+<h3 id="v36_req_oracle">For Oracle Users</h3>
+
+ <ul>
+ <li>Oracle
+ v10.02.0
+ </li>
+ <li><strong>perl module:</strong>
+ DBD::Oracle v1.19</li>
+ </ul>
+
+<h3 id="v36_req_modules">Required Perl Modules</h3>
+
+<table class="req_table" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <th>Module</th> <th>Version</th>
+ </tr>
+ <tr>
+ <td >CGI</td>
+ <td >3.21
+ </td>
+ </tr>
+ <tr>
+ <td >Digest::SHA</td>
+ <td >
+ (Any)
+ </td>
+ </tr>
+ <tr>
+ <td >Date::Format</td>
+ <td >2.21
+ </td>
+ </tr>
+ <tr>
+ <td >DateTime</td>
+ <td >0.28
+ </td>
+ </tr>
+ <tr>
+ <td >DateTime::TimeZone</td>
+ <td >0.71
+ </td>
+ </tr>
+ <tr>
+ <td >DBI</td>
+ <td >1.41
+ </td>
+ </tr>
+ <tr>
+ <td >Template</td>
+ <td >2.22
+ </td>
+ </tr>
+ <tr>
+ <td >Email::Send</td>
+ <td >2.00
+ </td>
+ </tr>
+ <tr>
+ <td >Email::MIME</td>
+ <td >1.861
+ </td>
+ </tr>
+ <tr>
+ <td >Email::MIME::Encodings</td>
+ <td >1.313
+ </td>
+ </tr>
+ <tr>
+ <td >Email::MIME::Modifier</td>
+ <td >1.442
+ </td>
+ </tr>
+ <tr>
+ <td >URI</td>
+ <td >
+ (Any)
+ </td>
+ </tr>
+</table>
+
+<h3 id="v36_req_optional_mod">Optional Perl Modules</h3>
+
+<p>The following perl modules, if installed, enable various
+ features of [% terms.Bugzilla %]:</p>
+
+<table class="req_table" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <th>Module</th> <th>Version</th>
+ <th>Enables Feature</th>
+ </tr>
+ <tr>
+ <td >GD</td>
+ <td >1.20
+ </td>
+ <td>Graphical Reports, New Charts, Old Charts</td>
+ </tr>
+ <tr>
+ <td >Chart::Lines</td>
+ <td class="req_new">2.1
+ </td>
+ <td>New Charts, Old Charts</td>
+ </tr>
+ <tr>
+ <td >Template::Plugin::GD::Image</td>
+ <td >
+ (Any)
+ </td>
+ <td>Graphical Reports</td>
+ </tr>
+ <tr>
+ <td >GD::Text</td>
+ <td >
+ (Any)
+ </td>
+ <td>Graphical Reports</td>
+ </tr>
+ <tr>
+ <td >GD::Graph</td>
+ <td >
+ (Any)
+ </td>
+ <td>Graphical Reports</td>
+ </tr>
+ <tr>
+ <td >XML::Twig</td>
+ <td >
+ (Any)
+ </td>
+ <td>Move [% terms.Bugs %] Between Installations,
+ Automatic Update Notifications</td>
+ </tr>
+ <tr>
+ <td >MIME::Parser</td>
+ <td >5.406
+ </td>
+ <td>Move [% terms.Bugs %] Between Installations</td>
+ </tr>
+ <tr>
+ <td >LWP::UserAgent</td>
+ <td >
+ (Any)
+ </td>
+ <td>Automatic Update Notifications</td>
+ </tr>
+ <tr>
+ <td >PatchReader</td>
+ <td >0.9.4
+ </td>
+ <td>Patch Viewer</td>
+ </tr>
+ <tr>
+ <td >Net::LDAP</td>
+ <td >
+ (Any)
+ </td>
+ <td>LDAP Authentication</td>
+ </tr>
+ <tr>
+ <td >Authen::SASL</td>
+ <td >
+ (Any)
+ </td>
+ <td>SMTP Authentication</td>
+ </tr>
+ <tr>
+ <td >Authen::Radius</td>
+ <td >
+ (Any)
+ </td>
+ <td>RADIUS Authentication</td>
+ </tr>
+ <tr>
+ <td >SOAP::Lite</td>
+ <td >0.710.06
+ </td>
+ <td>XML-RPC Interface</td>
+ </tr>
+ <tr>
+ <td class="req_new">JSON::RPC</td>
+ <td class="req_new">
+ (Any)
+ </td>
+ <td>JSON-RPC Interface</td>
+ </tr>
+ <tr>
+ <td class="req_new">Test::Taint</td>
+ <td class="req_new">
+ (Any)
+ </td>
+ <td>JSON-RPC Interface, XML-RPC Interface</td>
+ </tr>
+ <tr>
+ <td >HTML::Parser</td>
+ <td >3.40
+ </td>
+ <td>More HTML in Product/Group Descriptions</td>
+ </tr>
+ <tr>
+ <td >HTML::Scrubber</td>
+ <td >
+ (Any)
+ </td>
+ <td>More HTML in Product/Group Descriptions</td>
+ </tr>
+ <tr>
+ <td >Email::MIME::Attachment::Stripper</td>
+ <td >
+ (Any)
+ </td>
+ <td>Inbound Email</td>
+ </tr>
+ <tr>
+ <td >Email::Reply</td>
+ <td >
+ (Any)
+ </td>
+ <td>Inbound Email</td>
+ </tr>
+ <tr>
+ <td >TheSchwartz</td>
+ <td >
+ (Any)
+ </td>
+ <td>Mail Queueing</td>
+ </tr>
+ <tr>
+ <td >Daemon::Generic</td>
+ <td >
+ (Any)
+ </td>
+ <td>Mail Queueing</td>
+ </tr>
+ <tr>
+ <td >mod_perl2</td>
+ <td >1.999022
+ </td>
+ <td>mod_perl</td>
+ </tr>
+</table>
+
+<h2 id="v36_feat">New Features and Improvements</h2>
+
+<ul>
+ <li><a href="#v36_feat_usability">General Usability Improvements</a></li>
+ <li><a href="#v36_feat_extensions">New Extensions System</a></li>
+ <li><a href="#v36_feat_qs">Improved Quicksearch</a></li>
+ <li><a href="#v36_feat_browse">Simple "Browse" Interface</a></li>
+ <li><a href="#v36_feat_suexec">SUExec Support</a></li>
+ <li><a href="#v36_feat_mpwindows">Experimental mod_perl Support on Windows</a></li>
+ <li><a href="#v36_email_attachments">Send Attachments by Email</a></li>
+ <li><a href="#v36_feat_jsonrpc">JSON-RPC Interface</a></li>
+ <li><a href="#v36_feat_migrate">Migration From Other [% terms.Bug %]-Trackers</a></li>
+ <li><a href="#v36_feat_other">Other Enhancements and Changes</a></li>
+</ul>
+
+<h3 id="v36_feat_usability">General Usability Improvements</h3>
+
+<p>A <a href="https://wiki.mozilla.org/Bugzilla:CMU_HCI_Research_2008">scientific
+ usability study</a> was done on [% terms.Bugzilla %] by researchers
+ from Carnegie-Mellon University. As a result of this study,
+ <a href="https://bugzilla.mozilla.org/showdependencytree.cgi?id=490786&amp;hide_resolved=0">several
+ usability issues</a> were prioritized to be fixed, based on specific data
+ from the study.</p>
+
+<p>As a result, you will see many small improvements in [% terms.Bugzilla %]'s
+ usability, such as using Javascript to validate certain forms before
+ they are submitted, standardizing the words that we use in the user interface,
+ being clearer about what [% terms.Bugzilla %] needs from the user,
+ and other changes, all of which are also listed individually in this New
+ Features section.</p>
+
+<p>Work continues on improving usability for the next release of
+ [%+ terms.Bugzilla %], but the results of the research have already
+ had an impact on this 3.6 release.</p>
+
+<h3 id="v36_feat_extensions">New Extensions System</h3>
+
+<p>[% terms.Bugzilla %] has a brand-new Extensions system. The system is
+ consistent, fast, and
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/Extension.html">fully
+ documented</a>. It makes it possible to easily extend [% terms.Bugzilla %]'s
+ code and user interface to add new features or change existing features.
+ There's even
+ <a href="[% docs_urlbase FILTER html %]api/extensions/create.html">a
+ script</a> that will create the basic layout of an extension for you, to
+ help you get started. For more information about the new system, see the
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/Extension.html">Extensions
+ documentation</a>.</p>
+
+<p>If you had written any extensions using [% terms.Bugzilla %]'s previous
+ extensions system, there is
+ <a href="[% docs_urlbase FILTER html %]api/contrib/extension-convert.html">a
+ script to help convert old extensions into the new format</a>.</p>
+
+<h3 id="v36_feat_qs">Improved Quicksearch</h3>
+
+<p>The "quicksearch" box that appears on the front page of
+ [%+ terms.Bugzilla %] and in the header/footer of every page
+ is now simplified and made more powerful. There is a
+ <kbd>[?]</kbd> link next to the box that will take you to
+ the simplified <a href="page.cgi?id=quicksearch.html">Quicksearch Help</a>,
+ which describes every single feature of the system in a simple layout,
+ including new features such as the ability to use partial field names
+ when searching.</p>
+
+<p>Quicksearch should also be much faster than it was before, particularly
+ on large installations.</p>
+
+<p>Note that in order to implement the new quicksearch, certain old
+ and rarely-used features had to be removed:
+
+<ul>
+ <li><b>+</b> as a prefix to mean "search additional resolutions", and
+ <b>+</b> as a prefix to mean "search just the summary". You can
+ instead use <kbd>summary:</kbd> to explicitly search summaries.</li>
+ <li>Searching the [% field_descs.bug_severity FILTER html %] field if you
+ type something that matches the first few characters of a [%
+ field_descs.bug_severity FILTER html %]. You can explicitly
+ search the [% field_descs.bug_severity FILTER html %] field if you want to
+ find [% terms.bugs %] by [% field_descs.bug_severity FILTER html %].</li>
+ <li>Searching the Priority field if you typed something that exactly
+ matched the name of a priority. You can explicitly search the
+ Priority field if you want to find [% terms.bugs %] by priority.</li>
+ <li>Searching the [% field_descs.rep_platform FILTER html %] and OS fields
+ if you typed in one of a certain hard-coded list of strings (like "pc",
+ "windows", etc.). You can explicitly search these fields, instead, if you want
+ to find [% terms.bugs %] with a specific [% field_descs.rep_platform
+ FILTER html %] or OS set.</li>
+</ul>
+
+<h3 id="v36_feat_browse">Simple "Browse" Interface</h3>
+
+<p>There is now a "Browse" link in the header of each [% terms.Bugzilla %]
+ page that presents a very basic interface that allows users to simply
+ browse through all open [% terms.bugs %] in particular components.</p>
+
+<h3 id="v36_feat_suexec">SUExec Support</h3>
+
+<p>[% terms.Bugzilla %] can now be run in Apache's "SUExec" mode,
+ which is what control panel software like cPanel and Plesk use
+ (so [% terms.Bugzilla %] should now be much easier to install
+ on shared hosting). SUExec support shows up as an option
+ in the <kbd>localconfig</kbd> file during installation.</p>
+
+<h3 id="v36_feat_mpwindows">Experimental mod_perl Support on Windows</h3>
+
+<p>There is now experimental support for running [% terms.Bugzilla %]
+ under mod_perl on Windows, for a significant performance enhancement
+ (in exchange for using more memory).</p>
+
+<h3 id="v36_email_attachments">Send Attachments by Email</h3>
+
+<p>The <a href="[% docs_urlbase FILTER html %]api/email_in.html">email_in</a>
+ script now supports attaching multiple attachments to [% terms.abug %]
+ by email, both when filing and when updating [% terms.abug %].</p>
+
+<h3 id="v36_feat_jsonrpc">JSON-RPC Interface</h3>
+
+<p>[% terms.Bugzilla %] now has support for the
+ <a href="http://json-rpc.org/">JSON-RPC</a> WebServices protocol via
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/Server/JSONRPC.html">jsonrpc.cgi</a>.
+ The JSON-RPC interface is experimental in this release--if you want any
+ fundamental changes in how it works,
+ <a href="http://www.bugzilla.org/developers/reporting_bugs.html">let us
+ know</a>, for the next release of [% terms.Bugzilla %].</p>
+
+<h3 id="v36_feat_migrate">Migration From Other [% terms.Bug %]-Trackers</h3>
+
+<p>[% terms.Bugzilla %] 3.6 comes with a new script,
+ <a href="[% docs_urlbase FILTER html %]api/migrate.html">migrate.pl</a>,
+ which allows migration from other [% terms.bug %]-tracking systems.
+ Among the various features of the migration system are:</p>
+
+<ul>
+ <li>It is non-destructive--you can migrate into an existing
+ [%+ terms.Bugzilla %] installation without destroying any data
+ in the installation.</li>
+ <li>It has a "dry-run" mode so you can test your migration
+ before actually running it.</li>
+ <li>It is relatively easy to write new migrators for new systems,
+ if you know Perl. The basic migration framework does most of the work
+ for you, you just have to provide it with the data from your
+ [%+ terms.bug %]-tracker. See the
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/Migrate.html">Bugzilla::Migrate</a>
+ documentation and see our current migrator,
+ <kbd>Bugzilla/Migrate/GNATS.pm</kbd> for information on how to make your
+ own migrator.</li>
+</ul>
+
+<p>The first migrator that has been implemented is for the GNATS
+ [%+ terms.bug %]-tracking system. We'd love to see migrators for
+ other systems! If you want to contribute a new migrator, see our
+ <a href="http://wiki.mozilla.org/Bugzilla:Developers">development
+ process</a> for details on how to get code into [% terms.Bugzilla %].</p>
+
+<p>Thanks to <a href="http://lambdares.com/">Lambda Research</a> for
+ funding the initial development of this feature.</p>
+
+<h3 id="v36_feat_other">Other Enhancements and Changes</h3>
+
+<h4>Enhancements for Users</h4>
+
+<ul>
+ <li><b>[% terms.Bug %] Filing:</b> When filing [% terms.abug %],
+ [%+ terms.Bugzilla %] now visually indicates which fields are
+ mandatory.</li>
+ <li><b>[% terms.Bug %] Filing:</b> "Bookmarkable templates" now
+ support the "alias" and "estimated hours" fields.</li>
+
+ <li><b>[% terms.Bug %] Editing:</b> In previous versions of
+ [%+ terms.Bugzilla %], if you added a private comment to [% terms.abug %],
+ then <em>none</em> of the changes that you made at that time were
+ sent to users who couldn't see the private comment. Now, for users
+ who can't see private comments, public changes are sent, but the private
+ comment is excluded from their email notification.</li>
+ <li><b>[% terms.Bug %] Editing:</b> The controls for groups now
+ appear to the right of the attachment and time-tracking tables,
+ when editing [% terms.abug %].</li>
+ <li><b>[% terms.Bug %] Editing:</b> The "Collapse All Comments"
+ and "Expand All Comments" links now appear to the right of the
+ comment list instead of above it.</li>
+ <li><b>[% terms.Bug %] Editing:</b> The See Also field now supports
+ URLs for Google Code Issues and the Debian B[% %]ug-Tracking System.</li>
+ <li><b>[% terms.Bug %] Editing:</b> There have been significant performance
+ improvements in <kbd>show_bug.cgi</kbd> (the script that displays the
+ [% terms.bug %]-editing form), particularly for [% terms.bugs %] that
+ have lots of comments or attachments.</li>
+
+ <li><b>Attachments:</b> The "Details" page of an attachment
+ now displays itself as uneditable if you can't edit the fields
+ there.</li>
+ <li><b>Attachments:</b> We now make sure that there is
+ a Description specified for an attachment, using JavaScript, before
+ the form is submitted.</li>
+ <li><b>Attachments:</b> There is now a link back to the [% terms.bug %]
+ at the bottom of the "Details" page for an attachment.</li>
+ <li><b>Attachments:</b> When you click on an "attachment 12345" link
+ in a comment, if the attachment is a patch, you will now see the
+ formatted "Diff" view instead of the raw patch.</li>
+ <li><b>Attachments</b>: For text attachments, we now let the browser
+ auto-detect the character encoding, instead of forcing the browser to
+ always assume the attachment is in UTF-8.</li>
+
+ <li><b>Search:</b> You can now display [% terms.bug %] flags as a column
+ in search results.</li>
+ <li><b>Search:</b> When viewing search results, you can see which columns are
+ being sorted on, and which direction the sort is on, as indicated
+ by arrows next to the column headers.</li>
+ <li><b>Search:</b> You can now search the Deadline field using relative
+ dates (like "1d", "2w", etc.).</li>
+ <li><b>Search:</b> The iCalendar format of search results now includes
+ a PRIORITY field.</li>
+ <li><b>Search:</b> It is no longer an error to enter an invalid search
+ order in a search URL--[% terms.Bugzilla %] will simply warn you that
+ some of your order options are invalid.</li>
+ <li><b>Search:</b> When there are no search results, some helpful
+ links are displayed, offering actions you might want to take.</li>
+ <li><b>Search:</b> For those who like to make their own
+ <kbd>buglist.cgi</kbd> URLs (and for people working on customizations),
+ <kbd>buglist.cgi</kbd> now accepts nearly every valid field in
+ [%+ terms.Bugzilla %] as a direct URL parameter, like
+ <kbd>&amp;field=value</kbd>.</li>
+
+ <li><b>Requests:</b> When viewing the "My Requests" page, you can now
+ see the lists as a normal search result by clicking a link at the
+ bottom of each table.</li>
+ <li><b>Requests:</b> When viewing the "My Requests" page, if you are
+ using Classifications, the Product drop-down will be grouped by
+ Classification.</li>
+
+ <li><b>Inbound Email:</b> When filing [% terms.abug %] by email, if the
+ product that you are filing the [% terms.bug %] into has some groups
+ set as Default for you, the [% terms.bug %] will now be placed into those
+ groups automatically.</li>
+ <li><b>Inbound Email:</b> The field names that can be used when creating
+ [%+ terms.bugs %] by email now exactly matches the set of valid parameters
+ to the
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/Bug.html#create">B[% %]ug.create
+ WebService function</a>. You can still use most of the old field names
+ that 3.4 and earlier used for inbound emails, though, for
+ backwards-compatibility.</li>
+
+ <li>If there are multiple languages available for your
+ [%+ terms.Bugzilla %], you can now select what language you want
+ [%+ terms.Bugzilla %] displayed in using links at the top of every
+ page.</li>
+ <li>When creating a new account, you will be automatically logged in
+ after setting your password.</li>
+ <li>There is no longer a maximum password length for accounts.</li>
+ <li>In the Dusk skin, it's now easier to see links.</li>
+ <li>In the Whining system, you can now choose to receive emails even
+ if there are no [% terms.bugs %] that match your searches.</li>
+ <li>The arrows in dependency graphs now point the other way, so that
+ [%+ terms.bugs %] point at their dependencies.</li>
+
+ <li><b>New Charts:</b> You can now convert an existing Saved Search
+ into a data series for New Charts.</li>
+ <li><b>New Charts:</b> There is now an interface that allows you to
+ delete data series.</li>
+ <li><b>New Charts:</b> When deleting a product, you now have the option
+ to delete the data series that are associated with that product.</li>
+</ul>
+
+<h4>Enhancements for Administrators and Developers</h4>
+
+<ul>
+ <li>Depending on how your workflow is set up, it is now possible to
+ have both UNCONFIRMED and REOPENED show up as status choices for
+ a closed [% terms.bug %]. If you only want one or the other to
+ show up, you should edit your status workflow appropriately
+ (possibly by removing or disabling the REOPENED status).</li>
+ <li>You can now "disable" field values so that they don't show
+ up as choices on [% terms.abug %] unless they are already set as
+ the value for that [% terms.bug %]. This doesn't work for the
+ per-product field values (component, target_milestone, and version)
+ yet, though.</li>
+ <li>Users are now locked out of their accounts for 30 minutes after
+ trying five bad passwords in a row during login. Every time a
+ user is locked out like this, the user in the "maintainer" parameter
+ will get an email.</li>
+ <li>The minimum length allowed for a password is now 6 characters.</li>
+ <li>The <kbd>UNCONFIRMED</kbd> status being enabled in a product
+ is now unrelated to the voting parameters. Instead, there is a checkbox
+ to enable the <kbd>UNCONFIRMED</kbd> status in a product.</li>
+ <li>Information about duplicates is now stored in the database instead
+ of being stored in the <kbd>data/</kbd> directory. On large installations
+ this could save several hundred megabytes of disk space.</li>
+
+ <li><b>Installation:</b> When installing [% terms.Bugzilla %], the
+ "maintainer" parameter will be automatically set to the administrator
+ that was created by <kbd>checksetup.pl</kbd>.</li>
+ <li><b>Installation:</b> <kbd>checksetup.pl</kbd> now prints out
+ certain errors in a special color so that you know that something
+ needs to be done.</li>
+ <li><b>Installation:</b> <kbd>checksetup.pl</kbd> is now <em>much</em>
+ faster at upgrading installations, particularly older installations.
+ Also, it's been made faster to run for the case where it's not
+ doing an upgrade.</li>
+ <li><b>Installation:</b> If you install [% terms.Bugzilla %] using the
+ tarball, the <kbd>CGI.pm</kbd> module from CPAN is now included in
+ the <kbd>lib/</kbd> dir. If you would rather use the CGI.pm from your
+ global Perl installation, you can delete <kbd>CGI.pm</kbd> and the
+ <kbd>CGI</kbd> directory from the <kbd>lib/</kbd> directory.</li>
+
+ <li>When editing a group, you can now specify that members of a group
+ are allowed to grant others membership in that group itself.</li>
+ <li>The ability to compress BMP attachments to PNGs is now an Extension.
+ To enable the feature, remove the file
+ <kbd>extensions/BmpConvert/disabled</kbd> and then run <kbd>checksetup.pl</kbd>.</li>
+ <li>The default list of values for the Priority field are now clear English
+ words instead of P1, P2, etc.</li>
+ <li>There is now a system in place so that all field values can be
+ localized. See the <kbd>value_descs</kbd> variable in
+ <kbd>template/en/default/global/field-descs.none.tmpl</kbd>.</li>
+ <li><kbd>config.cgi</kbd> now returns an ETag header and understands
+ the If-None-Match header in HTTP requests.</li>
+ <li>The XML format of <kbd>show_bug.cgi</kbd> now returns more information:
+ the numeric id of each comment, whether an attachment is a URL,
+ the modification time of an attachment, the numeric id of a flag,
+ and the numeric id of a flag's type.</li>
+
+ <li><b>Parameters:</b> Parameters that aren't actually required are no longer
+ in the "Required" section of the Parameters page. Instead, some are in the
+ new "General" section, and some are in the new "Advanced" section.</li>
+ <li><b>Parameters:</b> The old <kbd>ssl</kbd> parameter has been
+ changed to <kbd>ssl_redirect</kbd>, and can only be turned "on" or "off".
+ If "on", then all users will be forcibly redirected to SSL whenever
+ they access [% terms.Bugzilla %]. When the parameter is off,
+ no SSL-related redirects will occur (even if the user directly
+ accesses [% terms.Bugzilla %] via SSL, they will <em>not</em> be
+ redirected to a non-SSL page).</li>
+ <li><b>Parameters:</b> In the Advanced parameters, there is a new parameter,
+ <kbd>inbound_proxies</kbd>. If your [% terms.Bugzilla %] is behind a
+ proxy, you should set this parameter to the IP address of that proxy.
+ Then, [% terms.Bugzilla %] will "believe" any "X-Forwarded-For"
+ header sent from that proxy, and correctly use the X-Forwarded-For
+ as the end user's IP, instead of believing that all traffic is coming
+ from the proxy.</li>
+
+ <li><b>Removed Parameter:</b> The <kbd>loginnetmask</kbd> parameter has
+ been removed. Since [% terms.Bugzilla %] sends secure cookies, it's no
+ longer necessary to always restrict logins to a specific IP or block
+ of addresses.</li>
+ <li><b>Removed Parameter:</b> The <kbd>quicksearch_comment_cutoff</kbd>
+ parameter is gone. Quicksearch now always searches comments; however, it
+ uses a much faster algorithm to do it.</li>
+ <li><b>Removed Parameter:</b> The <kbd>usermatchmode</kbd> parameter has
+ been removed. User-matching is now <em>always</em> done.</li>
+ <li><b>Removed Parameter:</b> The <kbd>useentrygroupdefault</kbd> parameter
+ has been removed. [% terms.Bugzilla %] now always behaves as though
+ that parameter were off.</li>
+ <li>The <kbd>t/001compile.t</kbd> test should now always pass, no matter
+ what configuration of optional modules you do or don't have installed.</li>
+ <li>New script: <kbd>contrib/console.pl</kbd>, which allows you to have
+ a "command line" into [% terms.Bugzilla %] by inputting Perl code
+ or using a few custom commands.</li>
+</ul>
+
+<h4>WebService Changes</h4>
+
+<ul>
+ <li>The WebService now returns all dates and times in the UTC timezone.
+ <kbd>B[% %]ugzilla.time</kbd> now acts as though the [% terms.Bugzilla %]
+ server were in the UTC timezone, always. If you want to write clients
+ that are compatible across all [% terms.Bugzilla %] versions,
+ check the timezone from <kbd>B[% %]ugzilla.timezone</kbd> or
+ <kbd>B[% %]ugzilla.time</kbd>, and always input times in that timezone
+ and expect times to be returned in that format.</li>
+ <li>You can now log in by passing <kbd>Bugzilla_login</kbd> and
+ <kbd>Bugzilla_password</kbd> as arguments to any WebService function.
+ See the
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService.html#LOGGING_IN">Bugzilla::WebService</a>
+ documentation for details.</li>
+ <li>New Method:
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/Bug.html#attachments">B[% %]ug.attachments</a>
+ which allows getting information about attachments.</li>
+ <li>New Method:
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/Bug.html#fields">B[% %]ug.fields</a>,
+ which gets information about all the fields that [% terms.abug %] can have
+ in [% terms.Bugzilla %], include custom fields and legal values for
+ all fields. The <kbd>B[% %]ug.legal_values</kbd> method is now deprecated.</li>
+ <li>In the <kbd>B[% %]ug.add_comment</kbd> method, the "private" parameter
+ has been renamed to "is_private" (for consistency with other methods).
+ You can still use "private", though, for backwards-compatibility.</li>
+ <li>The WebService now has Perl's "taint mode" turned on. This means that
+ it validates all data passed in before sending it to the database.
+ Also, all parameter names are validated, and if you pass in a parameter
+ whose name contains anything other than letters, numbers, or underscores,
+ that parameter will be ignored. Mostly this just affects
+ customizers--[% terms.Bugzilla %]'s WebService is not functionally
+ affected by these changes.</li>
+ <li>In previous versions of [% terms.Bugzilla %], error messages were
+ sent word-wrapped to the client, from the WebService. Error messages
+ are now sent as one unbroken line.</li>
+</ul>
+
+<h2 id="v36_issues">Outstanding Issues</h2>
+
+<ul>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=423439">
+ [%- terms.Bug %] 423439</a>: Tabs in comments will be converted
+ to four spaces, due to a b<!-- -->ug in Perl as of Perl 5.8.8.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=69621">
+ [%- terms.Bug %] 69621</a>: If you rename or remove a keyword that is
+ in use on [% terms.bugs %], you will need to rebuild the "keyword cache"
+ by running <a href="sanitycheck.cgi">sanitycheck.cgi</a> and choosing
+ the option to rebuild the cache when it asks. Otherwise keywords may
+ not show up properly in search results.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=89822">
+ [%- terms.Bug %] 89822</a>: When changing multiple [% terms.bugs %] at
+ the same time, there is no "mid-air collision" protection.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=276230">
+ [%- terms.Bug %] 276230</a>: The support for restricting access to
+ particular Categories of New Charts is not complete. You should treat
+ the 'chartgroup' Param as the only access mechanism available.<br>
+ However, charts migrated from Old Charts will be restricted to
+ the groups that are marked MANDATORY for the corresponding Product.
+ There is currently no way to change this restriction, and the
+ groupings will not be updated if the group configuration
+ for the Product changes.</li>
+</ul>
+
+<h2 id="v36_upgrading">Notes On Upgrading From a Previous Version</h2>
+
+<p>When upgrading to 3.6, <kbd>checksetup.pl</kbd> will create foreign keys
+ for many columns in the database. Before doing this, it will check the
+ database for consistency. If there are an unresolvable consistency
+ problems, it will tell you what table and column in the database contain
+ the bad values, and which values are bad. If you don't know what else to do,
+ you can always delete the database records which contain the bad values by
+ logging in to your database and running the following command:</p>
+
+<p><code>DELETE FROM <var>table</var> WHERE <var>column</var> IN
+ (<var>1, 2, 3, 4</var>)</code></p>
+
+<p>Just replace "table" and "column" with the name of the table
+ and column that <kbd>checksetup.pl</kbd> mentions, and "1, 2, 3, 4"
+ with the invalid values that <kbd>checksetup.pl</kbd> prints out.</p>
+
+<p>Remember that you should always back up your database before doing
+ an upgrade.</p>
+
+<h2 id="v36_code_changes">Code Changes Which May Affect Customizations</h2>
+
+<ul>
+ <li>There is no longer a SendBugMail method in the templates, and bugmail
+ is no longer sent by processing a template. Instead, it is sent
+ by using <kbd>Bugzilla::BugMail::Send</kbd>.</li>
+ <li>Comments are now represented as a
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/Comment.html">Bugzilla::Comment</a>
+ object instead of just being hashes.</li>
+ <li>In previous versions of [% terms.Bugzilla %], the template for displaying
+ [%+ terms.abug %] required a lot of extra variables that are now global
+ template variables instead.</li>
+ <li>You can now check if optional modules are installed by using
+ <kbd>Bugzilla-&gt;feature</kbd> in Perl code or
+ <kbd>feature_enabled</kbd> in template code.</li>
+ <li>All of the various template header information required to display
+ the [% terms.bug %] form is now in one template,
+ <kbd>template/en/default/bug/show-header.html.tmpl</kbd>.</li>
+ <li>You should now use <kbd>display_value</kbd> instead of
+ <kbd>get_status</kbd> or <kbd>get_resolution</kbd> in templates.
+ <kbd>display_value</kbd> should be used anywhere that a
+ &lt;select&gt;-type field has its values displayed.</li>
+</ul>
+
+
+<h1 id="v36_previous">[% terms.Bugzilla %] 3.4 Release Notes</h1>
+
+<ul class="bz_toc">
+ <li><a href="#v34_introduction">Introduction</a></li>
+ <li><a href="#v34_point">Updates in this 3.4.x Release</a></li>
+ <li><a href="#v34_req">Minimum Requirements</a></li>
+ <li><a href="#v34_feat">New Features and Improvements</a></li>
+ <li><a href="#v34_issues">Outstanding Issues</a></li>
+ <li><a href="#v34_upgrading">Notes On Upgrading From a Previous Version</a></li>
+ <li><a href="#v34_code_changes">Code Changes Which May Affect
+ Customizations</a></li>
+ <li><a href="#v34_previous">Release Notes for Previous Versions</a></li>
+</ul>
+
+<h2 id="v34_introduction">Introduction</h2>
+
+<p>This is [% terms.Bugzilla %] 3.4! [% terms.Bugzilla %] 3.4 brings a lot
+ of great enhancements for [% terms.Bugzilla %] over previous versions,
+ with various improvements to the user interface, lots of interesting new
+ features, and many long-standing requests finally being addressed.</p>
+
+<p>If you're upgrading, make sure to read <a href="#v34_upgrading">Notes
+ On Upgrading From a Previous Version</a>. If you are upgrading from a release
+ before 3.2, make sure to read the release notes for all the
+ <a href="#v34_previous">previous versions</a> in between your version
+ and this one, <strong>particularly the Upgrading section of each
+ version's release notes</strong>.</p>
+
+<p>We would like to thank <a href="http://www.canonical.com/">Canonical
+ Ltd.</a> for funding development of one new feature, and NASA for funding
+ development of several new features through the
+ <a href="http://www.sjsufoundation.org/">San Jose State University
+ Foundation</a>.</p>
+
+<h2 id="v34_point">Updates In This 3.4.x Release</h2>
+
+<h3>3.4.6</h3>
+
+<ul>
+ <li>When doing a search that involves "not equals" or "does not contain the
+ string" or similar "negative" search types, the search description that
+ appears at the top of the resulting [% terms.bug %] list will indicate
+ that the search was of that type.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=474738">[% terms.Bug %] 474738</a>)
+ </li>
+ <li>In Internet Explorer, users couldn't easily mark a RESOLVED DUPLICATE
+ [%+ terms.bug %] as REOPENED, due to a JavaScript error.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=546719">[% terms.Bug %] 546719</a>)
+ </li>
+ <li>If you use a "bookmarkable template" to pre-fill forms on
+ the [% terms.bug %]-filing page, and you have custom fields
+ that are only supposed to appear (or only supposed to have certain
+ values) based on the values of other fields, those custom fields will
+ now work properly.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=538211">[% terms.Bug %] 538211</a>)
+ </li>
+ <li>If you have a custom field that's only supposed to appear when
+ a [% terms.bug %]'s resolution is FIXED, it will now behave properly
+ on the [% terms.bug %]-editing form when a user sets the [% terms.bug %]'s
+ status to RESOLVED.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=520993">[% terms.Bug %] 520993</a>)
+ </li>
+ <li>If you are logged-out and using <kbd>request.cgi</kbd>, the Requester
+ and Requestee fields no longer respect the <kbd>usermatching</kbd>
+ parameter--they always require full usernames.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=533018">[% terms.Bug %] 533018</a>)
+ </li>
+ <li>If you tried to do a search with too many terms (resulting in a URL
+ that was longer than about 7000 characters), Apache would return a
+ 500 error instead of your search results.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=513989">[% terms.Bug %] 513989</a>)
+ </li>
+ <li>[% terms.Bugzilla %] would sometimes lose fields from your sort order
+ when you added new fields to your sort order.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=470214">[% terms.Bug %] 470214</a>)
+ </li>
+ <li>The Atom format of search results would sometimes be missing the
+ Reporter or Assignee field for some [% terms.bugs %].
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=537834">[% terms.Bug %] 537834</a>)
+ </li>
+</ul>
+
+<h3>3.4.5</h3>
+
+<p>This release contains fixes for multiple security issues. See the
+ <a href="http://www.bugzilla.org/security/3.0.10/">Security Advisory</a>
+ for details.</p>
+
+<p>In addition, the following important fixes/changes have been made in
+ this release:</p>
+
+<ul>
+ <li>Whining was failing if jobqueue.pl was enabled.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=530270">[% terms.Bug %] 530270</a>)
+ </li>
+ <li>The Assignee field was empty in Whine mails.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=511216">[% terms.Bug %] 511216</a>)
+ </li>
+ <li>Administrators can now successfully create user accounts using
+ editusers.cgi when using the "Env" authentication method.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=483987">[% terms.Bug %] 483987</a>)
+ </li>
+ <li>[% terms.Bug %]mail now uses the timezone of the recipient of the email,
+ when displaying the time a comment was made, instead of the timezone of the
+ person who made the change.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=534587">[% terms.Bug %] 534587</a>)
+ </li>
+ <li>"[% terms.bug %] 1234" in comments sometimes would not become a link if
+ word-wrapping happened between "[% terms.bug %]" and the number.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=514703">[% terms.Bug %] 514703</a>)
+ </li>
+ <li>Running <kbd>checksetup.pl</kbd> on Windows will no longer pop up an error box
+ about OCI.dll.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=480968">[% terms.Bug %] 480968</a>)
+ </li>
+</ul>
+
+<h3>3.4.4</h3>
+
+<p>This release contains a fix for a security issue. See the
+ <a href="http://www.bugzilla.org/security/3.4.3/">Security Advisory</a>
+ for details.</p>
+
+<p>Additionally, this release fixes a few minor [% terms.bugs %].</p>
+
+<h3>3.4.3</h3>
+
+<ul>
+ <li>[% terms.Bugzilla %] installations running under mod_perl were leaking
+ about 512K of RAM per page load.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=517793">[% terms.Bug %] 517793</a>)
+ </li>
+ <li>Attachments with Unicode characters in their names were being downloaded
+ with mangled names.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=328628">[% terms.Bug %] 328628</a>)
+ </li>
+ <li>Creating custom fields with Unicode in their database column name
+ is now no longer allowed, as it would break [% terms.Bugzilla %]. If you
+ created such a custom field, you should delete it by first marking it
+ obsolete and then clicking "Delete" in the custom field list, using
+ <a href="editfields.cgi">editfields.cgi</a>.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=525025">[% terms.Bug %] 525025</a>)
+ </li>
+ <li>Clicking "submit only my comment" on the "mid-air collisions" page
+ was leading to a "Suspicious Action" warning.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=514378">[% terms.Bug %] 514378</a>)
+ </li>
+ <li>The XML format of [% terms.abug %] accidentally contained the
+ word-wrapped content of comments instead of the unwrapped content.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=509152">[% terms.Bug %] 509152</a>)
+ </li>
+ <li>You can now do <kbd>./install-module.pl --shell</kbd> to get a CPAN
+ shell using the configuration of
+ <a href="[% docs_urlbase FILTER html %]api/install-module.html">install-module.pl</a>,
+ which allows you to do more advanced Perl module installation tasks.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=445875">[% terms.Bug %] 445875</a>)
+ </li>
+</ul>
+
+<h3>3.4.2</h3>
+
+<p>This release contains fixes for multiple security issues, one of which
+ is highly critical. See the
+ <a href="http://www.bugzilla.org/security/3.0.8/">Security Advisory</a>
+ for details.</p>
+
+<p>In addition, the following important fixes/changes have been made in
+ this release:</p>
+
+<ul>
+ <li>Upgrades from older releases were sometimes failing during UTF-8
+ conversion with a foreign key error.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=508181">[% terms.Bug %] 508181</a>)
+ </li>
+ <li>Sorting [% terms.bug %] lists on certain fields would result in an error.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=510944">[% terms.Bug %] 510944</a>)
+ </li>
+ <li>[% terms.Bug %] update emails had two or three blank lines at the top
+ and between the various sections of the email. There is now only one
+ blank line in each of those places, making these emails more compact.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=73330">[% terms.Bug %] 73330</a>)
+ </li>
+ <li>[% terms.Bug %] email notifications for new [% terms.bugs %] incorrectly
+ had a line saying that the description was "Comment 0".
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=510798">[% terms.Bug %] 510798</a>)
+ </li>
+ <li>Running <kbd>./collectstats.pl --regenerate</kbd> is now much faster,
+ on the order of 20x or 100x faster.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=286625">[% terms.Bug %] 286625</a>)
+ </li>
+ <li>For users of RHEL, CentOS, Fedora, etc. jobqueue.pl can now automatically
+ be installed as a daemon by running <kbd>./jobqueue.pl install</kbd>
+ as root.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=475403">[% terms.Bug %] 475403</a>)
+ </li>
+ <li>XML-RPC interface responses had an incorrect Content-Length header
+ and would sometimes be truncated, if they contained certain UTF-8
+ characters.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=486306">[% terms.Bug %] 486306</a>)
+ </li>
+ <li>Users who didn't have access to the time-tracking fields would get an
+ empty [% terms.bug %] update email when the time-tracking fields were
+ changed.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=509035">[% terms.Bug %] 509035</a>)
+ </li>
+ <li>In the New Charts, non-public series now no longer show up as selectable
+ if you cannot access them.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=389396">[% terms.Bug %] 389396</a>)
+ </li>
+</ul>
+
+<h3>3.4.1</h3>
+
+<p>This release contains an important security fix. See the
+ <a href="http://www.bugzilla.org/security/3.4/">Security Advisory</a>
+ for details.</p>
+
+<h2 id="v34_req">Minimum Requirements</h2>
+
+<p>Any requirements that are new since 3.2.3 will look like
+ <span class="req_new">this</span>.</p>
+
+<ul>
+ <li><a href="#v34_req_perl">Perl</a></li>
+ <li><a href="#v34_req_mysql">For MySQL Users</a></li>
+ <li><a href="#v34_req_pg">For PostgreSQL Users</a></li>
+ <li><a href="#v34_req_oracle">For Oracle Users</a></li>
+ <li><a href="#v34_req_modules">Required Perl Modules</a></li>
+ <li><a href="#v34_req_optional_mod">Optional Perl Modules</a></li>
+</ul>
+
+<h3 id="v34_req_perl">Perl</h3>
+
+<p>Perl v5.8.1</p>
+
+<h3 id="v34_req_mysql">For MySQL Users</h3>
+
+<ul>
+ <li>MySQL v4.1.2</li>
+ <li><strong>perl module:</strong> DBD::mysql v4.00</li>
+</ul>
+
+<h3 id="v34_req_pg">For PostgreSQL Users</h3>
+
+<ul>
+ <li>PostgreSQL v8.00.0000</li>
+ <li><strong>perl module:</strong> DBD::Pg v1.45</li>
+</ul>
+
+<h3 id="v34_req_oracle">For Oracle Users</h3>
+
+<ul>
+ <li>Oracle v10.02.0</li>
+ <li><strong>perl module:</strong> DBD::Oracle v1.19</li>
+</ul>
+
+<h3 id="v34_req_modules">Required Perl Modules</h3>
+
+<table class="req_table" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <th>Module</th> <th>Version</th>
+ </tr>
+ <tr>
+ <td>CGI</td>
+ <td>3.21</td>
+ </tr>
+ <tr>
+ <td class="req_new">Digest::SHA</td>
+ <td class="req_new"> (Any)</td>
+ </tr>
+ <tr>
+ <td>Date::Format</td>
+ <td>2.21</td>
+ </tr>
+ <tr>
+ <td class="req_new">DateTime</td>
+ <td class="req_new">0.28</td>
+ </tr>
+ <tr>
+ <td class="req_new">DateTime::TimeZone</td>
+ <td class="req_new">0.71</td>
+ </tr>
+ <tr>
+ <td>DBI</td>
+ <td>1.41</td>
+ </tr>
+ <tr>
+ <td>Template</td>
+ <td class="req_new">2.22</td>
+ </tr>
+ <tr>
+ <td>Email::Send</td>
+ <td>2.00</td>
+ </tr>
+ <tr>
+ <td>Email::MIME</td>
+ <td>1.861</td>
+ </tr>
+ <tr>
+ <td>Email::MIME::Encodings</td>
+ <td>1.313</td>
+ </tr>
+ <tr>
+ <td>Email::MIME::Modifier</td>
+ <td>1.442</td>
+ </tr>
+ <tr>
+ <td class="req_new">URI</td>
+ <td class="req_new">(Any)</td>
+ </tr>
+</table>
+
+<h3 id="v34_req_optional_mod">Optional Perl Modules</h3>
+
+<p>The following perl modules, if installed, enable various
+ features of [% terms.Bugzilla %]:</p>
+
+<table class="req_table" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <th>Module</th>
+ <th>Version</th>
+ <th>Enables Feature</th>
+ </tr>
+ <tr>
+ <td>LWP::UserAgent</td>
+ <td>(Any)</td>
+ <td>Automatic Update Notifications</td>
+ </tr>
+ <tr>
+ <td>Template::Plugin::GD::Image</td>
+ <td>(Any)</td>
+ <td>Graphical Reports</td>
+ </tr>
+ <tr>
+ <td>GD::Text</td>
+ <td>(Any)</td>
+ <td>Graphical Reports</td>
+ </tr>
+ <tr>
+ <td>GD::Graph</td>
+ <td>(Any)</td>
+ <td>Graphical Reports</td>
+ </tr>
+ <tr>
+ <td>GD</td>
+ <td>1.20</td>
+ <td>Graphical Reports, New Charts, Old Charts</td>
+ </tr>
+ <tr>
+ <td>Email::MIME::Attachment::Stripper</td>
+ <td>(Any)</td>
+ <td>Inbound Email</td>
+ </tr>
+ <tr>
+ <td>Email::Reply</td>
+ <td>(Any)</td>
+ <td>Inbound Email</td>
+ </tr>
+ <tr>
+ <td>Net::LDAP</td>
+ <td>(Any)</td>
+ <td>LDAP Authentication</td>
+ </tr>
+ <tr>
+ <td class="req_new">TheSchwartz</td>
+ <td class="req_new">(Any)</td>
+ <td>Mail Queueing</td>
+ </tr>
+ <tr>
+ <td class="req_new">Daemon::Generic</td>
+ <td class="req_new">(Any)</td>
+ <td>Mail Queueing</td>
+ </tr>
+ <tr>
+ <td>HTML::Parser</td>
+ <td>3.40</td>
+ <td>More HTML in Product/Group Descriptions</td>
+ </tr>
+ <tr>
+ <td>HTML::Scrubber</td>
+ <td>(Any)</td>
+ <td>More HTML in Product/Group Descriptions</td>
+ </tr>
+ <tr>
+ <td>XML::Twig</td>
+ <td>(Any)</td>
+ <td>Move [% terms.Bugs %] Between Installations</td>
+ </tr>
+ <tr>
+ <td>MIME::Parser</td>
+ <td>5.406</td>
+ <td>Move [% terms.Bugs %] Between Installations</td>
+ </tr>
+ <tr>
+ <td>Chart::Base</td>
+ <td>1.0</td>
+ <td>New Charts, Old Charts</td>
+ </tr>
+ <tr>
+ <td>Image::Magick</td>
+ <td>(Any)</td>
+ <td>Optionally Convert BMP Attachments to PNGs</td>
+ </tr>
+ <tr>
+ <td>PatchReader</td>
+ <td>0.9.4</td>
+ <td>Patch Viewer</td>
+ </tr>
+ <tr>
+ <td>Authen::Radius</td>
+ <td>(Any)</td>
+ <td>RADIUS Authentication</td>
+ </tr>
+ <tr>
+ <td>Authen::SASL</td>
+ <td>(Any)</td>
+ <td>SMTP Authentication</td>
+ </tr>
+ <tr>
+ <td>SOAP::Lite</td>
+ <td>0.710.06</td>
+ <td>XML-RPC Interface</td>
+ </tr>
+ <tr>
+ <td>mod_perl2</td>
+ <td>1.999022</td>
+ <td>mod_perl</td>
+ </tr>
+</table>
+
+<h2 id="v34_feat">New Features and Improvements</h2>
+
+<ul>
+ <li><a href="#v34_feat_enter">Simple [% terms.Bug %] Filing</a></li>
+ <li><a href="#v34_feat_index">New Home Page</a></li>
+ <li><a href="#v34_feat_spam">Email Addresses Hidden From Logged-Out
+ Users</a></li>
+ <li><a href="#v34_feat_urls">Shorter Search URLs</a></li>
+ <li><a href="#v34_feat_async">Asynchronous Email Sending</a></li>
+ <li><a href="#v34_feat_tz">Dates and Times Displayed In User's Time
+ Zone</a></li>
+ <li><a href="#v34_feat_vis">Custom Fields That Only Appear When
+ Another Field Has a Particular Value</a></li>
+ <li><a href="#v34_feat_vals">Custom Fields Whose List of Values
+ Change Depending on the Value of Another Field</a></li>
+ <li><a href="#v34_feat_bugid">New Custom Field Type:
+ [%+ terms.Bug %] ID</a></li>
+ <li><a href="#v34_feat_see">"See Also" Field</a></li>
+ <li><a href="#v34_feat_cols">Re-order Columns in Search Results</a></li>
+ <li><a href="#v34_feat_desc">Search Descriptions</a></li>
+ <li><a href="#v34_feat_other">Other Enhancements and Changes</a></li>
+</ul>
+
+<h3 id="v34_feat_enter">Simple [% terms.Bug %] Filing</h3>
+
+<p>When entering a new [% terms.bug %], the vast majority of fields are
+ now hidden by default, which enormously simplifies the bug-filing form.
+ You can click "Show Advanced Fields" to show all the fields, if you want
+ them. [%+ terms.Bugzilla %] remembers whether you last used the "Advanced"
+ or "Simple" version of the [% terms.bug %]-entry form, and will display the
+ same version to you again next time you file [% terms.abug %].</p>
+
+<h3 id="v34_feat_index">New Home Page</h3>
+
+<p>[% terms.Bugzilla %]'s front page has been redesigned to be better at
+ guiding new users into the activities that they most commonly want to
+ do. Further enhancements to the home page are coming in future versions
+ of [% terms.Bugzilla %].</p>
+
+<h3 id="v34_feat_spam">Email Addresses Hidden From Logged-Out Users</h3>
+
+<p>To help prevent spam to [% terms.Bugzilla %] users, all email addresses
+ stored in [% terms.Bugzilla %] are now displayed only if you are logged in.
+ If you are logged out, only the part before the "@" of the email address is
+ displayed. This includes [% terms.bug %] lists, viewing [% terms.bugs %], the
+ XML format of [% terms.abug %], and any other place in the web interface that
+ an email address could appear.</p>
+
+<p>Email addresses are not filtered out of [% terms.bug %] comments.
+ The WebService still returns full email addresses, even if you are logged
+ out.</p>
+
+<h3 id="v34_feat_urls">Shorter Search URLs</h3>
+
+<p>When submitting a search, all the unused fields are now stripped from
+ the URL, so search URLs are much more meaningful, and much shorter.</p>
+
+<h3 id="v34_feat_async">Asynchronous Email Sending</h3>
+
+<p>The largest performance problem in former versions of [% terms.Bugzilla %]
+ was that when updating [% terms.bugs %], email would be sent immediately
+ to every user who needed to be notified, and <kbd>process_bug.cgi</kbd>
+ would wait for the emails to be sent before continuing.</p>
+
+<p>Now [% terms.Bugzilla %] is capable of queueing emails to be sent
+ while [% terms.abug %] is being updated, and sending them in the
+ background. This requires the administrator to run a daemon
+ that comes with [% terms.Bugzilla %], named
+ <a href="[% docs_urlbase FILTER html %]api/jobqueue.html">jobqueue.pl</a>,
+ and to enable the <a href="editparams.cgi?section=mta#use_mailer_queue">
+ use_mailer_queue</a> parameter.</p>
+
+<p>Using the background email-sending daemon instead of sending mail directly
+ should result in a very large speed-up for updating [% terms.bugs %],
+ particularly on larger installations.</p>
+
+<h3 id="v34_feat_tz">Dates and Times Displayed In User's Time Zone</h3>
+
+<p>Users can now select what time zone they are in and [% terms.Bugzilla %]
+ will adjust displayed times to be correct for their time zone. However,
+ times the user inputs are unfortunately still in [% terms.Bugzilla %]'s
+ time zone.</p>
+
+<h3 id="v34_feat_vis">Custom Fields That Only Appear When Another Field
+ Has a Particular Value</h3>
+
+<p>When creating a new custom field (or updating the definition of
+ an existing custom field), you can now say that "this field only
+ appears when field X has value Y". (In the future, you will be able
+ to select multiple values for "Y", so a field will appear when any
+ one of those values is selected.)</p>
+
+<p>This feature only hides fields--it doesn't make their values go away.
+ So [% terms.bugs %] will still show up in searches for that field's
+ value, but the field won't appear in the user interface.</p>
+
+<p>This is a good way of making Product-specific fields.</p>
+
+<h3 id="v34_feat_vals">Custom Fields Whose List of Values Change
+ Depending on the Value of Another Field</h3>
+
+<p>When creating a drop-down or multiple-selection custom field, you can
+ now specify that another field "controls the values" of this field.
+ Then, when adding values to this field, you can say that a particular
+ value only appears when the other field is set to a particular
+ value.</p>
+
+<p>Here's an example: Let's say that we create a field called "Colors",
+ and we make the Product field "control the values" for Colors. Then we
+ add Blue, Red, Black, and Yellow as legal values for the "Colors" field.
+ Now we can say that "Blue" and "Red" only appear as valid choices in
+ Product A, "Yellow" only appears in Product B, but "Black" <em>always</em>
+ appears.</p>
+
+<p>One thing to note is that this feature only controls what values appear in
+ the <em>user interface</em>. [% terms.Bugzilla %] itself will still accept
+ any combination of values as valid, in the backend.</p>
+
+<h3 id="v34_feat_bugid">New Custom Field Type: [% terms.Bug %] ID</h3>
+
+<p>You can now create a custom field that holds a reference to a single
+ valid [% terms.bug %] ID. In the future this will be enhanced to allow
+ [%+ terms.bugs %] to refer to each other via this field.</p>
+
+<h3 id="v34_feat_see">"See Also" Field</h3>
+
+<p>We have added a new standard field called "See Also" to
+ [%+ terms.Bugzilla %]. In this field, you can put URLs to multiple
+ [%+ terms.bugs %] in any [% terms.Bugzilla %] installation, to indicate
+ that those [% terms.bugs %] are related to this one. It also supports
+ adding URLs to [% terms.bugs %] in
+ <a href="http://launchpad.net/">Launchpad</a>.</p>
+
+<p>Right now, the field just validates the URLs and then displays them, but
+ in the future, it will grab information from the other installation about
+ the [% terms.bug %] and display it here, and possibly even update the
+ other installation.</p>
+
+<p>If your installation does not need this field, you can hide it by disabling
+ the <a href="editparams.cgi?section=bugfields#use_see_also">use_see_also
+ parameter</a>.</p>
+
+<h3 id="v34_feat_cols">Re-order Columns in Search Results</h3>
+
+<p>There is a new interface for choosing what columns appear in search
+ results, which allows you to change the order in which columns appear
+ from left to right when viewing the [% terms.bug %] list.</p>
+
+<h3 id="v34_feat_desc">Search Descriptions</h3>
+
+<p>When displaying search results, [% terms.Bugzilla %] will now show
+ a brief description of what you searched for, at the top of the
+ [%+ terms.bug %] list.</p>
+
+<h3 id="v34_feat_other">Other Enhancements and Changes</h3>
+
+<h4>Enhancements for Users</h4>
+
+<ul>
+ <li>You can now log in from every page, using the login form that appears
+ in the header or footer when you click "Log In".</li>
+ <li>When viewing [% terms.abug %], obsolete attachments are now
+ hidden from the attachment list by default. You can show them
+ by clicking "Show Obsolete" at the bottom of the attachment list.</li>
+ <li>In the Email Preferences, you can now choose to get email when
+ a new [% terms.bug %] report is filed and you have a particular
+ role on it.</li>
+ <li>When resolving a mid-air collision, you can now choose to submit
+ only your comment.</li>
+ <li>You can now set the Blocks and Depends On field on the "Change
+ Several [% terms.Bugs %] At Once" page.</li>
+ <li>If your installation uses the "insidergroup" feature, you can now add
+ private comments on the "Change Several [% terms.Bugs %] At Once"
+ page.</li>
+ <li>When viewing a search result, you can now hover over any abbreviated
+ field to see its full value.</li>
+ <li>When logging out, users are now redirected to the main page of
+ [%+ terms.Bugzilla %] instead of an empty page.</li>
+ <li>When editing [% terms.abug %], text fields (except the comment box) now
+ grow longer when you widen your browser window.</li>
+ <li>When viewing [% terms.abug %], the Depends On and Blocks list will
+ display [% terms.abug %]'s alias if it has one, instead of its id.
+ Also, closed [% terms.bugs %] will be sorted to the end of the list.</li>
+
+ <li>If you use the time-tracking features of [% terms.Bugzilla %], and
+ you enable the time-tracking related columns in a search result,
+ then you will see a summary of the time-tracking data at the
+ bottom of the search result.</li>
+ <li>For users of time-tracking, the <kbd>summarize_time.cgi</kbd> page
+ now contains more data.</li>
+
+ <li>When viewing an attachment's details page while you are logged-out,
+ flags are no longer shown as editable.</li>
+ <li>Cloning [% terms.abug %] will now retain the "Blocks" and "Depends On"
+ fields from the [% terms.bug %] being cloned.</li>
+ <li>[% terms.Bug %]mail for new [% terms.bugs %] will now indicate
+ what security groups the [% terms.bug %] has been restricted to.</li>
+ <li>You can now use any custom drop-down field as an axis for a tabular
+ or graphical report.</li>
+ <li>The <kbd>X-Bugzilla-Type</kbd> header in emails sent by
+ [%+ terms.Bugzilla %] is now "new" for [% terms.bug %]mail sent for
+ newly-filed [% terms.bugs %], and "changed" for emails having to do
+ with updated [% terms.bugs %].</li>
+ <li>Mails sent by the "Whining" system now contain the header
+ <kbd>X-Bugzilla-Type: whine</kbd>.</li>
+ <li>[% terms.bug %]mail now contains a X-Bugzilla-URL header to uniquely
+ identify which [% terms.Bugzilla %] installation the email came from.</li>
+ <li>If you input an invalid regular expression anywhere in
+ [%+ terms.Bugzilla %], it will now tell you explicitly instead of failing
+ cryptically.</li>
+ <li>The <kbd>duplicates.xul</kbd> page (which wasn't used by very many
+ people) is now gone.</li>
+</ul>
+
+<h4>Enhancements for Administrators and Developers</h4>
+
+<ul>
+ <li>[% terms.Bugzilla %] now uses the SHA-256 algorithm (a variant of
+ SHA-2) to encrypt passwords in the database, instead of using Unix's
+ "crypt" function. This allows passwords longer than eight characters
+ to actually be effective. Each user's password will be converted to
+ SHA-256 the first time they log in after you upgrade to
+ [%+ terms.Bugzilla %] 3.4 or later.</li>
+ <li>If you are using database replication with [% terms.Bugzilla %],
+ many more scripts now take advantage of the read-only slave (the
+ "shadowdb"). It may be safe to open up <kbd>show_bug.cgi</kbd>
+ to search-engine indexing by editing your <kbd>robots.txt</kbd> file,
+ now, if your [% terms.Bugzilla %] is on fast-enough hardware.</li>
+ <li>The database now uses foreign keys to enforce the validity of
+ relationships between tables. Not every single table has all its
+ foreign keys yet, but most do.</li>
+ <li>Various parameters have been removed, in an effort to de-clutter
+ the parameter interface and simplify [% terms.Bugzilla %]'s code.
+ The parameters that were removed were: timezone, supportwatchers,
+ maxpatchsize, commentonclearresolution, commentonreassignbycomponent,
+ showallproducts. They have all been replaced with sensible default
+ behaviors. (For example, user watching is now always enabled.)</li>
+ <li>When adding <code>&amp;debug=1</code> to the end of a
+ <kbd>buglist.cgi</kbd> URL, [% terms.Bugzilla %] will now also do an
+ EXPLAIN on the query, to help debug performance issues.</li>
+ <li>When editing flag types in the administrative interface, you can now
+ see how many flags of each type have been set.</li>
+</ul>
+
+<h4>WebService Changes</h4>
+
+<ul>
+ <li>Various functions have been added to the WebService:
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/Bug.html#history">B[% %]ug.history</a>,
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/Bug.html#search">B[% %]ug.search</a>,
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/Bug.html#comments">B[% %]ug.comments</a>,
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/Bug.html#update_see_also">B[% %]ug.update_see_also</a>,
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/User.html#get">User.get</a>,
+ and <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/Bugzilla.html#time">B[% %]ugzilla.time</a>
+ (<kbd>B[% %]ugzilla.timezone</kbd> is now deprecated).
+ </li>
+ <li>For network efficiency, you can now limit which fields are returned
+ from certain WebService functions, like <kbd>User.get</kbd>.</li>
+ <li>There is now a "permissive" argument for the <kbd>B[% %]ug.get</kbd>
+ WebService function, which causes it not to throw an error when you
+ ask for [% terms.bugs %] you can't see.</li>
+
+ <li>The <kbd>B[% %]ug.get</kbd> method now returns many more fields.</li>
+ <li>The <kbd>B[% %]ug.add_comment</kbd> method now returns the ID of the comment
+ that was just added.</li>
+ <li>The <kbd>B[% %]ug.add_comment</kbd> method will now throw an error if you
+ try to add a private comment but do not have the correct permissions.
+ (In previous versions, it would just silently ignore the <kbd>private</kbd>
+ argument if you didn't have the correct permissions.)</li>
+ <li>Many WebService function parameters now take individual values in
+ addition to arrays.</li>
+ <li>The WebService now validates input types--it makes sure that dates
+ are in the right format, that ints are actually ints, etc. It will throw
+ an error if you send it invalid data. It also accepts empty ints, doubles,
+ and dateTimes, and translates them to <kbd>undef</kbd>.</li>
+</ul>
+
+<h2 id="v34_issues">Outstanding Issues</h2>
+
+<ul>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=423439">
+ [%- terms.Bug %] 423439</a>: Tabs in comments will be converted
+ to four spaces, due to a b<!-- -->ug in Perl as of Perl 5.8.8.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=69621">
+ [%- terms.Bug %] 69621</a>: If you rename or remove a keyword that is
+ in use on [% terms.bugs %], you will need to rebuild the "keyword cache"
+ by running <a href="sanitycheck.cgi">sanitycheck.cgi</a> and choosing
+ the option to rebuild the cache when it asks. Otherwise keywords may
+ not show up properly in search results.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=89822">
+ [%- terms.Bug %] 89822</a>: When changing multiple [% terms.bugs %] at
+ the same time, there is no "mid-air collision" protection.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=276230">
+ [%- terms.Bug %] 276230</a>: The support for restricting access to
+ particular Categories of New Charts is not complete. You should treat
+ the 'chartgroup' Param as the only access mechanism available.<br>
+ However, charts migrated from Old Charts will be restricted to
+ the groups that are marked MANDATORY for the corresponding Product.
+ There is currently no way to change this restriction, and the
+ groupings will not be updated if the group configuration
+ for the Product changes.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=370370">
+ [%- terms.Bug %] 370370</a>: mod_perl support is currently not
+ working on Windows machines.</li>
+</ul>
+
+<h2 id="v34_upgrading">Notes On Upgrading From a Previous Version</h2>
+
+<p>When upgrading to 3.4, <kbd>checksetup.pl</kbd> will create foreign keys
+ for many columns in the database. Before doing this, it will check the
+ database for consistency. If there are an unresolvable consistency
+ problems, it will tell you what table and column in the database contain
+ the bad values, and which values are bad. If you don't know what else to do,
+ you can always delete the database records which contain the bad values by
+ logging in to your database and running the following command:</p>
+
+<p><code>DELETE FROM <var>table</var> WHERE <var>column</var> IN
+ (<var>1, 2, 3, 4</var>)</code></p>
+
+<p>Just replace "table" and "column" with the name of the table
+ and column that <kbd>checksetup.pl</kbd> mentions, and "1, 2, 3, 4"
+ with the invalid values that <kbd>checksetup.pl</kbd> prints out.</p>
+
+<p>Remember that you should always back up your database before doing
+ an upgrade.</p>
+
+<h2 id="v34_code_changes">Code Changes Which May Affect Customizations</h2>
+
+<ul>
+ <li><kbd>checksetup.pl</kbd> now re-writes the <kbd>localconfig</kbd>
+ file every time it runs, keeping the current values set (if there
+ are any), but moving any unexpected variables into a file called
+ <kbd>localconfig.old</kbd>. If you want to continue having custom
+ varibles in <kbd>localconfig</kbd>, you will have to add them to
+ the <code>LOCALCONFIG_VARS</code> constant in
+ <kbd>Bugzilla::Install::Localconfig</kbd>.</li>
+ <li><kbd>Bugzilla::Object-&gt;update()</kbd> now returns something different
+ in list context than it does in scalar context.</li>
+ <li><kbd>Bugzilla::Object-&gt;check()</kbd> now can take object
+ ids in addition to names. Just pass in <code>{ id =&gt; $some_value
+ }</code>.</li>
+ <li>Instead of being defined in <kbd>buglist.cgi</kbd>, columns for
+ search results are now defined in a subroutine called <code>COLUMNS</code>
+ in <kbd>Bugzilla::Search</kbd>. The data now mostly comes from the
+ <kbd>fielddefs</kbd> table in the database. Search.pm now takes a list
+ of column names from fielddefs for its <kbd>fields</kbd> argument instead
+ of literal SQL columns.</li>
+ <li><kbd>Bugzilla::Field-&gt;legal_values</kbd> now returns an array of
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/Field/Choice.html">Bugzilla::Field::Choice</a>
+ objects instead of an array of strings. Bugzilla::Field::Choice will be used
+ in more places, in the future.</li>
+ <li>We now use <kbd>Bugzilla::Bug-&gt;check()</kbd> instead of
+ <kbd>ValidateBugId</kbd>.</li>
+ <li>The <kbd>groups</kbd> and <kbd>bless_groups</kbd> methods in
+ <kbd>Bugzilla::User</kbd> now return an arrayref of
+ <kbd>Bugzilla::Group</kbd> objects instead of a hashref with
+ group ids and group names.</li>
+ <li>Standard [% terms.Bugzilla %] drop-down fields now have their type
+ set to <kbd>FIELD_TYPE_SINGLE_SELECT</kbd> in the fielddefs table.</li>
+ <li><kbd>Bugzilla-&gt;usage_mode</kbd> now defaults to
+ <kbd>USAGE_MODE_CMDLINE</kbd> if we are not running inside a web
+ server.</li>
+ <li>We no longer delete environment variables like <kbd>$ENV{PATH}</kbd>
+ automatically unless we're actually running in taint mode.</li>
+ <li>We are now using YUI 2.6.0.</li>
+ <li>In <a href="config.cgi?ctype=rdf">the RDF format of config.cgi</a>,
+ the "resource" attribute for flags now contains "flag.cgi" instead
+ of "flags.cgi".</li>
+</ul>
+
+
+
+
+
+
+
+<h1 id="v34_previous">[% terms.Bugzilla %] 3.2 Release Notes</h1>
+
+<h2>Table of Contents</h2>
+
+<ul class="bz_toc">
+ <li><a href="#v32_introduction">Introduction</a></li>
+ <li><a href="#v32_point">Updates In This 3.2.x Release</a></li>
+ <li><a href="#v32_security">Security Fixes In This 3.2.x Release</a></li>
+ <li><a href="#v32_req">Minimum Requirements</a></li>
+ <li><a href="#v32_feat">New Features and Improvements</a></li>
+ <li><a href="#v32_issues">Outstanding Issues</a></li>
+ <li><a href="#v32_upgrading">How to Upgrade From An Older Version</a></li>
+ <li><a href="#v32_code_changes">Code Changes Which May Affect
+ Customizations</a></li>
+ <li><a href="#v32_previous">Release Notes for Previous Versions</a></li>
+</ul>
+
+<h2 id="v32_introduction">Introduction</h2>
+
+<p>Welcome to [% terms.Bugzilla %] 3.2! This is our first major feature
+ release since [% terms.Bugzilla %] 3.0, and it brings a lot of great
+ improvements and polish to the [% terms.Bugzilla %] experience.</p>
+
+<p>If you're upgrading, make sure to read <a href="#v32_upgrading">How to
+ Upgrade From An Older Version</a>. If you are upgrading from a release
+ before 3.0, make sure to read the release notes for all the
+ <a href="#v32_previous">previous versions</a> in between your version
+ and this one, <strong>particularly the "Notes For Upgraders" section of each
+ version's release notes</strong>.</p>
+
+<h2 id="v32_point">Updates in this 3.2.x Release</h2>
+
+<p>This section describes what's changed in the most recent b<!-- -->ug-fix
+ releases of [% terms.Bugzilla %] after 3.2. We only list the
+ most important fixes in each release. If you want a detailed list of
+ <em>everything</em> that's changed in each version, you should use our
+ <a href="http://www.bugzilla.org/status/changes.html">Change Log
+ Page</a>.</p>
+
+<h3>3.2.3</h3>
+
+<ul>
+ <li>[% terms.Bugzilla %] is now compatible with MySQL 5.1.x versions 5.1.31
+ and greater.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=480001">[% terms.Bug %] 480001</a>)</li>
+ <li>On Windows, [% terms.Bugzilla %] sometimes would send mangled emails
+ (that would often fail to send).
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=467920">[% terms.Bug %] 467920</a>)</li>
+ <li><code>recode.pl</code> would sometimes crash when trying to convert
+ databases from older versions of [% terms.Bugzilla %].
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=431201">[% terms.Bug %] 431201</a>)</li>
+ <li>Running a saved search with Unicode characters in its name would
+ cause [% terms.Bugzilla %] to crash.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=477513">[% terms.Bug %] 477513</a>)</li>
+ <li>[% terms.Bugzilla %] clients like Mylyn can now update [% terms.bugs %]
+ again (the [% terms.bug %] XML format now contains a "token" element that
+ can be used when updating [% terms.abug %]).
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=476678">[% terms.Bug %] 476678</a>)</li>
+ <li>For installations using the <code>shadowdb</code> parameter,
+ [%+ terms.Bugzilla %] was accidentally writing to the "tokens" table
+ in the shadow database (instead of the master database) when using the
+ "Change Several [% terms.Bugs %] at Once" page.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=476943">[% terms.Bug %] 476943</a>)</li>
+</ul>
+
+<p>This release also contains a security fix. See the
+ <a href="#v32_security">Security Fixes Section</a> for details.</p>
+
+<h3>3.2.2</h3>
+
+<p>This release fixes one security issue that is critical for installations
+ running 3.2.1 under mod_perl. See the
+ <a href="http://www.bugzilla.org/security/3.0.7/">Security Advisory</a>
+ for details.</p>
+
+<h3>3.2.1</h3>
+
+<ul>
+ <li>Attachments, charts, and graphs would sometimes be garbled on Windows.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=464992">[% terms.Bug %] 464992</a>)</li>
+
+ <li>Saving changes to parameters would sometimes fail silently (particularly
+ on Windows when the web server didn't have the right permissions to
+ update the <code>params</code> file). [% terms.Bugzilla %] will now
+ throw an error in this case, telling you what is wrong.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=347707">[% terms.Bug %] 347707</a>)</li>
+
+ <li>If you were using the <code>usemenuforusers</code> parameter,
+ and [% terms.abug %] was assigned to (or had a QA Contact of) a disabled
+ user, that field would be reset to the first user in the list when
+ updating [% terms.abug %].
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=465589">[% terms.Bug %] 465589</a>)</li>
+
+ <li>If you were using the <code>PROJECT</code> environment variable
+ to have multiple [% terms.Bugzilla %] installations using one codebase,
+ project-specific templates were being ignored.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=467324">[% terms.Bug %] 467324</a>)</li>
+
+ <li>Some versions of the SOAP::Lite Perl module had a b[% %]ug that caused
+ [%+ terms.Bugzilla %]'s XML-RPC service to break.
+ <kbd>checksetup.pl</kbd> now checks for these bad versions and
+ will reject them.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=468009">[% terms.Bug %] 468009</a>)</li>
+
+ <li>The font sizes in various places were too small, when using the
+ Classic skin.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=469136">[% terms.Bug %] 469136</a>)</li>
+</ul>
+
+<h2 id="v32_security">Security Fixes In This 3.2.x Release</h2>
+
+<h3>3.2.3</h3>
+
+<p>This release fixes one security issue related to attachments. See the
+ <a href="http://www.bugzilla.org/security/3.2.2/">Security Advisory</a>
+ for details.</p>
+
+<h3>3.2.2</h3>
+
+<p>This release fixes one security issue that is critical for installations
+ running 3.2.1 under mod_perl. See the
+ <a href="http://www.bugzilla.org/security/3.0.7/">Security Advisory</a>
+ for details.</p>
+
+<h3>3.2.1</h3>
+
+<p>This release contains several security fixes. One fix may break any
+ automated scripts you have that are loading <kbd>process_bug.cgi</kbd>
+ directly. We recommend that you read the entire
+ <a href="http://www.bugzilla.org/security/2.22.6/">Security Advisory</a>
+ for this release.</p>
+
+<h2 id="v32_req">Minimum Requirements</h2>
+
+<p>Any requirements that are new since 3.0.5 will look like
+ <span class="req_new">this</span>.</p>
+
+<ul>
+ <li><a href="#v32_req_perl">Perl</a></li>
+ <li><a href="#v32_req_mysql">For MySQL Users</a></li>
+ <li><a href="#v32_req_pg">For PostgreSQL Users</a></li>
+ <li><a href="#v32_req_oracle">For Oracle Users</a></li>
+ <li><a href="#v32_req_modules">Required Perl Modules</a></li>
+ <li><a href="#v32_req_optional_mod">Optional Perl
+ Modules</a></li>
+</ul>
+
+<h3 id="v32_req_perl">Perl</h3>
+
+<p>Perl <span class="req_new">v<strong>5.8.1</strong></span></p>
+
+<h3 id="v32_req_mysql">For MySQL Users</h3>
+
+<ul>
+ <li>MySQL v4.1.2</li>
+ <li><strong>perl module:</strong>
+ DBD::mysql <span class="req_new">v4.00</span></li>
+</ul>
+
+<h3 id="v32_req_pg">For PostgreSQL Users</h3>
+
+<ul>
+ <li>PostgreSQL v8.00.0000</li>
+ <li><strong>perl module:</strong> DBD::Pg v1.45</li>
+</ul>
+
+<h3 id="v32_req_oracle">Email Addresses Hidden From Logged-Out Users
+ For Oracle Users</h3>
+
+<ul>
+ <li>Oracle v10.02.0</li>
+ <li><strong>perl module:</strong> DBD::Oracle v1.19</li>
+</ul>
+
+<h3 id="v32_req_modules">Required Perl Modules</h3>
+
+<table class="req_table" border="0" cellpadding="0" cellspacing="0">
+<tr> <th>Module</th> <th>Version</th> </tr>
+<tr> <td>CGI</td> <td class="req_new">3.21 (on Perl 5.8.x)
+ or 3.33 (on Perl 5.10.x)</td> </tr>
+<tr> <td>Date::Format</td> <td>2.21</td> </tr>
+<tr> <td>File::Spec</td> <td>0.84</td> </tr>
+<tr> <td>DBI</td> <td>1.41</td> </tr>
+<tr> <td>Template</td> <td class="req_new">2.15</td> </tr>
+<tr> <td>Email::Send</td> <td>2.00</td> </tr>
+<tr> <td>Email::MIME</td> <td class="req_new">1.861</td> </tr>
+<tr>
+ <td class="req_new">Email::MIME::Encodings</td>
+ <td class="req_new">1.313</td>
+</tr>
+<tr>
+ <td>Email::MIME::Modifier</td>
+ <td class="req_new">1.442</td>
+</tr>
+</table>
+
+<h3 id="v32_req_optional_mod">Optional Perl Modules</h3>
+
+<p>The following perl modules, if installed, enable various
+ features of [% terms.Bugzilla %]:</p>
+
+<table class="req_table" border="0" cellpadding="0" cellspacing="0">
+<tr>
+ <th>Module</th>
+ <th>Version</th>
+ <th>Enables Feature</th>
+</tr>
+<tr>
+ <td>LWP::UserAgent</td>
+ <td>(Any)</td>
+ <td>Automatic Update Notifications</td>
+</tr>
+<tr>
+ <td>Template::Plugin::GD::Image</td>
+ <td>(Any)</td>
+ <td>Graphical Reports</td>
+</tr>
+<tr>
+ <td>GD::Text</td>
+ <td>(Any)</td>
+ <td>Graphical Reports</td>
+</tr>
+<tr>
+ <td>GD::Graph</td>
+ <td>(Any)</td>
+ <td>Graphical Reports</td>
+</tr>
+<tr>
+ <td>GD</td>
+ <td>1.20</td>
+ <td>Graphical Reports, New Charts, Old Charts</td>
+</tr>
+<tr>
+ <td>Email::MIME::Attachment::Stripper</td>
+ <td>(Any)</td>
+ <td>Inbound Email</td>
+</tr>
+<tr>
+ <td>Email::Reply</td>
+ <td>(Any)</td>
+ <td>Inbound Email</td>
+</tr>
+<tr>
+ <td>Net::LDAP</td>
+ <td>(Any)</td>
+ <td>LDAP Authentication</td>
+</tr>
+<tr>
+ <td>HTML::Parser</td>
+ <td>3.40</td>
+ <td>More HTML in Product/Group Descriptions</td>
+</tr>
+<tr>
+ <td>HTML::Scrubber</td>
+ <td>(Any)</td>
+ <td>More HTML in Product/Group Descriptions</td>
+</tr>
+<tr>
+ <td>XML::Twig</td>
+ <td>(Any)</td>
+ <td>Move [% terms.Bugs %] Between Installations</td>
+</tr>
+<tr>
+ <td>MIME::Parser</td>
+ <td>5.406</td>
+ <td>Move [% terms.Bugs %] Between Installations</td>
+</tr>
+<tr>
+ <td>Chart::Base</td>
+ <td>1.0</td>
+ <td>New Charts, Old Charts</td>
+</tr>
+<tr>
+ <td>Image::Magick</td>
+ <td>(Any)</td>
+ <td>Optionally Convert BMP Attachments to PNGs</td>
+</tr>
+<tr>
+ <td>PatchReader</td>
+ <td>0.9.4</td>
+ <td>Patch Viewer</td>
+</tr>
+<tr>
+ <td class="req_new">Authen::Radius</td>
+ <td class="req_new">(Any)</td>
+ <td>RADIUS Authentication</td>
+</tr>
+<tr>
+ <td class="req_new">Authen::SASL</td>
+ <td class="req_new">(Any)</td>
+ <td>SMTP Authentication</td>
+</tr>
+<tr>
+ <td>SOAP::Lite</td>
+ <td>(Any)</td>
+ <td>XML-RPC Interface</td>
+</tr>
+<tr>
+ <td>mod_perl2</td>
+ <td>1.999022</td>
+ <td>mod_perl</td>
+</tr>
+</table>
+
+<h2 id="v32_feat">New Features and Improvements</h2>
+
+<ul>
+ <li><a href="#v32_feat_ui">Major UI Improvements</a></li>
+ <li><a href="#v32_feat_skin">New Default Skin: Dusk</a></li>
+ <li><a href="#v32_feat_status">Custom Status Workflow</a></li>
+ <li><a href="#v32_feat_fields">New Custom Field Types</a></li>
+ <li><a href="#v32_feat_install">Easier Installation</a></li>
+ <li><a href="#v32_feat_oracle">Experimental Oracle Support</a></li>
+ <li><a href="#v32_feat_utf8">Improved UTF-8 Support</a></li>
+ <li><a href="#v32_feat_grcons">Group Icons</a></li>
+ <li><a href="#v32_feat_other">Other Enhancements and Changes</a></li>
+</ul>
+
+<h3 id="v32_feat_ui">Major UI Improvements</h3>
+
+<p>[% terms.Bugzilla %] 3.2 has had some UI assistance from the NASA
+ Human-Computer Interaction department and the new
+ <a href="http://wiki.mozilla.org/Bugzilla:UE">[% terms.Bugzilla %]
+ User Interface Team</a>.</p>
+
+<p>In particular, you will notice a massively redesigned [% terms.bug %]
+ editing form, in addition to our <a href="#v32_feat_skin">new skin</a>.</p>
+
+<h3 id="v32_feat_skin">New Default Skin: Dusk</h3>
+
+<p>[% terms.Bugzilla %] 3.2 now ships with a skin called "Dusk" that is
+ a bit more colorful than old default "Classic" skin.</p>
+
+<p>Upgrading installations will still default to the "Classic"
+ skin--administrators can change the default in the Default Preferences
+ control panel. Users can also choose to use the old skin in their
+ Preferences (or using the View :: Page Style menu in Firefox).</p>
+
+<p>The changes that [% terms.Bugzilla %] required for Dusk made
+ [%+ terms.Bugzilla %] much easier to skin. See the
+ <a href="http://wiki.mozilla.org/Bugzilla:Addons#Skins">Addons page</a>
+ for additional skins, or try making your own!</p>
+
+<h3 id="v32_feat_status">Custom Status Workflow</h3>
+
+<p>You can now customize the list of statuses in [% terms.Bugzilla %],
+ and transitions between them.</p>
+
+<p>You can also specify that a comment must be made on certain transitions.</p>
+
+<h3 id="v32_feat_fields">New Custom Field Types</h3>
+
+<p>[% terms.Bugzilla %] 3.2 has support for three new types of
+ custom fields:</p>
+
+<ul>
+ <li>Large Text: Adds a multi-line textbox to your [% terms.bugs %].</li>
+ <li>Multiple Selection Box: Adds a box that allows you to choose
+ multiple items from a list.</li>
+ <li>Date/Time: Displays a date and time, along with a JavaScript
+ calendar popup to make picking a date easier.</li>
+</ul>
+
+<h3 id="v32_feat_install">Easier Installation</h3>
+
+<p>[% terms.Bugzilla %] now comes with a script called
+ <kbd>install-module.pl</kbd> that can automatically download
+ and install all of the required Perl modules for [% terms.Bugzilla %].
+ It stores them in a directory inside your [% terms.Bugzilla %]
+ installation, so you can use it even if you don't have administrator-level
+ access to your machine, and without modifying your main Perl install.</p>
+
+<p><kbd>checksetup.pl</kbd> will print out instructions for using
+ <kbd>install-module.pl</kbd>, or you can read its
+ <a href="[% docs_urlbase FILTER html %]api/install-module.html">documentation</a>.</p>
+
+<h3 id="v32_feat_oracle">Experimental Oracle Support</h3>
+
+<p>[% terms.Bugzilla %] 3.2 contains experimental support for using
+ Oracle as its database. Some features of [% terms.Bugzilla %] are known
+ to be broken on Oracle, but hopefully will be working by our next major
+ release.</p>
+
+<p>The [% terms.Bugzilla %] Project, as an open-source project, of course
+ does not recommend the use of proprietary database solutions. However,
+ if your organization requires that you use Oracle, this will allow
+ you to use [% terms.Bugzilla %]!</p>
+
+<p>The [% terms.Bugzilla %] Project thanks Oracle Corp. for their extensive
+ development contributions to [% terms.Bugzilla %] which allowed this to
+ happen!</p>
+
+<h3 id="v32_feat_utf8">Improved UTF-8 Support</h3>
+
+<p>[% terms.Bugzilla %] 3.2 now has advanced UTF-8 support in its code,
+ including correct handling for truncating and wrapping multi-byte
+ languages. Major issues with multi-byte or unusual languages
+ are now resolved, and [% terms.Bugzilla %] should now be usable
+ by users in every country with little (or at least much less)
+ customization.</p>
+
+<h3 id="v32_feat_grcons">Group Icons</h3>
+
+<p>Administrators can now specify that users who are in certain groups
+ should have an icon appear next to their name whenever they comment.
+ This is particularly useful for distinguishing developers from
+ [%+ terms.bug %] reporters.</p>
+
+<h3 id="v32_feat_other">Other Enhancements and Changes</h3>
+
+<p>These are either minor enhancements, or enhancements that have
+ very short descriptions. Some of these are very useful, though!</p>
+
+<h4>Enhancements For Users</h4>
+
+<ul>
+ <li><strong>[% terms.Bugs %]</strong>: You can now reassign
+ [%+ terms.abug %] at the same time as you are changing its status.</li>
+ <li><strong>[% terms.Bugs %]</strong>: When entering [% terms.abug %],
+ you will now see the description of a component when you select it.</li>
+ <li><strong>[% terms.Bugs %]</strong>: The [% terms.bug %] view now
+ contains some <a href="http://microformats.org/about/">Microformats</a>,
+ most notably for users' names and email addresses.</li>
+ <li><strong>[% terms.Bugs %]</strong>: You can now remove a QA Contact
+ from [% terms.abug %] simply by clearing the QA Contact field.</li>
+ <li><strong>[% terms.Bugs %]</strong>: There is now a user preference
+ that will allow you to exclude the quoted text when replying
+ to comments.</li>
+ <li><strong>[% terms.Bugs %]</strong>: You can now expand or collapse
+ individual comments in the [% terms.bug %] view.</li>
+
+ <li><strong>Attachments</strong>: There is now "mid-air collision"
+ protection when editing attachments.</li>
+ <li><strong>Attachments</strong>: Patches in the Diff Viewer now show
+ line numbers (<a href="https://bugzilla.mozilla.org/attachment.cgi?id=327546">Example</a>).</li>
+ <li><strong>Attachments</strong>: After creating or updating an attachment,
+ you will be immediately shown the [% terms.bug %] that the attachment
+ is on.</li>
+
+ <li><strong>Search</strong>: You can now reverse the sort of
+ [%+ terms.abug %] list by clicking on a column header again.</li>
+ <li><strong>Search</strong>: Atom feeds of [% terms.bug %] lists now
+ contain more fields.</li>
+ <li><strong>Search</strong>: QuickSearch now supports searching flags
+ and groups. It also now includes the OS field in the list of fields
+ it searches by default.</li>
+ <li><strong>Search</strong>: "Help" text can now appear on query.cgi
+ for Internet Explorer and other non-Firefox browsers. (It always
+ could appear for Firefox.)</li>
+
+ <li>[% terms.Bugzilla %] now ships with an icon that will show
+ up next to the URL in most browsers. If you want to replace it,
+ it's in <kbd>images/favicon.ico</kbd>.</li>
+
+ <li>You can now set the Deadline when using "Change Several
+ [%+ terms.Bugs %] At Once"</li>
+ <li><strong>Saved Searches</strong> now save their column list, so if
+ you customize the list of columns and save your search, it will
+ always contain those columns.</li>
+ <li><strong>Saved Searches</strong>: When you share a search, you can
+ now see how many users have subscribed to it, on
+ <kbd>userprefs.cgi</kbd>.</li>
+ <li><strong>Saved Searches</strong>: You can now see what group a
+ shared search was shared to, on the list of available shared searches
+ in <kbd>userprefs.cgi</kbd>.</li>
+ <li><strong>Flags</strong>: If your installation uses drop-down user
+ lists, the flag requestee box will now contain only users who are
+ actually allowed to take requests.</li>
+ <li><strong>Flags</strong>: If somebody makes a request to you, and you
+ change the requestee to somebody else, the requester is no longer set
+ to you. In other words, you can "redirect" requests and maintain the
+ original requester.</li>
+ <li><strong>Flags</strong>: Emails about flags now will thread properly
+ in email clients to be a part of [% terms.abug %]'s thread.</li>
+ <li>When using <kbd>email_in.pl</kbd>, you can now add users to the CC
+ list by just using <kbd>@cc</kbd> as the field name.</li>
+ <li>Many pages (particularly administrative pages) now contain links to
+ the relevant section of the [% terms.Bugzilla %] Guide, so you can read
+ the documentation for that page.</li>
+ <li>Dependency Graphs should render more quickly, as they now (by default)
+ only include the same [% terms.bugs %] that you'd see in the dependency
+ tree.</li>
+</ul>
+
+<h4>Enhancements For Administrators</h4>
+
+<ul>
+ <li><strong>Admin UI</strong>: Instead of having the Administration
+ Control Panel links in the footer, there is now just one link called
+ "Administration" that takes you to a page that links to all the
+ administrative controls for [% terms.Bugzilla %].</li>
+ <li><strong>Admin UI</strong>: Administrative pages no longer display
+ confirmation pages, instead they redirect you to some useful page
+ and display a message about what changed.</li>
+ <li><strong>Admin UI</strong>: The interface for editing group
+ inheritance in <kbd>editgroups.cgi</kbd> is much clearer now.</li>
+ <li><strong>Admin UI</strong>: When editing a user, you can now see
+ all the components where that user is the Default Assignee or Default
+ QA Contact.</li>
+
+ <li><strong>Email</strong>: For installations that use SMTP to send
+ mail (as opposed to Sendmail), [%+ terms.Bugzilla %] now supports
+ SMTP Authentication, so that it can log in to your mail server
+ before sending messages.</li>
+ <li><strong>Email</strong>: Using the "Test" mail delivery method now
+ creates a valid mbox file to make testing easier.</li>
+
+ <li><strong>Authentication</strong>: [% terms.Bugzilla %] now correctly
+ handles LDAP records which contain multiple email addresses. (The first
+ email address in the list that is a valid [% terms.Bugzilla %] account
+ will be used, or if this is a new user, the first email address in
+ the list will be used.)</li>
+ <li><strong>Authentication</strong>: [% terms.Bugzilla %] can now take
+ a list of LDAP servers to try in order until it gets a successful
+ connection.</li>
+ <li><strong>Authentication</strong>: [% terms.Bugzilla %] now supports
+ RADIUS authentication.</li>
+
+ <li><strong>Security</strong>: The login cookie is now created as
+ "HTTPOnly" so that it can't be read by possibly malicious scripts.
+ Also, if SSL is enabled on your installation, the login cookie is
+ now only sent over SSL connections.</li>
+ <li><strong>Security</strong>: The <code>ssl</code> parameter now protects
+ every page a logged-in user accesses, when set to "authenticated sessions."
+ Also, SSL is now enforced appropriately in the WebServices interface when
+ the parameter is set.</li>
+
+ <li><strong>Database</strong>: [% terms.Bugzilla %] now uses transactions in
+ the database instead of table locks. This should generally improve
+ performance with many concurrent users. It also means if there is
+ an unexpected error in the middle of a page, all database changes made
+ during that page will be rolled back.</li>
+ <li><strong>Database</strong>: You no longer have to set
+ <code>max_packet_size</code> in MySQL to add large attachments. However,
+ you may need to set it manually if you restore a mysqldump into your
+ database.</li>
+
+ <li>New WebService functions:
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/Bug.html">B<!-- -->ug.add_comment</a>
+ and <a href="[% docs_urlbase FILTER html %]api/Bugzilla/WebService/Bugzilla.html">Bugzilla.extensions</a>.</li>
+
+ <li>You can now delete custom fields, but only if they have never been
+ set on any [% terms.bug %].</li>
+ <li>There is now a <kbd>--reset-password</kbd> argument to
+ <kbd>checksetup.pl</kbd> that allows you to reset a user's password
+ from the command line.</li>
+ <li>There is now a script called <kbd>sanitycheck.pl</kbd> that you can
+ run from the command line. It works just like <kbd>sanitycheck.cgi</kbd>.
+ By default, it only outputs anything if there's an error, so it's
+ ideal for administrators who want to run it nightly in a cron job.</li>
+ <li>The <kbd>strict_isolation</kbd> parameter now prevents you from setting
+ users who cannot see [% terms.abug %] as a CC, Assignee, or QA
+ Contact. Previously it only prevented you from adding users who
+ could not <em>edit</em> the [% terms.bug %].</li>
+ <li>Extensions can now add their own headers to the HTML &lt;head&gt;
+ for things like custom CSS and so on.</li>
+ <li><kbd>sanitycheck.cgi</kbd> has been templatized, meaning that the
+ entire [% terms.Bugzilla %] UI is now contained in templates.</li>
+ <li>When setting the <kbd>sslbase</kbd> parameter, you can now specify
+ a port number in the URL.</li>
+ <li>When importing [% terms.bugs %] using <kbd>importxml.pl</kbd>,
+ attachments will have their actual creator set as their creator,
+ instead of the person who exported the [% terms.bug %] from the other
+ system.</li>
+ <li>The voting system is off by default in new installs. This is to
+ prepare for the fact that it will be moved into an extension at
+ some point in the future.</li>
+ <li>The <code>shutdownhtml</code> parameter now works even when
+ [%+ terms.Bugzilla %]'s database server is down.</li>
+</ul>
+
+<h3>Enhancements for Localizers (or Localized Installations)</h3>
+
+<ul>
+ <li>The documentation can now be localized--in other words, you can have
+ documentation installed for multiple languages at once and
+ [%+ terms.Bugzilla %] will link to the correct language in its internal
+ documentation links.</li>
+ <li>[% terms.Bugzilla %] no longer uses the <kbd>languages</kbd> parameter.
+ Instead it reads the <kbd>template/</kbd> directory to see which
+ languages are available.</li>
+ <li>Some of the messages printed by <kbd>checksetup.pl</kbd> can now
+ be localized. See <kbd>template/en/default/setup/strings.txt.pl</kbd>.
+</ul>
+
+<h2 id="v32_issues">Outstanding Issues</h2>
+
+<ul>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=423439">
+ [%- terms.Bug %] 423439</a>: Tabs in comments will be converted
+ to four spaces, due to a b<!-- -->ug in Perl as of Perl 5.8.8.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=69621">
+ [%- terms.Bug %] 69621</a>: If you rename or remove a keyword that is
+ in use on [% terms.bugs %], you will need to rebuild the "keyword cache"
+ by running <a href="sanitycheck.cgi">sanitycheck.cgi</a> and choosing
+ the option to rebuild the cache when it asks. Otherwise keywords may
+ not show up properly in search results.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=89822">
+ [%- terms.Bug %] 89822</a>: When changing multiple [% terms.bugs %] at
+ the same time, there is no "mid-air collision" protection.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=276230">
+ [%- terms.Bug %] 276230</a>: The support for restricting access to
+ particular Categories of New Charts is not complete. You should treat
+ the 'chartgroup' Param as the only access mechanism available.<br>
+ However, charts migrated from Old Charts will be restricted to
+ the groups that are marked MANDATORY for the corresponding Product.
+ There is currently no way to change this restriction, and the
+ groupings will not be updated if the group configuration
+ for the Product changes.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=370370">
+ [%- terms.Bug %] 370370</a>: mod_perl support is currently not
+ working on Windows machines.</li>
+</ul>
+
+<h2 id="v32_upgrading">How to Upgrade From An Older Version</h2>
+
+<h3 id="v32_upgrading_notes">Notes For Upgraders</h3>
+
+<ul>
+ <li>If you upgrade by CVS, the <kbd>extensions</kbd> and
+ <kbd>skins/contrib</kbd> directories are now in CVS instead of
+ being created by <kbd>checksetup.pl</kbd> If you do a <kbd>cvs update</kbd>
+ from 3.0, you will be told that your directories are "in the way" and
+ you should delete (or move) them and then do <kbd>cvs update</kbd>
+ again. Also, the <kbd>docs</kbd> directory has been restructured
+ and after you <kbd>cvs update</kbd> you can delete the <kbd>docs/html</kbd>,
+ <kbd>docs/pdf</kbd>, <kbd>docs/txt</kbd>, and <kbd>docs/xml</kbd>
+ directories.</li>
+ <li>If you are using MySQL, you should know that [% terms.Bugzilla %]
+ now uses InnoDB for all tables. <kbd>checksetup.pl</kbd> will convert
+ your tables automatically, but if you have InnoDB disabled,
+ the upgrade will not be able to complete (and <kbd>checksetup.pl</kbd>
+ will tell you so).</li>
+
+ <li><strong>You should also read the
+ <a href="#v30_upgrading_notes">[% terms.Bugzilla %] 3.0 Notes For Upgraders
+ section</a> of the
+ <a href="#v32_previous">previous release notes</a> if you are upgrading
+ from a version before 3.0.</strong></li>
+</ul>
+
+<h3>Steps For Upgrading</h3>
+
+<p>Once you have read the notes above, see the
+ <a href="[% docs_urlbase FILTER html %]upgrade.html">Upgrading
+ documentation</a> for instructions on how to upgrade.</p>
+
+<h2 id="v32_code_changes">Code Changes Which May Affect Customizations</h2>
+
+<ul>
+ <li><a href="#v32_code_hooks">More Hooks!</a></li>
+ <li><a href="#v32_code_search">Search.pm Rearchitecture</a></li>
+ <li><a href="#v32_code_lib">lib Directory</a></li>
+ <li><a href="#v32_code_other">Other Changes</a></li>
+</ul>
+
+<h3 id="v32_code_hooks">More Hooks!</h3>
+
+<p>There are more code hooks in 3.2 than there were in 3.0. See the
+ documentation of <a href="[% docs_urlbase FILTER html %]api/Bugzilla/Hook.html">Bugzilla::Hook</a>
+ for more details.</p>
+
+<h3 id="v32_code_search">Search.pm Rearchitecture</h3>
+
+<p><kbd>Bugzilla/Search.pm</kbd> has been heavily modified, to be much
+ easier to read and use. It contains mostly the same code as it did in
+ 3.0, but it has been moved around and reorganized significantly.</p>
+
+<h3 id="v32_code_lib">lib Directory</h3>
+
+<p>As part of implementing <a href="#v32_feat_install">install-module.pl</a>,
+ [%+ terms.Bugzilla %] was given a local <kbd>lib</kbd> directory which
+ it searches for modules, in addition to the standard system path.</p>
+
+<p>This means that all [% terms.Bugzilla %] scripts now start with
+ <code>use lib qw(. lib);</code> as one of the first lines.</p>
+
+<h3 id="v32_code_other">Other Changes</h3>
+
+<ul>
+ <li>You should now be using <code>get_status('NEW')</code> instead of
+ <code>status_descs.NEW</code> in templates.</li>
+ <li>The <code>[&#37;# version = 1.0 &#37;]</code> comment at the top of every
+ template file has been removed.</li>
+</ul>
+
+<h1 id="v32_previous">[% terms.Bugzilla %] 3.0.x Release Notes</h1>
+
+<h2>Table of Contents</h2>
+
+<ul class="bz_toc">
+ <li><a href="#v30_introduction">Introduction</a></li>
+ <li><a href="#v30_point">Updates In This 3.0.x Release</a></li>
+ <li><a href="#v30_req">Minimum Requirements</a></li>
+ <li><a href="#v30_feat">New Features and Improvements</a></li>
+ <li><a href="#v30_issues">Outstanding Issues</a></li>
+ <li><a href="#v30_security">Security Fixes In This Release</a></li>
+ <li><a href="#v30_upgrading">How to Upgrade From An Older Version</a></li>
+ <li><a href="#v30_code_changes">Code Changes Which May Affect
+ Customizations</a></li>
+ <li><a href="#v30_previous">Release Notes for Previous Versions</a></li>
+</ul>
+
+<h2 id="v30_introduction">Introduction</h2>
+
+<p>Welcome to [% terms.Bugzilla %] 3.0! It's been over eight years since
+ we released [% terms.Bugzilla %] 2.0, and everything has changed since
+ then. Even just since our previous release, [% terms.Bugzilla %] 2.22,
+ we've added a <em>lot</em> of new features. So enjoy the release, we're
+ happy to bring it to you.</p>
+
+<p>If you're upgrading, make sure to read <a href="#v30_upgrading">How to
+ Upgrade From An Older Version</a>. If you are upgrading from a release
+ before 2.22, make sure to read the release notes for all the
+ <a href="#v30_previous">previous versions</a> in between your version
+ and this one.</p>
+
+<h2 id="v30_point">Updates in this 3.0.x Release</h2>
+
+<p>This section describes what's changed in the most recent b<!-- -->ug-fix
+ releases of [% terms.Bugzilla %] after 3.0. We only list the
+ most important fixes in each release. If you want a detailed list of
+ <em>everything</em> that's changed in each version, you should use our
+ <a href="http://www.bugzilla.org/status/changes.html">Change Log Page</a>.</p>
+
+<h3>3.0.6</h3>
+
+<ul>
+ <li>Before 3.0.6, unexpected fatal WebService errors would result in
+ a <code>faultCode</code> that was a string instead of a number.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=446327">[% terms.Bug %] 446327</a>)</li>
+ <li>If you created a product or component with the same name as one you
+ previously deleted, it would fail with an error about the series table.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=247936">[% terms.Bug %] 247936</a>)</li>
+</ul>
+
+<p>See also the <a href="#v30_security">Security Advisory</a> section for
+ information about a security issue fixed in this release.</p>
+
+<h3>3.0.5</h3>
+
+<ul>
+ <li>If you don't have permission to set a flag, it will now appear
+ unchangeable in the UI.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=433851">[% terms.Bug %] 433851</a>)</li>
+ <li>If you were running mod_perl, [% terms.Bugzilla %] was not correctly
+ closing its connections to the database since 3.0.3, and so sometimes
+ the DB would run out of connections.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=441592">[% terms.Bug %] 441592</a>)</li>
+ <li>The installation script is now clear about exactly which
+ <code>Email::</code> modules are required in Perl, thus avoiding the
+ problem where emails show up with a body like
+ <samp>SCALAR(0xBF126795)</samp>.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=441541">[% terms.Bug %] 441541</a>)</li>
+ <li><a href="[% docs_urlbase FILTER html %]api/email_in.html">email_in.pl</a>
+ is no longer case-sensitive for values of <kbd>@product</kbd>.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=365697">[% terms.Bug %] 365697</a>)</li>
+</ul>
+
+<p>See also the <a href="#v30_security">Security Advisory</a> section for
+ information about security issues fixed in this release.</p>
+
+<h3>3.0.4</h3>
+
+<ul>
+ <li>[% terms.Bugzilla %] administrators were not being correctly notified
+ about new releases.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=414726">[% terms.Bug %] 414726</a>)</li>
+
+ <li>There could be extra whitespace in email subject lines.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=411544">[% terms.Bug %] 411544</a>)</li>
+
+ <li>The priority, severity, OS, and platform fields were always required by
+ the <kbd>B<!-- -->ug.create</kbd> WebService function, even if they had
+ defaults specified.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=384009">[% terms.Bug %] 384009</a>)</li>
+
+ <li>Better threading of [% terms.bug %]mail in some email clients.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=376453">[% terms.Bug %] 376453</a>)</li>
+
+ <li>There were many fixes to the Inbound Email Interface
+ (<kbd>email_in.pl</kbd>).
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=92274">[% terms.Bug %] 92274</a>,
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=377025">[% terms.Bug %] 377025</a>,
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=412943">[% terms.Bug %] 412943</a>,
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=413672">[% terms.Bug %] 413672</a>, and
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=431721">[% terms.Bug %] 431721</a>)</li>
+
+ <li><kbd>checksetup.pl</kbd> now handles UTF-8 conversion more reliably during upgrades.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=374951">[% terms.Bug %] 374951</a>)</li>
+
+ <li>Comments written in CJK languages are now correctly word-wrapped.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=388723">[% terms.Bug %] 388723</a>)</li>
+
+ <li>All emails will now be sent in the correct language, when the user
+ has chosen a language for emails.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=405946">[% terms.Bug %] 405946</a>)
+
+ <li>On Windows, temporary files created when uploading attachments are now
+ correctly deleted when the upload is complete.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=414002">[% terms.Bug %] 414002</a>)</li>
+
+ <li><kbd>checksetup.pl</kbd> now prints correct installation instructions
+ for Windows users using Perl 5.10.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=414430">[% terms.Bug %] 414430</a>)
+</ul>
+
+<p>See also the <a href="#v30_security">Security Advisory</a> section for
+ information about security issues fixed in this release.</p>
+
+<h3>3.0.3</h3>
+
+<ul>
+ <li>mod_perl no longer compiles [% terms.Bugzilla %]'s code for each Apache
+ process individually. It now compiles code only once and shares it among
+ each Apache process. This greatly improves performance and highly
+ decreases the memory footprint.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=398241">[% terms.Bug %] 398241</a>)</li>
+
+ <li>You can now search for '---' (without quotes) in versions and milestones.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=362436">[% terms.Bug %] 362436</a>)</li>
+
+ <li>[% terms.Bugzilla %] should no longer break lines unnecessarily in
+ email subjects. This was causing trouble with some email clients.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=374424">[% terms.Bug %] 374424</a>)</li>
+
+ <li>If you had selected "I'm added to or removed from this capacity" option
+ for the "CC" role in your email preferences, you wouldn't get mail when
+ more than one person was added to the CC list at once.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=394796">[% terms.Bug %] 394796</a>)</li>
+
+ <li>Deleting a user account no longer deletes whines from another user who
+ has the deleted account as addressee. The schedule is simply removed,
+ but the whine itself is left intact.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=395924">[% terms.Bug %] 395924</a>)</li>
+
+ <li><kbd>contrib/merge-users.pl</kbd> now correctly merges all required
+ fields when merging two user accounts.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=400160">[% terms.Bug %] 400160</a>)</li>
+
+ <li>[% terms.Bugzilla %] no longer requires Apache::DBI to run under
+ mod_perl. It caused troubles such as lost connections with the DB and
+ didn't give any important performance gain.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=408766">[% terms.Bug %] 408766</a>)</li>
+</ul>
+
+<h3>3.0.2</h3>
+
+<ul>
+ <li>[% terms.Bugzilla %] should now work on Perl 5.9.5 (and thus the
+ upcoming Perl 5.10.0).
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=390442">[% terms.Bug %] 390442</a>)</li>
+</ul>
+
+<p>See also the <a href="#v30_security">Security Advisory</a> section for
+ information about an important security issue fixed in this release.</p>
+
+<h3>3.0.1</h3>
+
+<ul>
+ <li>For users of Firefox 2, the <code>show_bug.cgi</code> user interface
+ should no longer "collapse" after you modify [% terms.abug %].
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=370739">[% terms.Bug %] 370739</a>)</li>
+ <li>If you can bless a group, and you share a saved search with that
+ group, it will no longer automatically appear in all of that group's
+ footers unless you specifically request that it automatically appear
+ in their footers.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=365890">[% terms.Bug %] 365890</a>)</li>
+ <li>There is now a parameter to allow users to perform searches without
+ any search terms. (In other words, to search for just a Product
+ and Status on the Simple Search page.) The parameter is called
+ <code>specific_search_allow_empty_words</code>.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=385910">[% terms.Bug %] 385910</a>)</li>
+ <li>If you attach a file that has a MIME-type of <code>text/x-patch</code>
+ or <code>text/x-diff</code>, it will automatically be treated as a
+ patch by [% terms.Bugzilla %].
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=365756">[% terms.Bug %] 365756</a>)</li>
+ <li>Dependency Graphs now work correctly on all mod_perl installations.
+ There should now be no remaining signficant problems with running
+ [%+ terms.Bugzilla %] under mod_perl.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=370398">[% terms.Bug %] 370398</a>)</li>
+ <li>If moving [% terms.abug %] between products would remove groups
+ from the [% terms.bug %], you are now warned.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=303183">[% terms.Bug %] 303183</a>)</li>
+ <li>On IIS, whenever [% terms.Bugzilla %] threw a warning, it would
+ actually appear on the web page. Now warnings are suppressed,
+ unless you have a file in the <code>data</code> directory called
+ <code>errorlog</code>, in which case warnings will be printed there.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=390148">[% terms.Bug %] 390148</a>)</li>
+ <li>If you used <kbd>email_in.pl</kbd> to edit [% terms.abug %] that was
+ protected by groups, all of the groups would be cleared.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=385453">[% terms.Bug %] 385453</a>)</li>
+ <li>PostgreSQL users: New Charts were failing to collect data over time.
+ They will now start collecting data correctly.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=257351">[% terms.Bug %] 257351</a>)</li>
+ <li>Some flag mails didn't specify who the requestee was.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=379787">[% terms.Bug %] 379787</a>)</li>
+ <li>Instead of throwing real errors, <kbd>collectstats.pl</kbd> would
+ just say that it couldn't find <code>ThrowUserError</code>.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=380709">[% terms.Bug %] 380709</a>)</li>
+ <li>Logging into [% terms.Bugzilla %] from the home page works again
+ with IIS5.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=364008">[% terms.Bug %] 364008</a>)</li>
+ <li>If you were using SMTP for sending email, sometimes emails would
+ be missing the <code>Date</code> header.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=304999">[% terms.Bug %] 304999</a>).</li>
+ <li>In the XML-RPC WebService, <code>B<!-- -->ug.legal_values</code> now
+ correctly returns values for custom fields if you request values
+ for custom fields.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=381737">[% terms.Bug %] 381737</a>)</li>
+ <li>The "[% terms.Bug %]-Writing Guidelines" page has been shortened
+ and re-written.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=378590">[% terms.Bug %] 378590</a>)</li>
+ <li>If your <code>urlbase</code> parameter included a port number,
+ like <code>www.domain.com:8080</code>, SMTP might have failed.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=384501">[% terms.Bug %] 384501</a>)</li>
+ <li>For SMTP users, there is a new parameter, <code>smtp_debug</code>.
+ Turning on this parameter will log the full information about
+ every SMTP session to your web server's error log, to help with
+ debugging issues with SMTP.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=384497">[% terms.Bug %] 384497</a>)</li>
+ <li>If you are a "global watcher" (you get all mails from every
+ [%+ terms.bug %]), you can now see that in your Email Preferences.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=365302">[% terms.Bug %] 365302</a>)</li>
+ <li>The Status and Resolution of [% terms.bugs %] are now correctly
+ localized in CSV search results.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=389517">[% terms.Bug %] 389517</a>)</li>
+ <li>The "Subject" line of an email was being mangled if it contained
+ non-Latin characters.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=387860">[% terms.Bug %] 387860</a>)</li>
+ <li>Editing the "languages" parameter using <kbd>editparams.cgi</kbd> would
+ sometimes fail, causing [% terms.Bugzilla %] to throw an error.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=335354">[% terms.Bug %] 335354</a>)</li>
+</ul>
+
+<h2 id="v30_req">Minimum Requirements</h2>
+
+<p>Any requirements that are new since 2.22 will look like
+ <span class="req_new">this</span>.</p>
+
+<ul>
+ <li><a href="#v30_req_perl">Perl</a></li>
+ <li><a href="#v30_req_mysql">For MySQL Users</a></li>
+ <li><a href="#v30_req_pg">For PostgreSQL Users</a></li>
+ <li><a href="#v30_req_modules">Required Perl Modules</a></li>
+ <li><a href="#v30_req_optional_mod">Optional Perl
+ Modules</a></li>
+</ul>
+
+
+<h3 id="v30_req_perl">Perl</h3>
+
+<ul>
+ <li>Perl <span class="req_new">v<strong>5.8.0</strong></span> (non-Windows
+ platforms)</li>
+ <li>Perl v<strong>5.8.1</strong> (Windows platforms)</li>
+</ul>
+
+<h3 id="v30_req_mysql">For MySQL Users</h3>
+
+<ul>
+ <li>MySQL <span class="req_new">v4.1.2</span></li>
+ <li><strong>perl module:</strong> DBD::mysql v2.9003</li>
+</ul>
+
+<h3 id="v30_req_pg">For PostgreSQL Users</h3>
+
+<ul>
+ <li>PostgreSQL v8.00.0000</li>
+ <li><strong>perl module:</strong> DBD::Pg v1.45</li>
+</ul>
+
+<h3 id="v30_req_modules">Required Perl Modules</h3>
+
+<table class="req_table" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <th>Module</th> <th>Version</th>
+ </tr>
+ <tr><td>CGI</td> <td>2.93</td>
+ </tr>
+ <tr>
+ <td>Date::Format</td> <td>2.21</td>
+ </tr>
+ <tr>
+ <td>DBI</td>
+ <td class="req_new">1.41</td>
+ </tr>
+ <tr>
+ <td>File::Spec</td> <td>0.84</td>
+ </tr>
+ <tr>
+ <td>Template</td> <td>2.12</td>
+ </tr>
+ <tr>
+ <td class="req_new">Email::Send</td>
+ <td class="req_new">2.00</td>
+ </tr>
+ <tr>
+ <td>Email::MIME</td>
+ <td>1.861</td>
+ </tr>
+ <tr>
+ <td class="req_new">Email::MIME::Modifier</td>
+ <td class="req_new">1.442</td>
+ </tr>
+</table>
+
+<h3 id="v30_req_optional_mod">Optional Perl Modules</h3>
+
+<p>The following perl modules, if installed, enable various
+ features of [% terms.Bugzilla %]:</p>
+
+<table class="req_table" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <th>Module</th> <th>Version</th>
+ <th>Enables Feature</th>
+ </tr>
+ <tr>
+ <td class="req_new">LWP::UserAgent</td>
+ <td class="req_new">(Any)</td>
+ <td>Automatic Update Notifications</td>
+ </tr>
+ <tr>
+ <td>Template::Plugin::GD::Image</td>
+ <td>(Any)</td>
+ <td>Graphical Reports</td>
+ </tr>
+ <tr>
+ <td>GD::Graph</td>
+ <td>(Any)</td>
+ <td>Graphical Reports</td>
+ </tr>
+ <tr>
+ <td>GD::Text</td>
+ <td>(Any)</td>
+ <td>Graphical Reports</td>
+ </tr>
+ <tr>
+ <td>GD</td>
+ <td>1.20</td>
+ <td>Graphical Reports, New Charts, Old Charts</td>
+ </tr>
+ <tr>
+ <td class="req_new">Email::MIME::Attachment::Stripper</td>
+ <td class="req_new">(Any)</td>
+ <td>Inbound Email</td>
+ </tr>
+ <tr>
+ <td class="req_new">Email::Reply</td>
+ <td class="req_new">(Any)</td>
+ <td>Inbound Email</td>
+ </tr>
+ <tr>
+ <td>Net::LDAP</td>
+ <td>(Any)</td>
+ <td>LDAP Authentication</td>
+ </tr>
+ <tr>
+ <td>HTML::Parser</td>
+ <td>3.40</td>
+ <td>More HTML in Product/Group Descriptions</td>
+ </tr>
+ <tr>
+ <td>HTML::Scrubber</td>
+ <td>(Any)</td>
+ <td>More HTML in Product/Group Descriptions</td>
+ </tr>
+ <tr>
+ <td>XML::Twig</td>
+ <td>(Any)</td>
+ <td>Move [% terms.Bugs %] Between Installations</td>
+ </tr>
+ <tr>
+ <td>MIME::Parser</td>
+ <td>5.406</td>
+ <td>Move [% terms.Bugs %] Between Installations</td>
+ </tr>
+ <tr>
+ <td>Chart::Base</td>
+ <td>1.0</td>
+ <td>New Charts, Old Charts</td>
+ </tr>
+ <tr>
+ <td>Image::Magick</td>
+ <td>(Any)</td>
+ <td>Optionally Convert BMP Attachments to PNGs</td>
+ </tr>
+ <tr>
+ <td>PatchReader</td>
+ <td>0.9.4</td>
+ <td>Patch Viewer</td>
+ </tr>
+ <tr>
+ <td class="req_new">SOAP::Lite</td>
+ <td class="req_new">(Any)</td>
+ <td>XML-RPC Interface</td>
+ </tr>
+ <tr>
+ <td class="req_new">mod_perl2</td>
+ <td class="req_new">1.999022</td>
+ <td>mod_perl</td>
+ </tr>
+ <tr>
+ <td> CGI</td>
+ <td>3.11</td>
+ <td>mod_perl</td>
+ </tr>
+</table>
+
+<h2 id="v30_feat">New Features and Improvements</h2>
+
+<ul>
+ <li><a href="#v30_feat_cf">Custom Fields</a></li>
+ <li><a href="#v30_feat_mp">mod_perl Support</a></li>
+ <li><a href="#v30_feat_sq">Shared Saved Searches</a></li>
+ <li>
+ <a href="#v30_feat_afn">Attachments and Flags on New [% terms.Bugs %]</a>
+ </li>
+ <li><a href="#v30_feat_cr">Custom Resolutions</a></li>
+ <li><a href="#v30_feat_ppp">Per-Product Permissions</a></li>
+ <li><a href="#v30_feat_ui">User Interface Improvements</a></li>
+ <li><a href="#v30_feat_xml">XML-RPC Interface</a></li>
+ <li><a href="#v30_feat_skin">Skins</a></li>
+ <li><a href="#v30_feat_sbu">Unchangeable Fields Appear
+ Unchangeable</a></li>
+ <li><a href="#v30_feat_et">All Emails in Templates</a></li>
+ <li><a href="#v30_feat_df">No More Double-Filed [% terms.Bugs %]</a></li>
+ <li><a href="#v30_feat_cc">Default CC List for Components</a></li>
+ <li><a href="#v30_feat_emi">File/Modify [% terms.Bugs %] By Email</a></li>
+ <li><a href="#v30_feat_gw">Users Who Get All [% terms.Bug %]
+ Notifications</a></li>
+ <li><a href="#v30_feat_utf8">Improved UTF-8 Support</a></li>
+ <li><a href="#v30_feat_upda">Automatic Update Notification</a></li>
+ <li><a href="#v30_feat_welc">Welcome Page for New Installs</a></li>
+ <li><a href="#v30_feat_other">Other Enhancements and Changes</a></li>
+</ul>
+
+<h3 id="v30_feat_cf">Custom Fields</h3>
+
+<p>[% terms.Bugzilla %] now includes very basic support for custom fields.</p>
+
+<p>Users in the <kbd>admin</kbd> group can add plain-text or drop-down
+ custom fields. You can edit the values available for drop-down fields
+ using the &quot;Field Values&quot; control panel.</p>
+
+<p>Don't add too many custom fields! It can make [% terms.Bugzilla %]
+ very difficult to use. Try your best to get along with the default
+ fields, and then if you find that you can't live without custom fields
+ after a few weeks of using [% terms.Bugzilla %], only then should you
+ start your custom fields.</p>
+
+<h3 id="v30_feat_mp">mod_perl Support</h3>
+
+<p>[% terms.Bugzilla %] 3.0 supports mod_perl, which allows for extremely
+ enhanced page-load performance. mod_perl trades memory usage for performance,
+ allowing near-instantaneous page loads, but using much more memory.</p>
+
+<p>If you want to enable mod_perl for your [% terms.Bugzilla %], we recommend
+ a minimum of 1.5GB of RAM, and for a site with heavy traffic, 4GB to 8GB.</p>
+
+<p>If performance isn't that critical on your installation, you don't
+ have the memory, or you are running some other web server than
+ Apache, [% terms.Bugzilla %] still runs perfectly as a normal CGI
+ application, as well.</p>
+
+<h3 id="v30_feat_sq">Shared Saved Searches</h3>
+
+<p>Users can now choose to &quot;share&quot; their saved searches
+ with a certain group. That group will then be able to
+ &quot;subscribe&quot; to those searches, and have them appear
+ in their footer.</p>
+
+<p>If the sharer can &quot;bless&quot; the group he's sharing to,
+ (that is, if he can add users to that group), it's considered
+ that he's a manager of that group, and his queries show up
+ automatically in that group's footer (although they can
+ unsubscribe from any particular search, if they want.)</p>
+
+<p>In order to allow a user to share their queries, they also
+ have to be a member of the group specified in the
+ <code>querysharegroup</code> parameter.</p>
+
+<p>Users can control their shared and subscribed queries from
+ the &quot;Preferences&quot; screen.</p>
+
+<h3 id="v30_feat_afn">Attachments and Flags on New [% terms.Bugs %]</h3>
+
+<p>You can now add an attachment while you are filing a new
+ [%+ terms.bug %].</p>
+
+<p>You can also set flags on the [% terms.bug %] and on attachments, while
+ filing a new [% terms.bug %].</p>
+
+<h3 id="v30_feat_cr">Custom Resolutions</h3>
+
+<p>You can now customize the list of resolutions available
+ in [% terms.Bugzilla %], including renaming the default resolutions.</p>
+
+<p>The resolutions <code>FIXED</code>, <code>DUPLICATE</code>
+ and <code>MOVED</code> have a special meaning to [% terms.Bugzilla %],
+ though, and cannot be renamed or deleted.</p>
+
+<h3 id="v30_feat_ppp">Per-Product Permissions</h3>
+
+<p>You can now grant users <kbd>editbugs</kbd> and <kbd>canconfirm</kbd>
+ for only certain products. You can also grant users <kbd>editcomponents</kbd>
+ on a product, which means they will be able to edit that product
+ including adding/removing components and other product-specific
+ controls.</p>
+
+<h3 id="v30_feat_ui">User Interface Improvements</h3>
+
+<p>There has been some work on the user interface for [% terms.Bugzilla %] 3.0,
+ including:</p>
+
+<ul>
+ <li>There is now navigation and a search box a the <em>top</em> of
+ each page, in addition to the bar at the bottom of the page.</li>
+ <li>A re-designed &quot;Format for Printing&quot; page for
+ [%+ terms.bugs %].</li>
+ <li>The layout of <kbd>show_bug.cgi</kbd> (the [% terms.bug %] editing
+ page) has been changed, and the attachment table has been redesigned.</li>
+</ul>
+
+<h3 id="v30_feat_xml">XML-RPC Interface</h3>
+
+<p>[% terms.Bugzilla %] now has a Web Services interface using the XML-RPC
+ protocol. It can be accessed by external applications by going
+ to the <kbd>xmlrpc.cgi</kbd> on your installation.</p>
+
+<p>Documentation can be found in the
+ <a href="[% docs_urlbase FILTER html %]api/">[% terms.Bugzilla %]
+ API Docs</a>, in the various <kbd>Bugzilla::WebService</kbd> modules.</p>
+
+<h3 id="v30_feat_skin">Skins</h3>
+
+<p>[% terms.Bugzilla %] can have multiple &quot;skins&quot; installed,
+ and users can pick between them. To write a skin, you just have to
+ write several CSS files. See the <a href="[% docs_urlbase FILTER html %]cust-skins.html">Custom
+ Skins Documentation</a> for more details.</p>
+
+<p>We currently don't have any alternate skins shipping with
+ [%+ terms.Bugzilla %]. If you write an alternate skin, please
+ let us know!</p>
+
+<h3 id="v30_feat_sbu">Unchangeable Fields Appear Unchangeable</h3>
+
+<p>As long as you are logged in, when viewing [% terms.abug %], if you
+ cannot change a field, it will not look like you can change it. That
+ is, the value will just appear as plain text.</p>
+
+<h3 id="v30_feat_et">All Emails in Templates</h3>
+
+<p>All outbound emails are now controlled by the templating system.
+ What used to be the <code>passwordmail</code>, <code>whinemail</code>,
+ <code>newchangedmail</code> and <code>voteremovedmail</code>
+ parameters are now all templates in the <kbd>template/</kbd> directory.</p>
+
+<p>This means that it's now much easier to customize your outbound
+ emails, and it's also possible for localizers to have more
+ localized emails as part of their language packs, if they want.</p>
+
+<p>We also added a <code>mailfrom</code> parameter to let you set
+ who shows up in the <code>From</code> field on all emails that
+ [%+ terms.Bugzilla %] sends.</p>
+
+<h3 id="v30_feat_df">No More Double-Filed [% terms.Bugs %]</h3>
+
+<p>Users of [% terms.Bugzilla %] will sometimes accidentally submit
+ [%+ terms.abug %] twice, either by going back in their web browser,
+ or just by refreshing a page. In the past, this could file the same
+ [%+ terms.bug %] twice (or even three times) in a row, irritating
+ developers and confusing users.</p>
+
+<p>Now, if you try to submit [% terms.abug %] twice from the same screen
+ (by going back or by refreshing the page), [% terms.Bugzilla %] will warn
+ you about what you're doing, before it actually submits the duplicate
+ [%+ terms.bug %].</p>
+
+<h3 id="v30_feat_cc">Default CC List for Components</h3>
+
+<p>You can specify a list of users who will <em>always</em> be added to
+ the CC list of new [% terms.bugs %] in a component.</p>
+
+<h3 id="v30_feat_emi">File/Modify [% terms.Bugs %] By Email</h3>
+
+<p>You can now file or modify [% terms.bugs %] via email. Previous versions
+ of [% terms.Bugzilla %] included this feature only as an
+ unsupported add-on, but it is now an official interface to
+ [%+ terms.Bugzilla %].</p>
+
+<p>For more details see the <a href="[% docs_urlbase FILTER html %]api/email_in.html">documentation
+ for email_in.pl</a>.</p>
+
+<h3 id="v30_feat_gw">Users Who Get All [% terms.Bug %] Notifications</h3>
+
+<p>There is now a parameter called <kbd>globalwatchers</kbd>. This
+ is a comma-separated list of [% terms.Bugzilla %] users who will
+ get all [% terms.bug %] notifications generated by [% terms.Bugzilla %].</p>
+
+<p>Group controls still apply, though, so users who can't see [% terms.abug %]
+ still won't get notifications about that [% terms.bug %].</p>
+
+<h3 id="v30_feat_utf8">Improved UTF-8 Support</h3>
+
+<p>[% terms.Bugzilla %] users running MySQL should now have excellent
+ UTF-8 support if they turn on the <kbd>utf8</kbd> parameter. (New
+ installs have this parameter on by default.) [% terms.Bugzilla %]
+ now correctly supports searching and sorting in non-English languages,
+ including multi-bytes languages such as Chinese.</p>
+
+<h3 id="v30_feat_upda">Automatic Update Notification</h3>
+
+<p>If you belong to the <kbd>admin</kbd> group, you will be notified
+ when you log in if there is a new release of [% terms.Bugzilla %]
+ available to download.</p>
+
+<p>You can control these notifications by changing the
+ <kbd>upgrade_notification</kbd> parameter.</p>
+
+<p>If your [% terms.Bugzilla %] installation is on a machine that needs to go
+ through a proxy to access the web, you may also have to set the
+ <kbd>proxy_url</kbd> parameter.</p>
+
+<h3 id="v30_feat_welc">Welcome Page for New Installs</h3>
+
+<p>When you log in for the first time on a brand-new [% terms.Bugzilla %]
+ installation, you will be presented with a page that describes
+ where you should go from here, and what parameters you should set.</p>
+
+<h3 id="v30_feat_qs">QuickSearch Plugin for IE7 and Firefox 2</h3>
+
+<p>Firefox 2 users and Internet Explorer 7 users will be presented
+ with the option to add [% terms.Bugzilla %] to their search bar.
+ This uses the
+ <a href="page.cgi?id=quicksearch.html">QuickSearch syntax</a>.</p>
+
+<h3 id="v30_feat_other">Other Enhancements and Changes</h3>
+
+<p>These are either minor enhancements, or enhancements that have
+ very short descriptions. Some of these are very useful, though!</p>
+
+<h4>Enhancements That Affect [% terms.Bugzilla %] Users</h4>
+
+<ul>
+ <li>In comments, quoted text (lines that start with <kbd>&gt;</kbd>)
+ will be a different color from normal text.</li>
+ <li>There is now a user preference that will add you to the CC list
+ of any [% terms.bug %] you modify. Note that it's <strong>on</strong>
+ by default.</li>
+ <li>[% terms.Bugs %] can now be filed with an initial state of
+ <kbd>ASSIGNED</kbd>, if you are in the <kbd>editbugs</kbd> group.</li>
+ <li>By default, comment fields will zoom large when you are typing in them,
+ and become small when you move out of them. You can disable this
+ in your user preferences.</li>
+ <li>You can hide obsolete attachments on [% terms.abug %] by clicking
+ &quot;Hide Obsolete&quot; at the bottom of the attachment table.</li>
+ <li>If [% terms.abug %] has flags set, and you move it to a different
+ product that has flags with the same name, the flags will be
+ preserved.</li>
+ <li>You now can't request a flag to be set by somebody who can't set it
+ ([% terms.Bugzilla %] will throw an error if you try).</li>
+ <li>Many new headers have been added to outbound [% terms.Bugzilla %]
+ [%+ terms.bug %] emails: <code>X-Bugzilla-Status</code>,
+ <code>X-Bugzilla-Priority</code>, <code>X-Bugzilla-Assigned-To</code>,
+ <code>X-Bugzilla-Target-Milestone</code>, and
+ <code>X-Bugzilla-Changed-Fields</code>, <code>X-Bugzilla-Who</code>.
+ You can look at an email to get an idea of what they contain.</li>
+ <li>In addition to the old <code>X-Bugzilla-Reason</code> email header
+ which tells you why you got an email, if you got an email because
+ you were watching somebody, there is now an
+ <code>X-Bugzilla-Watch-Reason</code> header that tells you who you
+ were watching and what role they had.</li>
+ <li>If you hover your mouse over a full URL (like
+ <code>http://bugs.mycompany.com/show_bug.cgi?id=1212</code>) that
+ links to [% terms.abug %], you will see the title of the
+ [%+ terms.bug %]. Of course, this only works for [% terms.bugs %] in your
+ [%+ terms.Bugzilla %] installation.</li>
+ <li>If your installation has user watching enabled, you will now see
+ the users that you can remove from your watch-list as a multi-select
+ box, much like the current CC list. (Previously it was just a text
+ box.)</li>
+ <li>When a user creates their own account in [% terms.Bugzilla %], the
+ account is now not actually created until they verify their email
+ address by clicking on a link that is emailed to them.</li>
+ <li>You can change [% terms.abug %]'s resolution without reopening it.</li>
+ <li>When you view the dependency tree on [% terms.abug %], resolved
+ [%+ terms.bugs %] will be hidden by default. (In previous versions,
+ resolved [% terms.bugs %] were shown by default.)</li>
+ <li>When viewing [% terms.bug %] activity, fields that hold [% terms.bug %]
+ numbers (such as &quot;Blocks&quot;) will have the [% terms.bug %] numbers
+ displayed as links to those [% terms.bugs %].</li>
+ <li>When viewing the &quot;Keywords&quot; field in [% terms.abug %] list,
+ it will be sorted alphabetically, so you can sanely sort a list on
+ that field.</li>
+ <li>In most places, the Version field is now sorted using a version-sort
+ (so 1.10 is greater than 1.2) instead of an alphabetical sort.</li>
+ <li>Options for flags will only appear if you can set them. So, for
+ example, if you can't grant <kbd>+</kbd> on a flag, that option
+ won't appear for you.</li>
+ <li>You can limit the product-related output of <kbd>config.cgi</kbd>
+ by specifying a <kbd>product=</kbd> URL argument, containing the name
+ of a product. You can specify the argument more than once for multiple
+ products.</li>
+ <li>You can now search the boolean charts on whether or not a comment
+ is private.</li>
+</ul>
+
+<h4>Enhancements For Administrators</h4>
+
+<ul>
+ <li>Administrators can now delete attachments, making them disappear
+ entirely from [% terms.Bugzilla %].</li>
+ <li><kbd>sanitycheck.cgi</kbd> can now only be accessed by users
+ in the <kbd>editcomponents</kbd> group.</li>
+ <li>The &quot;Field Values&quot; control panel can now only be accessed
+ by users in the <kbd>admin</kbd> group. (Previously it was accessible
+ to anybody in the <kbd>editcomponents</kbd> group.)</li>
+ <li>There is a new parameter <kbd>announcehtml</kbd>, that will allow
+ you to enter some HTML that will be displayed at the top of every
+ page, as an announcement.</li>
+ <li>The <kbd>loginnetmask</kbd> parameter now defaults to 0 for new
+ installations, meaning that as long as somebody has the right
+ login cookie, they can log in from any IP address. This makes
+ life a lot easier for dial-up users or other users whose IP
+ changes a lot. This could be done because the login cookie is now
+ very random, and thus secure.</li>
+ <li>Classifications now have sortkeys, so they can be sorted in an
+ order that isn't alphabetical.</li>
+ <li>Authentication now supports LDAP over SSL (LDAPS) or TLS (using
+ the STARTLS command) in addition to plain LDAP.</li>
+ <li>LDAP users can have their LDAP username be their email address,
+ instead of having the LDAP <kbd>mail</kbd> attribute be their
+ email address. You may wish to set the <kbd>emailsuffix</kbd>
+ parameter if you do this.</li>
+ <li>Administrators can now see what has changed in a user account,
+ when using the &quot;Users&quot; control panel.</li>
+ <li><code>REMIND</code> and <code>LATER</code> are no longer part
+ of the default list of resolutions. Upgrading installations will
+ not be affected--they will still have these resolutions.</li>
+ <li><kbd>editbugs</kbd> is now the default for the <kbd>timetrackinggroup</kbd>
+ parameter, meaning that time-tracking will be on by default in a new
+ installation.</li>
+</ul>
+
+<h2 id="v30_issues">Outstanding Issues</h2>
+
+<ul>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=69621">
+ [%- terms.Bug %] 69621</a>: If you rename or remove a keyword that is
+ in use on [% terms.bugs %], you will need to rebuild the "keyword cache"
+ by running <a href="sanitycheck.cgi">sanitycheck.cgi</a> and choosing
+ the option to rebuild the cache when it asks. Otherwise keywords may
+ not show up properly in search results.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=99215">
+ [%- terms.Bug %] 99215</a>: Flags are not protected by "mid-air
+ collision" detection. Nor are any attachment changes.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=89822">
+ [%- terms.Bug %] 89822</a>: When changing multiple [% terms.bugs %] at
+ the same time, there is no "mid-air collision" protection.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=276230">
+ [%- terms.Bug %] 276230</a>: The support for restricting access to
+ particular Categories of New Charts is not complete. You should treat
+ the 'chartgroup' Param as the only access mechanism available.<br>
+ However, charts migrated from Old Charts will be restricted to
+ the groups that are marked MANDATORY for the corresponding Product.
+ There is currently no way to change this restriction, and the
+ groupings will not be updated if the group configuration
+ for the Product changes.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=370370">
+ [%- terms.Bug %] 370370</a>: mod_perl support is currently not
+ working on Windows machines.</li>
+ <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=361149">
+ [%- terms.Bug %] 361149</a>: If you are using Perl 5.8.0, you may
+ get a lot of warnings in your Apache error_log about "deprecated
+ pseudo-hashes." These are harmless--they are a b[%# fool test %]ug in
+ Perl 5.8.0. Perl 5.8.1 and later do not have this problem.</li>
+ <li>[% terms.Bugzilla %] 3.0rc1 allowed custom field column names in
+ the database to be mixed-case. [% terms.Bugzilla %] 3.0 only allows
+ lowercase column names. It will fix any column names that you have
+ made mixed-case, but if you have custom fields that previously were
+ mixed-case in any Saved Search, you will have to re-create that Saved
+ Search yourself.</li>
+</ul>
+
+<h2 id="v30_security">Security Updates in This Release</h2>
+
+<h3>3.0.6</h3>
+
+<p>[% terms.Bugzilla %] contains a minor security fix. For details, see the
+ <a href="http://www.bugzilla.org/security/2.20.6/">Security Advisory</a>.</p>
+
+<h3>3.0.5</h3>
+
+<p>[% terms.Bugzilla %] contains one security fix for
+ <a href="[% docs_urlbase FILTER html %]api/importxml.html">importxml.pl</a>.
+ For details, see the
+ <a href="http://www.bugzilla.org/security/2.22.4/">Security Advisory</a>.</p>
+
+<h3>3.0.4</h3>
+
+<p>[% terms.Bugzilla %] 3.0.4 contains three security fixes.
+ For details, see the
+ <a href="http://www.bugzilla.org/security/2.20.5/">Security Advisory</a>.</p>
+
+<h3>3.0.3</h3>
+
+<p>No security fixes in this release.</p>
+
+<h3>3.0.2</h3>
+
+<p>[% terms.Bugzilla %] 3.0.1 had an important security fix that is
+ critical for public installations with "requirelogin" turned on.
+ For details, see the
+ <a href="http://www.bugzilla.org/security/3.0.1/">Security Advisory</a></p>
+
+<h3>3.0.1</h3>
+
+<p>[% terms.Bugzilla %] 3.0 had three security issues that have been
+ fixed in this release: one minor information leak, one hole only
+ exploitable by an admin or using <code>email_in.pl</code>, and one in an
+ uncommonly-used template. For details, see the
+ <a href="http://www.bugzilla.org/security/2.20.4/">Security Advisory</a>.</p>
+
+<h2 id="v30_upgrading">How to Upgrade From An Older Version</h2>
+
+<h3 id="v30_upgrading_notes">Notes For Upgraders</h3>
+
+<ul>
+ <li>If you upgrade by CVS, there are several .cvsignore files
+ that are now in CVS instead of being locally created by
+ <kbd>checksetup.pl</kbd>. This means that you will have to
+ delete those files when CVS tells you there's a conflict, and
+ then run <kbd>cvs update</kbd> again.</li>
+ <li>In this version of [% terms.Bugzilla %], the Summary field
+ is now limited to 255 characters. When you upgrade, any Summary
+ longer than that will be truncated, and the old summary will be
+ preserved in a comment.</li>
+ <li>If you have the <kbd>utf8</kbd> parameter turned on, at some
+ point you will have to convert your database. <kbd>checksetup.pl</kbd>
+ will tell you when this is, and it will give you certain instructions
+ at that time, that you have to follow before you can complete
+ the upgrade. Don't do the conversion yourself manually--follow
+ the instructions of <kbd>checksetup.pl</kbd>.</li>
+ <li>If you ever ran 2.23.3, 2.23.4, or 3.0rc1, you will have to run
+ <kbd>./collectstats.pl --regenerate</kbd> at the command line, because
+ the data for your Old Charts is corrupted. This can take several days,
+ so you may only want to run it if you use Old Charts.</li>
+ <li>You should also read the Outstanding Issues sections of
+ <a href="#v30_previous">older release notes</a> if you are upgrading
+ from a version lower than 2.22.</li>
+</ul>
+
+<h3>Steps For Upgrading</h3>
+
+<p>Once you have read the notes above, see the
+ <a href="[% docs_urlbase FILTER html %]upgrade.html">Upgrading
+ documentation</a> for instructions on how to upgrade.</p>
+
+<h2 id="v30_code_changes">Code Changes Which May Affect Customizations</h2>
+
+<ul>
+ <li><a href="#v30_code_loc"><strong>Packagers:</strong> Location
+ Variables Have Moved</a></li>
+ <li><a href="#v30_code_hooks">Hooks!</a></li>
+ <li><a href="#v30_code_api">API Documentation</a></li>
+ <li><a href="#v30_code_globals">Elimination of globals.pl</a></li>
+ <li><a href="#v30_code_scope">Cleaned Up Variable Scoping Issues</a></li>
+ <li><a href="#v30_code_sql">No More SendSQL</a></li>
+ <li><a href="#v30_code_auth">Auth Re-write</a></li>
+ <li><a href="#v30_code_obj">Bugzilla::Object</a></li>
+ <li><a href="#v30_code_req">Bugzilla-&gt;request_cache</a></li>
+ <li><a href="#v30_code_other">Other Changes</a></li>
+</ul>
+
+<h3 id="v30_code_loc"><strong>Packagers:</strong> Location Variables
+ Have Moved</h3>
+
+<p>In previous versions of [% terms.Bugzilla %], <kbd>Bugzilla::Config</kbd>
+ held all the paths for different things, such as the path to localconfig
+ and the path to the <kbd>data/</kbd> directory.</p>
+
+<p>Now, all of this data is stored in a subroutine,
+ <kbd>Bugzilla::Constants::bz_locations</kbd>.</p>
+
+<p>Also, note that for mod_perl, <kbd>bz_locations</kbd> must return
+ <em>absolute</em> (not relative) paths. There is already code in that
+ subroutine to help you with this.</p>
+
+<h3 id="v30_code_hooks">Hooks!</h3>
+
+<p>[% terms.Bugzilla %] now supports a code hook mechanism. See the
+ documentation for
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/Hook.html">Bugzilla::Hook</a>
+ for more details.</p>
+
+<p>This gives [% terms.Bugzilla %] very advanced plugin support. You can
+ hook templates, hook code, add new parameters, and use the XML-RPC
+ interface. So we'd like to see some [% terms.Bugzilla %] plugins
+ written! Let us know on the <a href="http://bugzilla.org/cgi-bin/mj_wwwusr?func=lists-long-full&amp;extra=developers">developers&#64;bugzilla.org</a>
+ mailing list if you write a plugin.</p>
+
+<p>If you need more hooks, please
+ <a href="http://www.bugzilla.org/developers/reporting_bugs.html">File a b<!-- -->ug</a>!</p>
+
+<h3 id="v30_code_api">API Documentation</h3>
+
+<p>[% terms.Bugzilla %] now ships with all of its perldoc built
+ as HTML. Go ahead and read the
+ <a href="[% docs_urlbase FILTER html %]api/">API Documentation</a>
+ for all of the [% terms.Bugzilla %] modules now! Even scripts like
+ <kbd>checksetup.pl</kbd> have HTML documentation.</p>
+
+<h3 id="v30_code_globals">Elimination of globals.pl</h3>
+
+<p>The old file <kbd>globals.pl</kbd> has been eliminated.
+ Its code is now in various modules. Each function went to the module
+ that was appropriate for it.</p>
+
+<p>Usually we filed [% terms.abug %] in
+ <a href="https://bugzilla.mozilla.org">bugzilla.mozilla.org</a> for
+ each function we moved. You can search there for the old name of
+ the function, and that should get you the information about what
+ it's called now and where it lives.</p>
+
+<h3 id="v30_code_scope">Cleaned Up Variable Scoping Issues</h3>
+
+<p>In normal perl, you can have code like this:</p>
+<pre>my $var = 0;
+sub y { $var++ }</pre>
+
+<p>However, under mod_perl that doesn't work. So variables are no
+ longer &quot;shared&quot; with subroutines--instead all variables
+ that a subroutine needs must be declared inside the subroutine itself.</p>
+
+<h3 id="v30_code_sql">No More SendSQL</h3>
+
+<p>The old <kbd>SendSQL</kbd> function and all of its companions are
+ <strong>gone</strong>. Instead, we now use DBI for all database
+ interaction.</p>
+
+<p>For more information about how to use
+ <a href="http://search.cpan.org/perldoc?DBI">DBI</a> with
+ [%+ terms.Bugzilla %], see the
+ <a href="http://www.bugzilla.org/docs/developer.html#sql-sendreceive">Developer's
+ Guide Section About DBI</a></p>
+
+<h3 id="v30_code_auth">Auth Re-write</h3>
+
+<p>The <kbd>Bugzilla::Auth</kbd> family of modules have been completely
+ re-written. For details on how the new structure of authentication,
+ read the
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/Auth.html">Bugzilla::Auth
+ API docs</a>.</p>
+
+<p>It should be very easy to write new authentication plugins, now.</p>
+
+<h3 id="v30_code_obj">Bugzilla::Object</h3>
+
+<p>There is a new base class for most of our objects,
+ <a href="[% docs_urlbase FILTER html %]api/Bugzilla/Object.html">Bugzilla::Object</a>.
+ It makes it really easy to create new objects based on things that are
+ in the database.</p>
+
+<h3 id="v30_code_req">Bugzilla-&gt;request-cache</h3>
+
+<p><kbd>Bugzilla.pm</kbd> used to cache things like the database
+ connection in package-global variables (like <kbd>$_dbh</kbd>).
+ That doesn't work in mod_perl, so instead now there's a hash
+ that can be accessed through <code>Bugzilla-&gt;request_cache</code>
+ to store things for the rest of the current page request.</p>
+
+<p>You shouldn't access <code>Bugzilla-&gt;request_cache</code> directly,
+ but you should use it inside of <kbd>Bugzilla.pm</kbd> if you modify
+ that. The only time you should be accessing it directly is if you need
+ to reset one of the caches. Hash keys are always named after the function
+ that they cache, so to reset the template object, you'd do:
+ <code>delete Bugzilla-&gt;request_cache-&gt;{template};</code>.</p>
+
+<h3 id="v30_code_other">Other Changes</h3>
+
+<ul>
+ <li><kbd>checksetup.pl</kbd> has been completely re-written, and most
+ of its code moved into modules in the <kbd>Bugzilla::Install</kbd>
+ namespace. See the
+ <a href="[% docs_urlbase FILTER html %]api/checksetup.html">checksetup
+ documentation</a> and <a href="https://bugzilla.mozilla.org/showdependencytree.cgi?id=277502&amp;hide_resolved=0">[% terms.Bugzilla %]
+ [%+ terms.bug %] 277502</a> for details.</li>
+ <li>Instead of <kbd>UserInGroup()</kbd>, all of [% terms.Bugzilla %] now
+ uses <kbd>Bugzilla-&gt;user-&gt;in_group</kbd></li>
+ <li>mod_perl doesn't like dependency loops in modules, so we now have
+ a test for that detects dependency loops in modules when you run
+ <kbd>runtests.pl</kbd>.</li>
+ <li><kbd>globals.pl</kbd> used to modify the environment variables,
+ like <kbd>PATH</kbd>. That now happens in <kbd>Bugzilla.pm</kbd>.</li>
+ <li>Templates can now link to the documentation more easily.
+ See the <kbd>global/code-error.html.tmpl</kbd> and
+ <kbd>global/user-error.html.tmpl</kbd> templates for examples.
+ (Search for &quot;docslinks.&quot;)</li>
+ <li>Parameters are accessed through <kbd>Bugzilla-&gt;params</kbd>
+ instead of using the <kbd>Param()</kbd> function, now.</li>
+ <li>The variables from the <kbd>localconfig</kbd> file are accessed
+ through the <code>Bugzilla-&gt;localconfig</code> hash instead of through
+ <kbd>Bugzilla::Config</kbd>.</li>
+ <li><kbd>Bugzilla::BugMail::MessageToMTA()</kbd> has moved into its
+ own module, along with other mail-handling code, called
+ <kbd>Bugzilla::Mailer</kbd></li>
+ <li>The <kbd>CheckCanChangeField()</kbd> subroutine in
+ <kbd>process_bug.cgi</kbd> has been moved to <kbd>Bugzilla::Bug</kbd>,
+ and is now a method of [% terms.abug %] object.</li>
+ <li>The code that used to be in the <kbd>global/banner.html.tmpl</kbd>
+ template is now in <kbd>global/header.html.tmpl</kbd>. The banner
+ still exists, but the file is empty.</li>
+</ul>
+
+<h2 id="v30_previous">Release Notes For Previous Versions</h2>
+
+<p>Release notes for versions of [% terms.Bugzilla %] for versions
+ prior to 3.0 are only available in text format:
+ <a href="[% docs_urlbase FILTER remove('html/$') FILTER html %]rel_notes.txt">Release Notes for [% terms.Bugzilla %] 2.22
+ and Earlier</a>.</p>
+
+[% INCLUDE global/footer.html.tmpl %]
+
+[% BLOCK db_req %]
+ [% SET m = DB_MODULE.$db %]
+ <h3 id="v40_req_[% db FILTER html %]">For [% m.name FILTER html %] Users</h3>
+
+ <ul>
+ <li>[% m.name FILTER html %]
+ [%+ '<span class="req_new">' IF db_new %]v[% m.db_version FILTER html %]
+ [% '</span>' IF db_new %]
+ </li>
+ <li><strong>perl module:</strong>
+ [%+ m.dbd.module FILTER html %]
+ [% '<span class="req_new">' IF dbd_new %]v[% m.dbd.version FILTER html %]
+ [% '</span>' IF dbd_new %]</li>
+ </ul>
+[% END %]
+
+
+[% BLOCK req_table %]
+ <table class="req_table" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <th>Module</th> <th>Version</th>
+ [% IF include_feature %]
+ <th>Enables Feature</th>
+ [% END %]
+ </tr>
+ [% FOREACH req = reqs %]
+ <tr>
+ <td [% ' class="req_new"' IF new.contains(req.package) %]>
+ [%- req.module FILTER html %]</td>
+ <td [% ' class="req_new"' IF updated.contains(req.package)
+ OR new.contains(req.package) %]>
+ [%- IF req.version == 0 %]
+ (Any)
+ [% ELSE %]
+ [%- req.version FILTER html %]
+ [% END %]
+ </td>
+ [% IF include_feature %]
+ <td>[% req.feature.join(', ') FILTER html %]</td>
+ [% END %]
+ </tr>
+ [% END %]
+</table>
+[% END %]
diff --git a/template/en/default/pages/sudo.html.tmpl b/template/en/default/pages/sudo.html.tmpl
new file mode 100644
index 0000000..2e90358
--- /dev/null
+++ b/template/en/default/pages/sudo.html.tmpl
@@ -0,0 +1,55 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% INCLUDE global/header.html.tmpl title = "sudo: User Impersonation" %]
+
+<p>
+ [%+ terms.Bugzilla %] includes the ability to have one user impersonate
+another, in something called a <i>sudo session</i>, so long as the person
+doing the impersonating has the appropriate privileges.
+</p>
+
+<p>
+ While a session is in progress, [% terms.Bugzilla %] will act as if the
+ impersonated user is doing everything. This is especially useful for testing,
+ and for doing critical work when the impersonated user is unavailable. The
+ impersonated user will receive an email from [% terms.Bugzilla %] when the
+ session begins; they will not be told anything else.
+</p>
+
+<p>
+ To use this feature, you must be a member of the appropriate group. The group
+ includes all administrators by default. Other users, and members of other
+ groups, can be given access to this feature on a case-by-case basis. To
+ request access, contact the maintainer of this installation:
+ <a href="mailto:[% Param("maintainer") %]">
+ [%- Param("maintainer") %]</a>.
+</p>
+
+<p>
+ If you would like to be protected from impersonation, you should contact the
+ maintainer of this installation to see if that is possible. People with
+ access to this feature are protected automatically.
+</p>
+
+<p id="message">
+ [% IF user.in_group('bz_sudoers') %]
+ You are a member of the <b>bz_sudoers</b> group. You may use this
+ feature to impersonate others.
+ [% ELSE %]
+ You are not a member of an appropriate group. You may not use this
+ feature.
+ [% END %]
+ [% IF user.in_group('bz_sudo_protect') %]
+ <br>
+ You are a member of the <b>bz_sudo_protect</b> group. Other people will
+ not be able to use this feature to impersonate you.
+ [% END %]
+</p>
+
+[% INCLUDE global/footer.html.tmpl %]
diff --git a/template/en/default/reports/chart.csv.tmpl b/template/en/default/reports/chart.csv.tmpl
new file mode 100644
index 0000000..7293abb
--- /dev/null
+++ b/template/en/default/reports/chart.csv.tmpl
@@ -0,0 +1,32 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% colsepchar = user.settings.csv_colsepchar.value %]
+
+[% data = chart.data %]
+Date\Series
+[% FOREACH label = chart.labels %]
+ [% colsepchar %][% label FILTER csv %]
+[% END %]
+[%# The data, which is in the correct format for GD, is conceptually the wrong
+ # way round for CSV output. So, we need to invert it here, which is why
+ # these loops aren't just plain FOREACH.
+ #%]
+[% i = 0 %]
+[% WHILE i < data.0.size %]
+ [% j = 0 %]
+ [% WHILE j < data.size %]
+ [% IF j > 0 %]
+ [% colsepchar %]
+ [% END %]
+ [% data.$j.$i %]
+ [% j = j + 1 %]
+ [% END %]
+ [% i = i + 1 %]
+
+[% END %]
diff --git a/template/en/default/reports/chart.html.tmpl b/template/en/default/reports/chart.html.tmpl
new file mode 100644
index 0000000..ab33463
--- /dev/null
+++ b/template/en/default/reports/chart.html.tmpl
@@ -0,0 +1,55 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ #%]
+
+[% DEFAULT width = 600
+ height = 350
+%]
+
+[% time = time FILTER time('%Y-%m-%d %H:%M:%S') FILTER html %]
+
+[% PROCESS global/header.html.tmpl
+ title = "Chart"
+ header_addl_info = time
+%]
+
+<div align="center">
+
+ [% imageurl = BLOCK %]chart.cgi?
+ [% imagebase FILTER html %]&amp;ctype=png&amp;action=plot&amp;width=
+ [% width %]&amp;height=[% height -%]
+ [% END %]
+
+ <img alt="Graphical report results" src="[% imageurl %]"
+ width="[% width %]" height="[% height %]">
+ <p>
+ [% sizeurl = BLOCK %]chart.cgi?
+ [% imagebase FILTER html %]&amp;action=wrap
+ [% END %]
+ <a href="[% sizeurl %]&amp;width=[% width %]&amp;height=
+ [% height + 100 %]">Taller</a><br>
+ <a href="[% sizeurl %]&amp;width=[% width - 100 %]&amp;height=
+ [% height %]">Thinner</a> *
+ <a href="[% sizeurl %]&amp;width=[% width + 100 %]&amp;height=
+ [% height %]">Fatter</a>&nbsp;&nbsp;&nbsp;&nbsp;<br>
+ <a href="[% sizeurl %]&amp;width=[% width %]&amp;height=
+ [% height - 100 %]">Shorter</a><br>
+ </p>
+
+ <p>
+ <a href="chart.cgi?
+ [% imagebase FILTER html %]&amp;ctype=csv&amp;action=plot">CSV</a> |
+ <a href="chart.cgi?[% imagebase FILTER html %]&amp;action=assemble">Edit
+ this chart</a>
+ </p>
+
+</div>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/reports/chart.png.tmpl b/template/en/default/reports/chart.png.tmpl
new file mode 100644
index 0000000..a464acc
--- /dev/null
+++ b/template/en/default/reports/chart.png.tmpl
@@ -0,0 +1,47 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% y_label = "$terms.Bugs" %]
+[% x_label = "Time" %]
+
+[% IF chart.cumulate %]
+ [% USE graph = GD.Graph.area(width, height) %]
+ [% graph.set(cumulate => "true") %]
+[% ELSE %]
+ [% USE graph = GD.Graph.lines(width, height) %]
+[% END %]
+
+[% FILTER null;
+ x_label_skip = (30 * chart.data.0.size / width);
+
+ graph.set(x_label => x_label,
+ y_label => y_label,
+ y_tick_number => 8,
+ y_max_value => chart.y_max_value,
+ x_label_position => 0.5,
+ x_labels_vertical => 1,
+ x_label_skip => x_label_skip,
+ legend_placement => "RT",
+ line_width => 2,
+ dclrs => ["lred", "lgreen", "lblue", "lyellow",
+ "lpurple", "lorange", "black", "green",
+ "blue", "dpink", "lbrown", "gray",
+ "red", "dpurple", "gold", "marine"]);
+
+ # Workaround for the fact that set_legend won't take chart.labels directly,
+ # because chart.labels is an array reference rather than an array.
+ graph.set_legend(chart.labels.0, chart.labels.1, chart.labels.2,
+ chart.labels.3, chart.labels.4, chart.labels.5,
+ chart.labels.6, chart.labels.7, chart.labels.8,
+ chart.labels.9, chart.labels.10, chart.labels.11,
+ chart.labels.12, chart.labels.13, chart.labels.14,
+ chart.labels.15);
+
+ graph.plot(chart.data).png | stdout(1);
+ END;
+-%]
diff --git a/template/en/default/reports/components.html.tmpl b/template/en/default/reports/components.html.tmpl
new file mode 100644
index 0000000..2a5d239
--- /dev/null
+++ b/template/en/default/reports/components.html.tmpl
@@ -0,0 +1,94 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # product: object. The product for which we want to display component
+ # descriptions.
+ #%]
+
+[% title = BLOCK %]
+ Components for [% product.name FILTER html %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ style_urls = [ "skins/standard/reports.css" ]
+ title = title
+%]
+
+[% IF Param("useqacontact") %]
+ [% numcols = 3 %]
+[% ELSE %]
+ [% numcols = 2 %]
+[% END %]
+
+<table cellpadding="0" cellspacing="0" id="components_header_table">
+ <tr>
+ <td class="instructions">
+ Select a component to see open [% terms.bugs %] in that component:
+ </td>
+ <td class="product_container">
+ <span class="product_name">[% product.name FILTER html %]</span>
+ <div class="product_desc">
+ [% product.description FILTER html_light %]
+ </div>
+ </td>
+ </tr>
+</table>
+
+<span class="components_header">Components</span>
+
+<table summary="Components table"
+ class="component_table" cellspacing="0" cellpadding="0">
+ <thead>
+ <tr>
+ <th>&nbsp;</th>
+ <th>Default Assignee</th>
+ [% IF Param("useqacontact") %]
+ <th>Default QA Contact</th>
+ [% END %]
+ </tr>
+ </thead>
+
+ <tbody>
+ [% FOREACH comp = product.components %]
+ [% INCLUDE describe_comp %]
+ [% END %]
+ </tbody>
+</table>
+
+[% PROCESS global/footer.html.tmpl %]
+
+[%############################################################################%]
+[%# BLOCK for components %]
+[%############################################################################%]
+
+[% BLOCK describe_comp %]
+ <tr id="[% comp.name FILTER html %]">
+ <td rowspan="2" class="component_name">
+ <a href="buglist.cgi?product=
+ [%- product.name FILTER uri %]&amp;component=
+ [%- comp.name FILTER uri %]&amp;resolution=---">
+ [% comp.name FILTER html %]</a>
+ </td>
+ <td class="component_assignee">
+ [% INCLUDE global/user.html.tmpl who = comp.default_assignee %]
+ </td>
+ [% IF Param("useqacontact") %]
+ <td class="component_qa_contact">
+ [% IF comp.default_qa_contact %]
+ [% INCLUDE global/user.html.tmpl who = comp.default_qa_contact %]
+ [% END %]
+ </td>
+ [% END %]
+ </tr>
+ <tr>
+ <td colspan="[% numcols - 1 %]" class="component_description">
+ [% comp.description FILTER html_light %]
+ </td>
+ </tr>
+[% END %]
diff --git a/template/en/default/reports/create-chart.html.tmpl b/template/en/default/reports/create-chart.html.tmpl
new file mode 100644
index 0000000..471a9cb
--- /dev/null
+++ b/template/en/default/reports/create-chart.html.tmpl
@@ -0,0 +1,258 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # chart: Chart object representing the currently assembled chart.
+ # category: hash (keyed by category) of hashes (keyed by subcategory) of
+ # hashes (keyed by name), with value being the series_id of the
+ # series. Contains details of all series the user can see.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Create Chart"
+%]
+
+[% PROCESS "reports/series-common.html.tmpl"
+ donames = 1
+%]
+
+<script type="text/javascript">
+[%# This function takes necessary action on selection of a subcategory %]
+function subcatSelected() {
+ var cat = document.chartform.category.value;
+ var subcat = document.chartform.subcategory.value;
+ var names = series[cat][subcat];
+
+ var namewidget = document.chartform.name;
+
+ namewidget.options.length = 0;
+ var i = 0;
+
+ for (x in names) {
+ namewidget.options[i] = new Option(x, names[x]);
+ i++;
+ }
+
+ namewidget.disabled = false;
+ namewidget.options[0].selected = true;
+
+ checkNewState();
+}
+</script>
+
+[% gttext = "Grand Total" %]
+
+<form method="get" action="chart.cgi" name="chartform">
+
+ <table cellpadding="2" cellspacing="2" border="0">
+ [% IF NOT category OR category.size == 0 %]
+ <tr>
+ <td>
+ <i>No data sets exist, or none are visible to you.</i>
+ </td>
+ </tr>
+ [% ELSE %]
+ <tr>
+ <th><label for="category">Category</label>:</th>
+ <th></th>
+ <th><label for="subcategory">Sub-category</label>:</th>
+ <th></th>
+ <th><label for="name" accesskey="N">Name</label>:</th>
+ <th><br>
+ </th>
+ </tr>
+ <tr>
+
+ [% PROCESS series_select sel = { name => 'category',
+ size => 5,
+ onchange = "catSelected();
+ subcatSelected();" } %]
+
+ <td>
+ <noscript>
+ <input type="submit" name="action-assemble" value="Update --&gt;"
+ id="action-assemble">
+ </noscript>
+ </td>
+
+ [% PROCESS series_select sel = { name => 'subcategory',
+ size => 5,
+ onchange = "subcatSelected()" } %]
+
+ <td>
+ <noscript>
+ <input type="submit" name="action-assemble" value="Update --&gt;"
+ id="action-assemble2">
+ </noscript>
+ </td>
+
+ [% PROCESS series_select sel = { name => 'name',
+ size => 5,
+ multiple => 1,
+ # We want to use the series ID as value,
+ # not its name.
+ value_in_hash => 1 } %]
+
+ <td align="center" valign="middle">
+ <input type="submit" name="action-add" value="Add To List"
+ id="action-add"><br>
+ </td>
+ </tr>
+ [% END %]
+ </table>
+
+ <h3>List Of Data Sets To Plot</h3>
+
+ [% IF chart.lines.size %]
+ <table cellspacing="2" cellpadding="2">
+ <tr>
+ <th style="width: 5em;">Select</th>
+ <th>Label</th>
+ <th></th>
+ <th>Data Set</th>
+ <th></th>
+ </tr>
+
+ [%# The external loop has two counters; one which keeps track of where we
+ # are in the old labels array, and one which keeps track of the new
+ # indexes for the form elements. They are different if chart.lines has
+ # empty slots in it.
+ #%]
+ [% labelidx = 0 %]
+ [% newidx = 0 %]
+
+ [% FOREACH line = chart.lines %]
+ [% IF NOT line %]
+ [%# chart.lines has an empty slot, so chart.labels will too. We
+ # increment labelidx only to keep the labels in sync with the data.
+ #%]
+ [% labelidx = labelidx + 1 %]
+ [% NEXT %]
+ [% END %]
+
+ [% FOREACH series = line %]
+ <tr>
+ [% IF loop.first %]
+ <td align="center" rowspan="[% line.size %]">
+ <input type="checkbox" value="1" name="select[% newidx %]">
+ </td>
+ <td rowspan="[% line.size %]">
+ <input type="text" size="20" name="label[% newidx %]"
+ value="[% (chart.labels.$labelidx OR series.name)
+ FILTER html %]">
+ </td>
+ [% END %]
+
+ <td>
+ [% "{" IF line.size > 1 %]
+ </td>
+
+ <td>
+ [% series.category FILTER html %] /
+ [%+ series.subcategory FILTER html %] /
+ [%+ series.name FILTER html %]
+ <input type="hidden" name="line[% newidx %]"
+ value="[% series.series_id %]">
+ </td>
+
+ <td align="center">
+ [% IF user.id == series.creator_id OR user.in_group("admin") %]
+ <a href="chart.cgi?action=edit&amp;series_id=
+ [% series.series_id %]">Edit</a> |
+ <a href="chart.cgi?action=confirm-delete&amp;series_id=
+ [%- series.series_id %]">Delete</a> |
+ [% END %]
+ <a href="buglist.cgi?cmdtype=dorem&amp;namedcmd=
+ [% series.category FILTER uri %]%20/%20
+ [% series.subcategory FILTER uri %]%20/%20
+ [% series.name FILTER uri -%]&amp;series_id=
+ [% series.series_id %]&amp;remaction=runseries">Run Search</a>
+ </td>
+ </tr>
+ [% END %]
+ [% labelidx = labelidx + 1 %]
+ [% newidx = newidx + 1 %]
+ [% END %]
+
+ [% IF chart.gt %]
+ <tr>
+ <td align="center">
+ <input type="checkbox" value="1" name="select65536">
+ <input type="hidden" value="1" name="gt">
+ </td>
+ <td>
+ <input type="text" size="20" name="labelgt"
+ value="[% (chart.labelgt OR gttext) FILTER html %]">
+ </td>
+ <td></td>
+ <td>
+ <i>[% gttext FILTER html %]</i>
+ </td>
+ <td></td>
+ </tr>
+ [% END %]
+ <tr>
+ <td colspan="6">&nbsp;</td>
+ </tr>
+
+ <tr>
+ <td valign="bottom" style="text-align: center;">
+ <input type="submit" name="action-sum" value="Sum"
+ style="width: 5em;" id="action-sum"><br>
+ <input type="submit" name="action-remove" value="Remove"
+ style="width: 5em;" id="action-remove">
+ </td>
+
+ <td style="text-align: right; vertical-align: bottom;">
+ <label for="cumulate"><b>Cumulate</b></label>:
+ <input type="checkbox" name="cumulate" id="cumulate" value="1"
+ [% " checked" IF chart.cumulate %]>
+ </td>
+
+ <td></td>
+ <td valign="bottom">
+ <label for="datefrom"><b>Date Range</b></label>:
+ <input type="text" size="12" name="datefrom" id="datefrom"
+ value="[% time2str("%Y-%m-%d", chart.datefrom) IF chart.datefrom%]">
+ <label for="dateto"><b>to</b></label>
+ <input type="text" size="12" name="dateto" id="dateto"
+ value="[% time2str("%Y-%m-%d", chart.dateto) IF chart.dateto %]">
+ </td>
+
+ <td style="text-align: right" valign="bottom">
+ <input type="submit" name="action-wrap" value="Chart This List"
+ id="action-wrap">
+ </td>
+ </tr>
+ </table>
+ [% ELSE %]
+ <p><i>None</i></p>
+ [% END %]
+</form>
+
+[% IF user.in_group('editbugs') %]
+ <h3>Create New Data Set</h3>
+ <p>
+ You can either create a new data set based on one of your saved searches
+ or start with a clean slate.
+ </p>
+
+ <form action="chart.cgi" id="create_series" name="create_series" method="GET">
+ <input type="hidden" name="action" value="convert_search">
+ <label for="series_from_search">Based on:</label>
+ <select id="series_from_search" name="series_from_search">
+ <option value="">(Clean slate)</option>
+ [% FOREACH q = user.queries %]
+ <option value="[% q.name FILTER html %]">[% q.name FILTER html %]</option>
+ [% END %]
+ </select>
+ <input id="submit_create" type="submit" value="Create a new data set">
+ </form>
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/reports/delete-series.html.tmpl b/template/en/default/reports/delete-series.html.tmpl
new file mode 100644
index 0000000..7ff8876
--- /dev/null
+++ b/template/en/default/reports/delete-series.html.tmpl
@@ -0,0 +1,47 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% series_name = BLOCK %]
+ [% series.category FILTER html %] /
+ [%+ series.subcategory FILTER html %] /
+ [%+ series.name FILTER html %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl title = "Delete Series"
+ style_urls = ['skins/standard/admin.css'] %]
+
+<p>
+ You are going to completely remove the <b>[% series_name FILTER none %]</b> series
+ from the database. All data related to this series will be permanently deleted.
+</p>
+<p>
+ [% IF series.creator %]
+ This series has been created by <a href="mailto:[% series.creator.email FILTER html %]">
+ [% series.creator.email FILTER html %]</a>
+ [% ELSE %]
+ This series has been automatically created by [% terms.Bugzilla %]
+ [% END %]
+
+ [% IF series.public %]
+ and is public.
+ [% ELSIF series.creator %]
+ and is only visible by this user.
+ [% ELSE %]
+ and cannot be displayed by anybody.
+ [% END %]
+</p>
+
+<p class="areyoureallyreallysure">Are you sure you want to delete this series?</p>
+
+<p>
+ <a href="chart.cgi?action=delete&amp;series_id=[% series.series_id FILTER html %]&amp;token=
+ [%- issue_hash_token([series.id, series.name]) FILTER uri %]">Yes, delete</a> |
+ <a href="chart.cgi">No, go back to the charts page</a>
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/reports/duplicates-simple.html.tmpl b/template/en/default/reports/duplicates-simple.html.tmpl
new file mode 100644
index 0000000..6f58654
--- /dev/null
+++ b/template/en/default/reports/duplicates-simple.html.tmpl
@@ -0,0 +1,35 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # You need to fulfill the interface to duplicates-table.html.tmpl.
+ #%]
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+ [% IF product.size %]
+ [% title = BLOCK %]
+ Most Frequently Reported [% terms.Bugs %] for [% product.join(', ') FILTER html %]
+ [% END %]
+ [% ELSE %]
+ [% title = "Most Frequently Reported $terms.Bugs" %]
+ [% END%]
+
+ <head>
+ <title>[% title FILTER html %]</title>
+ <link href="[% 'skins/standard/global.css' FILTER mtime %]"
+ rel="stylesheet" type="text/css">
+ <link href="[% 'skins/standard/duplicates.css' FILTER mtime %]"
+ rel="stylesheet" type="text/css">
+ </head>
+
+ <body>
+ [% PROCESS "reports/duplicates-table.html.tmpl" %]
+ </body>
+</html>
diff --git a/template/en/default/reports/duplicates-table.html.tmpl b/template/en/default/reports/duplicates-table.html.tmpl
new file mode 100644
index 0000000..45cf8c3
--- /dev/null
+++ b/template/en/default/reports/duplicates-table.html.tmpl
@@ -0,0 +1,109 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # bugs: list of hashes. May be empty. Each hash has three members:
+ # bug: A Bugzilla::Bug object
+ # count: integer. The number of dupes
+ # delta: integer. The change in count in the last $changedsince days
+ #
+ # bug_ids: list of integers. May be empty. The IDs of the bugs in $bugs.
+ #
+ # sortby: string. the column on which we are sorting the buglist.
+ # reverse: boolean. True if we are reversing the current sort.
+ # maxrows: integer. Max number of rows to display.
+ # changedsince: integer. The number of days ago for the changedsince column.
+ # openonly: boolean. True if we are only showing open bugs.
+ # product: array of strings. Restrict to these products only.
+ #%]
+
+[%# *** Column Headers *** %]
+
+[% SET columns = [
+ { name => "id", description => "$terms.Bug #" },
+ { name => "count", description => "Dupe<br>Count" },
+ { name => "delta",
+ description => "Change in last<br>$changedsince day(s)" },
+ { name => "component", description => field_descs.component },
+ { name => "bug_severity", description => field_descs.bug_severity },
+ { name => "op_sys", description => field_descs.op_sys },
+ { name => "target_milestone", description => field_descs.target_milestone },
+ { name => "short_desc", description => field_descs.short_desc },
+] %]
+
+[% SET base_args = [] %]
+[% FOREACH param = ['maxrows', 'openonly', 'format', 'sortvisible',
+ 'changedsince', 'product']
+%]
+ [% NEXT IF NOT ${param}.defined %]
+ [% FOREACH value = ${param} %]
+ [% filtered_value = value FILTER uri %]
+ [% base_args.push("$param=$filtered_value") %]
+ [% END %]
+[% END %]
+[% IF sortvisible %]
+ [% bug_ids_string = bug_ids.nsort.join(',') FILTER uri %]
+ [% base_args.push("bug_id=$bug_ids_string") %]
+[% END %]
+[% base_args_string = base_args.join('&amp;') %]
+
+[% IF bugs.size %]
+ <table id="duplicates_table" cellpadding="0" cellspacing="0">
+ <thead>
+ <tr>
+ [% FOREACH column = columns %]
+ [% IF column.name == sortby %]
+ [%# We add this to the column object so it doesn't affect future
+ # iterations of the loop.
+ #%]
+ [% column.reverse_sort = reverse ? 0 : 1 %]
+ [% END %]
+ <th class="[% column.name FILTER html %]">
+ <a href="duplicates.cgi?sortby=[% column.name FILTER uri %]
+ [% IF column.reverse_sort.defined %]
+ [%- %]&amp;reverse=[% column.reverse_sort FILTER uri %]
+ [% END %]
+ [% IF base_args_string %]
+ [% "&amp;$base_args_string" FILTER none %]
+ [% END %]"
+ >[% column.description FILTER none %]</a>
+ </th>
+ [% END %]
+ </tr>
+ </thead>
+
+ [%# *** Buglist *** %]
+
+ <tbody>
+ [% FOREACH item = bugs %]
+ [% SET bug = item.bug %]
+ <tr [% " class='resolved'" IF NOT bug.isopened %]>
+ <td class="id">
+ [% bug.id FILTER bug_link(bug) FILTER none %]
+ </td>
+ <td class="count">[% item.count FILTER html %]</td>
+ <td class="delta">[% item.delta FILTER html %]</td>
+ <td class="component">[% bug.component FILTER html %]</td>
+ <td class="bug_severity">
+ [%- display_value('bug_severity', bug.bug_severity) FILTER html %]
+ </td>
+ <td class="op_sys">
+ [%- display_value('op_sys', bug.op_sys) FILTER html %]
+ </td>
+ <td class="target_milestone">
+ [% display_value('target_milestone',
+ bug.target_milestone) FILTER html %]
+ </td>
+ <td class="short_desc">[% bug.short_desc FILTER html %]</td>
+ </tr>
+ [% END %]
+ </tbody>
+ </table>
+[% ELSE %]
+ <h3>No duplicate [% terms.bugs %] found.</h3>
+[% END %]
diff --git a/template/en/default/reports/duplicates.html.tmpl b/template/en/default/reports/duplicates.html.tmpl
new file mode 100644
index 0000000..4efdcf9
--- /dev/null
+++ b/template/en/default/reports/duplicates.html.tmpl
@@ -0,0 +1,165 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # sortby: string. the column on which we are sorting the buglist.
+ # reverse: boolean. True if we are reversing the current sort.
+ # maxrows: integer. Max number of rows to display.
+ # changedsince: integer. The number of days ago for the changedsince column.
+ # openonly: boolean. True if we are only showing open bugs.
+ # product: array of strings. The set of products we check for dups.
+ #
+ # Additionally, you need to fulfill the interface to
+ # duplicates-table.html.tmpl.
+ #%]
+
+[% IF product.size %]
+ [% title = BLOCK %]
+ Most Frequently Reported [% terms.Bugs %] for
+ [%+ product.join(', ') FILTER html %]
+ [% END %]
+[% ELSE %]
+ [% title = "Most Frequently Reported $terms.Bugs" %]
+[% END%]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/duplicates.css']
+%]
+
+<p>
+ <a href="#explanation">What is this data?</a>
+ <br>
+ <a href="#params">Change parameters</a>
+</p>
+
+[% PROCESS "reports/duplicates-table.html.tmpl" %]
+
+[%# *** Parameters *** %]
+
+[% bug_ids_string = bug_ids.join(',') %]
+
+<h3 id="params">Change Parameters</h3>
+
+<form method="get" action="duplicates.cgi">
+ <input type="hidden" name="sortby" value="[% sortby FILTER html %]">
+ <input type="hidden" name="reverse" value="[% reverse FILTER html %]">
+ <input type="hidden" name="bug_id" value="[% bug_ids_string FILTER html %]">
+ <table>
+ <tr>
+ <td>When sorting or restricting, work with:</td>
+ <td>
+ <input type="radio" name="sortvisible" id="entirelist" value="0"
+ [% ' checked="checked"' IF NOT sortvisible %]>
+ <label for="entirelist">
+ entire list
+ </label>
+ <br>
+ <input type="radio" name="sortvisible" id="visiblelist" value="1"
+ [% ' checked="checked"' IF sortvisible %]>
+ <label for="visiblelist">
+ currently visible list
+ </label>
+ </td>
+ <td rowspan="4" valign="top">Restrict to products:</td>
+ <td rowspan="4" valign="top">
+ <select name="product" size="5" multiple="multiple">
+ [% FOREACH p = user.get_selectable_products %]
+ <option name="[% p.name FILTER html %]"
+ [% ' selected="selected"' IF product.contains(p.name) %]
+ >[% p.name FILTER html %]</option>
+ [% END %]
+ </select>
+ </td>
+ </tr>
+
+ <tr>
+ <td><label for="maxrows">Max rows:</label></td>
+ <td>
+ <input size="4" name="maxrows" id="maxrows"
+ value="[% maxrows FILTER html %]">
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <label for="changedsince">Change column is change in the last:</label>
+ </td>
+ <td>
+ <input size="4" name="changedsince" id="changedsince"
+ value="[% changedsince FILTER html %]"> days
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <label for="openonly">
+ Open [% terms.bugs %] only:
+ </label>
+ </td>
+ <td>
+ <input type="checkbox" name="openonly" id="openonly" value="1"
+ [% ' checked="checked"' IF openonly %]>
+ </td>
+ </tr>
+
+ </table>
+
+ <input type="submit" id="change" value="Change">
+</form>
+
+<form method="post" action="buglist.cgi">
+ <input type="hidden" name="bug_id" value="[% bug_ids_string FILTER html %]">
+ Or just give this to me as a <input type="submit" id="list"
+ value="[% terms.bug %] list">.
+ (Note: the order may not be the same.)
+</form>
+
+<hr>
+
+<h3 id="explanation">
+ What are "Most Frequently Reported [% terms.Bugs %]"?
+</h3>
+
+<p>
+ The Most Frequent [% terms.Bugs %] page lists the known open
+ [%+ terms.bugs %] which are reported most frequently,
+ counting the number of direct and indirect duplicates of [% terms.bugs %].
+ This information is provided in order to assist in minimizing
+ the amount of duplicate [% terms.bugs %] entered into [% terms.Bugzilla %],
+ which saves time for Quality Assurance engineers who have to triage
+ the [% terms.bugs %].
+</p>
+
+<b>How do I use this list?</b>
+
+<ul>
+ <li>Review the most frequent [% terms.bugs %] list.</li>
+ <li>If your problem is listed:</li>
+
+ <ul>
+ <li>Click on the [% terms.bug %] number to confirm that you have found the
+ same [% terms.bug %], and comment if you have additional information
+ or move on with your testing of the product.
+ </li>
+ </ul>
+
+ <li>If your problem not listed:</li>
+
+ <ul>
+ <li><a href="query.cgi">Try and locate a similar [% terms.bug %]</a>
+ that has already been filed.</li>
+ <li>If you find your [% terms.bug %] in [% terms.Bugzilla %],
+ feel free to comment with any new or additional data you may have.</li>
+ <li>If you cannot find your problem already documented in
+ [%+ terms.Bugzilla %],
+ <a href="enter_bug.cgi">file a new [% terms.bug %]</a>.</li>
+ </ul>
+</ul>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/reports/edit-series.html.tmpl b/template/en/default/reports/edit-series.html.tmpl
new file mode 100644
index 0000000..c789262
--- /dev/null
+++ b/template/en/default/reports/edit-series.html.tmpl
@@ -0,0 +1,63 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% title = "Edit Series" %]
+[% subheader = BLOCK %]
+ [% default.category FILTER html %] /
+ [%+ default.subcategory FILTER html %] /
+ [%+ default.name FILTER html %]
+[% END %]
+
+[% PROCESS global/header.html.tmpl %]
+
+[% IF changes_saved %]
+ <p>
+ <font color="red">
+ Series updated.
+ </font>
+ </p>
+[% END %]
+
+<form method="get" action="chart.cgi" name="chartform">
+
+ [% PROCESS reports/series.html.tmpl
+ button_name = "Change Data Set" %]
+ <input type="hidden" name="action" value="alter">
+ <input type="hidden" name="token"
+ value="[% issue_hash_token([default.id, default.name]) FILTER html %]">
+
+ [% IF default.series_id %]
+ <input type="hidden" name="series_id" value="[% default.series_id %]">
+ [% END %]
+</form>
+
+<p>
+ <b>Creator</b>:
+ [% IF default.creator %]
+ <a href="mailto:[% default.creator.email FILTER html %]">
+ [% default.creator.email FILTER html %]</a>
+ [% ELSE %]
+ (automatically created by [% terms.Bugzilla %])
+ [% END %]
+</p>
+
+<p>Note: it is not yet possible to edit the search associated with this data
+set.
+</p>
+
+<p>
+ <a href="query.cgi?[% default.query FILTER html %]">View
+ series search parameters</a> |
+ <a href="buglist.cgi?cmdtype=dorem&amp;namedcmd=
+ [% default.category FILTER uri %]-
+ [% default.subcategory FILTER uri %]-
+ [% default.name FILTER uri %]&amp;remaction=runseries&amp;series_id=
+ [% default.series_id %]">Run series search</a>
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/reports/keywords.html.tmpl b/template/en/default/reports/keywords.html.tmpl
new file mode 100644
index 0000000..0624041
--- /dev/null
+++ b/template/en/default/reports/keywords.html.tmpl
@@ -0,0 +1,71 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # keywords: array keyword objects. May be empty. Each has has four members:
+ # id: id of the keyword
+ # name: the name of the keyword
+ # description: keyword description. Can contain some limited HTML code.
+ # bug_count: number of bugs with that keyword
+ # caneditkeywords: boolean. True if this user can edit keywords
+ %]
+
+[% PROCESS global/header.html.tmpl
+ title = "$terms.Bugzilla Keyword Descriptions"
+%]
+
+[% FOREACH keyword = keywords %]
+ [% IF loop.index % 50 == 0 %]
+ [% IF loop.index != 0 %]
+ </table>
+ [% END %]
+
+ <table border="1" cellpadding="4" cellspacing="0">
+ <tr bgcolor="#6666FF">
+ <th align="left">Name</th>
+ <th align="left">Description</th>
+ <th align="left">Open [% terms.Bugs %]</th>
+ <th align="left">Total [% terms.Bugs %]</th>
+ </tr>
+ [% END %]
+
+ <tr id="[% keyword.name FILTER html %]">
+ <th>
+ [% keyword.name FILTER html %]
+ </th>
+ <td>[% keyword.description FILTER html_light %]</td>
+ <td align="center">
+ [% IF keyword.bug_count > 0 %]
+ <a href="buglist.cgi?keywords=[% keyword.name FILTER uri %]&amp;resolution=---">
+ Search</a>
+ [% ELSE %]
+ none
+ [% END %]
+ </td>
+ <td align="right">
+ [% IF keyword.bug_count > 0 %]
+ <a href="buglist.cgi?keywords=[% keyword.name FILTER uri %]">
+ [% keyword.bug_count %]</a>
+ [% ELSE %]
+ none
+ [% END %]
+ </td>
+ </tr>
+[% END %]
+
+[% IF keywords.size > 0 %]
+ </table>
+[% END %]
+
+[% IF caneditkeywords %]
+ <p>
+ <a href="editkeywords.cgi">Edit keywords</a>.
+ </p>
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/reports/menu.html.tmpl b/template/en/default/reports/menu.html.tmpl
new file mode 100644
index 0000000..af83ffb
--- /dev/null
+++ b/template/en/default/reports/menu.html.tmpl
@@ -0,0 +1,75 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # This template has no interface. It's a list of the available report
+ # types in Bugzilla.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Reporting and Charting Kitchen"
+ doc_section = "reporting.html"
+ style_urls = ['skins/standard/reports.css']
+%]
+
+<p>
+ [% terms.Bugzilla %] allows you to view and track the state of the [% terms.bug %] database in
+ all manner of exciting ways.
+</p>
+
+<h2>Current State</h2>
+
+<ul>
+ <li id="report_search">
+ <strong><a href="query.cgi">Search</a></strong> -
+ list sets of [% terms.bugs %].
+ </li>
+ <li id="report_tabular">
+ <strong>
+ <a href="query.cgi?format=report-table">Tabular reports</a>
+ </strong> -
+ tables of [% terms.bug %] counts in 1, 2 or 3 dimensions, as HTML or CSV.
+ </li>
+ [% IF feature_enabled('graphical_reports') %]
+ <li id="report_graphical">
+ <strong>
+ <a href="query.cgi?format=report-graph">Graphical reports</a>
+ </strong> -
+ line graphs, bar and pie charts.
+ </li>
+ [% END %]
+ <li id="report_duplicates">
+ <strong><a href="duplicates.cgi">Duplicates</a></strong> -
+ list of most frequently reported [% terms.bugs %].
+ </li>
+ [% Hook.process('current_state') %]
+</ul>
+
+[% IF feature_enabled('new_charts') OR feature_enabled('old_charts') %]
+ <h2>Change Over Time</h2>
+
+ <ul>
+ [% IF feature_enabled('old_charts') %]
+ <li id="old_charts">
+ <strong><a href="reports.cgi">Old Charts</a></strong> -
+ plot the status and/or resolution of [% terms.bugs %] against
+ time, for each product in your database.
+ </li>
+ [% END %]
+ [% IF feature_enabled('new_charts') AND user.in_group(Param("chartgroup")) %]
+ <li id="new_charts">
+ <strong><a href="chart.cgi">New Charts</a></strong> -
+ plot any arbitrary search against time. Far more powerful.
+ </li>
+ [% END %]
+ </ul>
+[% END %]
+
+[% Hook.process('end') %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/reports/old-charts.html.tmpl b/template/en/default/reports/old-charts.html.tmpl
new file mode 100644
index 0000000..12a0cdd
--- /dev/null
+++ b/template/en/default/reports/old-charts.html.tmpl
@@ -0,0 +1,62 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # products: an array of product names the user is allowed to view.
+ # datasets: an array of hashes with available statuses and resolutions.
+ # url_image: URL of the generated graph.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "$terms.Bug Charts"
+ h1 = "Welcome to the $terms.Bugzilla Charting Kitchen"
+ doc_section = "reporting.html#charts"
+%]
+
+<div align="center">
+ [% IF url_image %]
+ <img src="[% url_image FILTER html %]">
+ <br clear="both">
+ [% ELSE %]
+ <form id="choose_product" method="get" action="reports.cgi">
+ <table border="1" cellpadding="5" cellspacing="2">
+ <tr>
+ <th>Product:</th>
+ <td align="center">
+ <select id="product" name="product">
+ [% FOREACH product = products %]
+ <option value="[% product FILTER html %]">[% product FILTER html %]</option>
+ [% END %]
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <th>Chart datasets:</th>
+ <td align="center">
+ <select id="datasets" name="datasets" multiple="multiple" size="5">
+ [%# We cannot use translated statuses and resolutions from field-descs.none.html
+ # because old charts do not distinguish statuses from resolutions. %]
+ [% FOREACH dataset = datasets %]
+ <option value="[% dataset.value FILTER html %]"
+ [% " selected=\"selected\"" IF dataset.selected %]>
+ [% dataset.value FILTER html %]</option>
+ [% END %]
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <th colspan="2">
+ <input type="submit" id="submit" value="Continue">
+ </th>
+ </tr>
+ </table>
+ </form>
+ [% END %]
+</div>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/reports/report-bar.png.tmpl b/template/en/default/reports/report-bar.png.tmpl
new file mode 100644
index 0000000..70d482e
--- /dev/null
+++ b/template/en/default/reports/report-bar.png.tmpl
@@ -0,0 +1,48 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% y_label = "$terms.Bugs" %]
+
+[% col_field_disp = field_descs.$col_field || col_field %]
+
+[% FOR i IN [ 0 .. data.0.0.max ] %]
+ [% data.0.0.$i = display_value(col_field, data.0.0.$i) %]
+[% END %]
+
+[% FOR i IN [ 0 .. row_names.max ] %]
+ [% row_names.$i = display_value(row_field, row_names.$i) %]
+[% END %]
+
+[% FILTER null;
+ USE graph = GD.Graph.bars(width, height);
+
+ graph.set(x_label => col_field_disp,
+ y_label => y_label,
+ y_tick_number => 8,
+ y_number_format => "%d",
+ x_label_position => 0.5,
+ x_labels_vertical => x_labels_vertical,
+ bar_spacing => 8,
+ shadow_depth => 4,
+ shadowclr => 'dred',
+ show_values => 1,
+ legend_placement => "RT");
+
+ graph.set(cumulate => "true",
+ show_values => 0) IF cumulate;
+
+ # Workaround for the fact that set_legend won't take row_names directly,
+ # because row_names is an array reference rather than an array.
+ graph.set_legend(row_names.0, row_names.1, row_names.2, row_names.3,
+ row_names.4, row_names.5, row_names.6, row_names.7,
+ row_names.8, row_names.9, row_names.10, row_names.11,
+ row_names.12, row_names.13, row_names.14, row_names.15);
+
+ graph.plot(data.0).png | stdout(1);
+ END;
+-%]
diff --git a/template/en/default/reports/report-line.png.tmpl b/template/en/default/reports/report-line.png.tmpl
new file mode 100644
index 0000000..073e69b
--- /dev/null
+++ b/template/en/default/reports/report-line.png.tmpl
@@ -0,0 +1,50 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% y_label = "$terms.Bugs" %]
+
+[% col_field_disp = field_descs.$col_field || col_field %]
+
+[% FOR i IN [ 0 .. data.0.0.max ] %]
+ [% data.0.0.$i = display_value(col_field, data.0.0.$i) %]
+[% END %]
+
+[% FOR i IN [ 0 .. row_names.max ] %]
+ [% row_names.$i = display_value(row_field, row_names.$i) %]
+[% END %]
+
+[% IF cumulate %]
+ [% USE graph = GD.Graph.area(width, height) %]
+ [% graph.set(cumulate => "true") %]
+[% ELSE %]
+ [% USE graph = GD.Graph.lines(width, height) %]
+[% END %]
+
+[% FILTER null;
+ graph.set(x_label => col_field_disp,
+ y_label => y_label,
+ y_tick_number => 8,
+ x_label_position => 0.5,
+ x_labels_vertical => x_labels_vertical,
+ legend_placement => "RT",
+ line_width => 2,
+ dclrs => ["lred", "lgreen", "lblue", "lyellow",
+ "lpurple", "lorange", "black", "green",
+ "blue", "dpink", "lbrown", "gray",
+ "red", "dpurple", "gold", "marine"]);
+
+ # Workaround for the fact that set_legend won't take row_names directly,
+ # because row_names is an array reference rather than an array.
+ graph.set_legend(row_names.0, row_names.1, row_names.2, row_names.3,
+ row_names.4, row_names.5, row_names.6, row_names.7,
+ row_names.8, row_names.9, row_names.10, row_names.11,
+ row_names.12, row_names.13, row_names.14, row_names.15);
+
+ graph.plot(data.0).png | stdout(1);
+ END;
+-%]
diff --git a/template/en/default/reports/report-pie.png.tmpl b/template/en/default/reports/report-pie.png.tmpl
new file mode 100644
index 0000000..9d3f16f
--- /dev/null
+++ b/template/en/default/reports/report-pie.png.tmpl
@@ -0,0 +1,25 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% col_field_disp = field_descs.$col_field || col_field %]
+
+[% FOR i IN [ 0 .. data.0.0.max ] %]
+ [% data.0.0.$i = display_value(col_field, data.0.0.$i) %]
+[% END %]
+
+[% FILTER null;
+ USE graph = GD.Graph.pie(width, height);
+
+ graph.set(title => col_field_disp,
+ pie_height => 20,
+ suppress_angle => 2,
+ start_angle => 180);
+
+ graph.plot(data.0).png | stdout(1);
+ END;
+-%]
diff --git a/template/en/default/reports/report-simple.html.tmpl b/template/en/default/reports/report-simple.html.tmpl
new file mode 100644
index 0000000..17b87c6
--- /dev/null
+++ b/template/en/default/reports/report-simple.html.tmpl
@@ -0,0 +1,25 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # You need to fulfill the interface to report-table.html.tmpl.
+ #%]
+
+<html>
+
+ [% title = "$terms.Bug List" %]
+
+ <head>
+ <title>[% title FILTER html %]</title>
+ </head>
+
+ <body>
+ [% PROCESS "reports/report-table.html.tmpl" %]
+ </body>
+
+</html>
diff --git a/template/en/default/reports/report-table.csv.tmpl b/template/en/default/reports/report-table.csv.tmpl
new file mode 100644
index 0000000..e2a92b5
--- /dev/null
+++ b/template/en/default/reports/report-table.csv.tmpl
@@ -0,0 +1,61 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% colsepchar = user.settings.csv_colsepchar.value %]
+
+[% num_bugs = BLOCK %]Number of [% terms.bugs %][% END %]
+[% tbl_field_disp = field_descs.$tbl_field || tbl_field %]
+[% col_field_disp = field_descs.$col_field || col_field %]
+[% row_field_disp = field_descs.$row_field || row_field %]
+
+[% IF tbl_field %]
+ [% IF tbl_field == 'assigned_to' OR tbl_field == 'reporter'
+ OR tbl_field == 'qa_contact'
+ %]
+ [% tbl_disp = tbl FILTER email %]
+ [% ELSE %]
+ [% tbl_disp = tbl %]
+ [% END %]
+ [% tbl_field_disp FILTER csv %]: [% tbl_disp FILTER csv %]
+[% END %]
+[% IF row_field %]
+ [% row_field_disp FILTER csv %]
+[% END %]
+[% " / " IF col_field AND row_field %]
+[% col_field_disp FILTER csv %]
+[% IF col_field -%]
+ [% FOREACH col = col_names -%]
+ [% colsepchar %]
+ [% PROCESS value_display value = col field = col_field %]
+ [% END -%]
+[% ELSE -%]
+ [% colsepchar %][% num_bugs FILTER csv %]
+[% END %]
+
+[% FOREACH row = row_names %]
+ [% PROCESS value_display value = row field = row_field %]
+ [% FOREACH col = col_names %]
+ [% colsepchar %]
+ [% IF data.$tbl AND data.$tbl.$col AND data.$tbl.$col.$row %]
+ [% data.$tbl.$col.$row -%]
+ [% ELSE %]
+ [% -%]0
+ [% END %]
+ [% END %]
+
+[% END %]
+
+[% BLOCK value_display %]
+ [% SET disp_value = display_value(field, value) %]
+ [% IF field == 'assigned_to' OR field == 'reporter'
+ OR field == 'qa_contact'
+ %]
+ [% disp_value = value FILTER email %]
+ [% END %]
+ [% disp_value FILTER csv %]
+[% END %]
diff --git a/template/en/default/reports/report-table.html.tmpl b/template/en/default/reports/report-table.html.tmpl
new file mode 100644
index 0000000..2747166
--- /dev/null
+++ b/template/en/default/reports/report-table.html.tmpl
@@ -0,0 +1,256 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # buglistbase: The base query for this table, in URL form
+ # col_field: string. Name of the field being plotted as columns.
+ # row_field: string. Name of the field being plotted as rows.
+ # tbl_field: string. Name of the field being plotted as tables.
+ # col_names: array. List of values for the field being plotted as columns.
+ # row_names: array. List of values for the field being plotted as rows.
+ # data: <depends on format>. Data to plot. Only data.$tbl is accessed.
+ # tbl: Name of a hash in data which is the table to be plotted.
+ #%]
+
+[% col_field_disp = field_descs.$col_field || col_field %]
+[% row_field_disp = field_descs.$row_field || row_field %]
+
+[% urlbase = BLOCK %]buglist.cgi?[% buglistbase FILTER html %][% END %]
+[% IF tbl == "-total-" %]
+ [% IF tbl_vals %]
+ [% urlbase = urlbase _ "&amp;" _ tbl_vals %]
+ [% END %]
+[% ELSIF tbl_field %]
+ [% urlbase = BLOCK %][% urlbase %]&amp;[% tbl_field FILTER uri %]=[% tbl FILTER uri %][% END %]
+[% END %]
+
+<script type="text/javascript">
+function bz_encode (str, decode) {
+ // First decode HTML entities, if requested.
+ if (decode)
+ str = str.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"')
+ .replace(/&nbsp;/g, " ").replace(/&amp;/g, "&").replace(/\s+$/,"");
+
+ // encodeURIComponent() doesn't escape single quotes.
+ return encodeURIComponent(str).replace(/'/g, escape);
+};
+
+YAHOO.util.Event.addListener(window, "load", function() {
+ this.Linkify = function(elLiner, oRecord, oColumn, oData) {
+ if (oData == 0)
+ elLiner.innerHTML = ".";
+ else if (oRecord.getData("row_title") == "Total")
+ elLiner.innerHTML = '<a href="[% urlbase FILTER js %]&amp;[% col_field FILTER uri FILTER js %]='
+ + bz_encode(oColumn.field)
+ + '[% "&amp;" _ row_vals IF row_vals %]">' + oData + '</a>';
+ else
+ elLiner.innerHTML = '<a href="[% urlbase FILTER js %]&amp;[% row_field FILTER uri FILTER js %]='
+ + bz_encode(oRecord.getData("row_title"), 1)
+ + '&amp;[% col_field FILTER uri FILTER js %]='
+ + bz_encode(oColumn.field) + '">' + oData + '</a>';
+ };
+
+ this.LinkifyTotal = function(elLiner, oRecord, oColumn, oData) {
+ if (oData == 0)
+ elLiner.innerHTML = ".";
+ else if (oRecord.getData("row_title") == "Total")
+ elLiner.innerHTML = '<a href="[% urlbase FILTER js %][% "&amp;" _ row_vals IF row_vals %]
+ [%~ "&amp;" _ col_vals IF col_vals %]">'
+ + oData + '</a>';
+ else
+ elLiner.innerHTML = '<a href="[% urlbase FILTER js %]&amp;[% row_field FILTER uri FILTER js %]='
+ + bz_encode(oRecord.getData("row_title"), 1)
+ + '[% "&amp;" _ col_vals IF col_vals %]">' + oData + '</a>';
+
+ YAHOO.util.Dom.addClass(elLiner.parentNode, "ttotal");
+ };
+
+ var totalRowFormatter = function( elTr, oRecord ) {
+ if ( oRecord.getData('row_title') == "Total" ) {
+ YAHOO.util.Dom.addClass( elTr, 'ttotal' );
+ }
+ return true;
+ };
+
+ var totalNumberSorter = function( a, b, desc, field ){
+ var a_value = a.getData(field);
+ var b_value = b.getData(field);
+ var a_total_test = a.getData("row_title");
+ var b_total_test = b.getData("row_title");
+ var comp_result = YAHOO.util.Sort.compare(a_value, b_value, desc);
+ if( a_total_test == "Total" ){
+ comp_result = 1;
+ }else if( b_total_test == "Total" ){
+ comp_result = -1;
+ }
+ return comp_result;
+ };
+
+
+ var myColumnDefs = [
+ {key:"row_title", label:"", sortable:true, sortOptions: { sortFunction:totalNumberSorter }},
+ [% FOREACH col = col_names %]
+ {key:"[% col FILTER js %]", label:"[% display_value(col_field, col) FILTER html FILTER js %]", sortable:true,
+ formatter:this.Linkify, sortOptions: { defaultDir: YAHOO.widget.DataTable.CLASS_DESC, sortFunction:totalNumberSorter }},
+ [% END %]
+ {key:"total", label:"Total", sortable:true, formatter:this.LinkifyTotal,
+ sortOptions: { defaultDir: YAHOO.widget.DataTable.CLASS_DESC, sortFunction:totalNumberSorter }}
+ ];
+ this.parseString = function(str) {
+ return YAHOO.lang.trim(str);
+ };
+
+ this.parseNumber = function(str) {
+ if (str.match(/^\s*\.\s*$/m))
+ return 0;
+
+ // Do not use <\/a>$. For some reason, IE6 doesn't understand it.
+ // We use [^\d]+$ instead.
+ var res = str.match(/>(\d+)[^\d]+$/m);
+ if (res && res[1])
+ return parseFloat(res[1]);
+ };
+
+ this.myDataSource = new YAHOO.util.DataSource(YAHOO.util.Dom.get("tabular_report"));
+ this.myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
+ this.myDataSource.responseSchema = {
+ fields: [
+ {key:"row_title", parser:this.parseString},
+ [% FOREACH col = col_names %]
+ {key:"[% col FILTER js %]", parser:this.parseNumber},
+ [% END %]
+ {key:"total", parser:this.parseNumber}
+ ]
+ };
+ this.myDataTable = new YAHOO.widget.DataTable("tabular_report_container_
+ [% tbl FILTER js %]", myColumnDefs, this.myDataSource,
+ {formatRow: totalRowFormatter});
+});
+</script>
+
+[% IF tbl_field %]
+ <h2>[% tbl_disp FILTER email FILTER html %]</h2>
+[% END %]
+
+<table>
+ <tr>
+ <td>
+ </td>
+ <td align="center">
+ <strong>[% col_field_disp FILTER html %]</strong>
+ </td>
+ </tr>
+
+ <tr>
+ <td valign="middle">
+ <strong>[% row_field_disp FILTER html %]</strong>
+ </td>
+ <td>
+
+
+[% classes = [ [ "t1", "t2" ] , [ "t3", "t4" ] ] %]
+[% col_idx = 0 %]
+[% row_idx = 0 %]
+[% grand_total = 0 %]
+<div id="tabular_report_container_[% tbl FILTER html %]">
+<table id="tabular_report" border="1">
+ [% IF col_field %]
+ <thead>
+ <tr>
+ <th class="[% classes.$row_idx.$col_idx %]">
+ </th>
+ [% FOREACH col = col_names %]
+ [% col_totals.$col = 0 %]
+ [% NEXT IF col == "" %]
+
+ [% col_idx = 1 - col_idx %]
+ <th class="[% classes.$row_idx.$col_idx %]">
+ [% PROCESS value_display value = col field = col_field %]
+ </th>
+ [% END %]
+ <th class="ttotal">
+ Total
+ </th>
+ </tr>
+ </thead>
+ [% END %]
+ <tbody>
+ [% FOREACH row = row_names %]
+ [% row_total = 0 %]
+
+ [% row_idx = 1 - row_idx %]
+ <tr>
+ <td class="[% classes.$row_idx.$col_idx %]" align="right">
+ [% PROCESS value_display value = row field = row_field %]
+ </td>
+ [% FOREACH col = col_names %]
+ [% row_total = row_total + data.$tbl.$col.$row %]
+ [% NEXT IF col == "" %]
+ [% col_totals.$col = (col_totals.$col || 0) + data.$tbl.$col.$row %]
+
+ [% col_idx = 1 - col_idx %]
+ <td class="[% classes.$row_idx.$col_idx %]" align="center">
+ [% IF data.$tbl.$col.$row AND data.$tbl.$col.$row > 0 %]
+ <a href="[% urlbase %]&amp;
+ [% row_field FILTER uri %]=[% row FILTER uri %]&amp;
+ [% col_field FILTER uri %]=[% col FILTER uri %]">
+ [% data.$tbl.$col.$row %]</a>
+ [% ELSE %]
+ .
+ [% END %]
+ </td>
+ [% END %]
+ <td class="ttotal" align="right">
+ <a href="[% urlbase %]&amp;
+ [% row_field FILTER uri %]=[% row FILTER uri %]
+ [% "&amp;$col_vals" IF col_vals %]">
+ [% row_total %]</a>
+ [% grand_total = grand_total + row_total %]
+ </td>
+ </tr>
+ [% END %]
+ <tr>
+ [% row_idx = 1 - row_idx %]
+ <td class="ttotal">
+ Total
+ </td>
+ [% FOREACH col = col_names %]
+ [% NEXT IF col == "" %]
+
+ <td class="ttotal" align="center">
+ <a href="[% urlbase %]&amp;
+ [% col_field FILTER uri %]=[% col FILTER uri %]
+ [% "&amp;$row_vals" IF row_vals %]">
+ [% col_totals.$col %]</a>
+ </td>
+ [% END %]
+ <td class="ttotal" align="right">
+ <strong>
+ <a href="[% urlbase %]
+ [% "&amp;$row_vals" IF row_vals %]
+ [% "&amp;$col_vals" IF col_vals %]">[% grand_total %]</a>
+ </strong>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+ </td>
+ </tr>
+</table>
+
+[% BLOCK value_display %]
+ [% SET disp_value = display_value(field, value) %]
+ [% IF field == 'assigned_to' OR field == 'reporter'
+ OR field == 'qa_contact'
+ %]
+ [% disp_value = value FILTER email %]
+ [% END %]
+ [% disp_value FILTER html FILTER replace('^ $','&nbsp;') %]
+[% END %]
diff --git a/template/en/default/reports/report.csv.tmpl b/template/en/default/reports/report.csv.tmpl
new file mode 100644
index 0000000..a4f8589
--- /dev/null
+++ b/template/en/default/reports/report.csv.tmpl
@@ -0,0 +1,12 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+[% FOREACH tbl = tbl_names %]
+ [% PROCESS "reports/report-table.csv.tmpl" %]
+
+
+[% END %]
diff --git a/template/en/default/reports/report.html.tmpl b/template/en/default/reports/report.html.tmpl
new file mode 100644
index 0000000..2ca5dd9
--- /dev/null
+++ b/template/en/default/reports/report.html.tmpl
@@ -0,0 +1,152 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # col_field: string. Name of the field being plotted as columns.
+ # row_field: string. Name of the field being plotted as rows.
+ # tbl_field: string. Name of the field being plotted as tables.
+ # tbl_names: array. List of values for the field being plotted as tables.
+ # time: integer. Seconds since the epoch.
+ # data: <depends on format>. Data to plot.
+ # format: string. Format of the individual reports.
+ # width: integer. For image charts, height of the image.
+ # height: integer. For image charts, width of the image.
+ # imagebase: string. Base URL for chart image.
+ # switchbase: string. Base URL for format switching.
+ # cumulate: boolean. For bar/line charts, whether to cumulate data sets.
+ #%]
+
+[% DEFAULT width = 1024
+ height = 600
+%]
+
+[% IF min_width AND width < min_width %]
+ [% width = min_width %]
+[% END %]
+
+[%# We ignore row_field for pie charts %]
+[% IF format == "pie" %]
+ [% row_field = "" %]
+[% END %]
+
+[% tbl_field_disp = field_descs.$tbl_field || tbl_field %]
+[% col_field_disp = field_descs.$col_field || col_field %]
+[% row_field_disp = field_descs.$row_field || row_field %]
+[% switchbase = switchbase FILTER html %]
+
+[% title = BLOCK %]
+ Report:
+ [% IF tbl_field %]
+ [% tbl_field_disp FILTER html %]
+ [% END %]
+ [% " / " IF tbl_field AND (col_field OR row_field) %]
+ [% IF row_field %]
+ [% row_field_disp FILTER html %]
+ [% END %]
+ [% " / " IF col_field AND row_field %]
+ [% col_field_disp FILTER html %]
+[% END %]
+
+[% time = time FILTER time('%Y-%m-%d %H:%M:%S') FILTER html %]
+
+[% PROCESS global/header.html.tmpl
+ header_addl_info = time
+ style_urls = ['skins/standard/reports.css']
+ yui = ['datatable']
+%]
+
+[% IF debug %]
+ [% FOREACH query = queries %]
+ <p>[% query.sql FILTER html %]</p>
+ [% END %]
+[% END %]
+
+<div align="center">
+
+ [% FOREACH tbl = tbl_names %]
+ [% IF tbl == "-total-" %]
+ [% tbl_disp = "Total" %]
+ [% ELSE %]
+ [% tbl_disp = tbl %]
+ [% END %]
+
+ [% IF format == "table" %]
+ [% PROCESS "reports/report-table.html.tmpl" %]
+ [% ELSE %]
+ [% IF tbl %]
+ <h2>[% tbl_disp FILTER email FILTER html %]</h2>
+ [% END %]
+
+ [% imageurl = BLOCK %]report.cgi?[% imagebase FILTER html %]&amp;format=
+ [% format FILTER uri %]&amp;ctype=png&amp;action=plot&amp;
+ [% IF tbl_field %]
+ [% IF tbl != "-total-" %]
+ [% tbl_field FILTER uri %]=[% tbl FILTER uri %]&amp;
+ [% ELSE %]
+ [% FOREACH tblname = tbl_names %]
+ [% IF tblname != "-total-" %]
+ [% tbl_field FILTER uri %]=[% tblname FILTER uri %]&amp;
+ [% END %]
+ [% END %]
+ [% END %]
+ [% END %]width=[% width %]&amp;height=[% height %]
+ [% END %]
+
+ <img id="graphical_report" alt="Graphical report results" src="[% imageurl %]">
+ [% END %]
+ <br>
+ [% END %]
+
+ [% formats = [ { name => "pie", description => "Pie" },
+ { name => "bar", description => "Bar" },
+ { name => "line", description => "Line" },
+ { name => "table", description => "Table" } ] %]
+
+ [% formaturl = "report.cgi?$switchbase&amp;width=$width&amp;height=$height&amp;action=wrap" %]
+ [% FOREACH other_format = formats %]
+ [% NEXT IF other_format.name == "pie" AND row_field AND col_field %]
+ [% UNLESS other_format.name == format %]
+ <a href="[% formaturl %]&amp;format=[% other_format.name %]">
+ [% END %]
+ [% other_format.description FILTER html %]
+ [% "</a>" UNLESS other_format.name == format %] |
+ [% END %]
+ <a href="[% formaturl %]&amp;ctype=csv&amp;format=table">CSV</a>
+
+ <table>
+ <tr>
+ <td>
+ [% IF format == "table" %]
+ <a href="query.cgi?[% switchbase %]&amp;format=report-table">Edit this report</a>
+ [% ELSE %]
+ <a href="query.cgi?[% switchbase %]&amp;chart_format=
+ [%~ format FILTER uri %]&amp;format=report-graph&amp;cumulate=[% cumulate %]">
+ Edit this report</a>
+ [% END %]
+ </td>
+ <td>|</td>
+ <td>
+ [% IF saved_report_id %]
+ <a href="report.cgi?action=del&amp;saved_report_id=[% saved_report_id FILTER uri %]&amp;token=
+ [%~ issue_hash_token(['delete_report', saved_report_id]) FILTER uri %]">Forget this report</a>
+ [% ELSE %]
+ <form method="get" action="report.cgi">
+ <input type="submit" id="remember" value="Remember report"> as
+ <input type="hidden" name="query" value="[% switchbase %]&amp;format=[% format FILTER uri %]&amp;action=wrap">
+ <input type="hidden" name="action" value="add">
+ <input type="hidden" name="token" value="[% issue_hash_token(['save_report']) FILTER html %]">
+ <input type="text" id="name" name="name" size="20" value="" maxlength="64">
+ </form>
+ [% END %]
+ </td>
+ </tr>
+ </table>
+
+</div>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/reports/series-common.html.tmpl b/template/en/default/reports/series-common.html.tmpl
new file mode 100644
index 0000000..35d3c04
--- /dev/null
+++ b/template/en/default/reports/series-common.html.tmpl
@@ -0,0 +1,107 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # donames: boolean. True if we have a multi-select for names as well as
+ # categories and subcategories.
+ # category: hash (keyed by category) of hashes (keyed by subcategory) of
+ # hashes (keyed by name), with value being the series_id of the
+ # series. Contains details of all series the user can see.
+ #%]
+
+[% subcategory = category.${default.category} %]
+[% name = subcategory.${default.subcategory} %]
+
+<script type="text/javascript">
+[%# This structure holds details of the series the user can select from. %]
+var series = {
+[% FOREACH c = category.keys.sort %]
+ "[%+ c FILTER js %]" : {
+ [% FOREACH s = category.$c.keys.sort %]
+ "[%+ s FILTER js %]" : {
+ [% IF donames %]
+ [% FOREACH n = category.$c.$s.keys.sort %]
+ "[% n FILTER js %]":
+ [% category.$c.$s.$n FILTER js %][% ", " UNLESS loop.last %]
+ [% END %]
+ [% END %]
+ }[% ", " UNLESS loop.last %]
+ [% END %]
+ }[% ", " UNLESS loop.last %]
+[% END %]
+};
+
+[%# This function takes necessary action on selection of a category %]
+function catSelected() {
+ var cat = document.chartform.category.value;
+ var subcats = series[cat];
+
+ var subcatwidget = document.chartform.subcategory;
+
+ subcatwidget.options.length = 0;
+ var i = 0;
+
+ for (x in subcats) {
+ subcatwidget.options[i] = new Option(x, x);
+ i++;
+ }
+
+ [% IF newtext %]
+ subcatwidget.options[i] = new Option("[% newtext FILTER js %]", "");
+ [% END %]
+
+ subcatwidget.disabled = false;
+ subcatwidget.options[0].selected = true;
+
+ if (document.chartform.action[1]) {
+ [%# On the query form, select the right radio button. %]
+ document.chartform.action[1].checked = true;
+ }
+
+ checkNewState();
+}
+
+[%# This function updates the disabled state of the two "new" textboxes %]
+function checkNewState() {
+ var fm = document.chartform;
+ if (fm.newcategory) {
+ fm.newcategory.disabled =
+ (fm.category.value != "" ||
+ fm.action[1] && fm.action[1].checked == false);
+ fm.newsubcategory.disabled =
+ (fm.subcategory.value != "" ||
+ fm.action[1] && fm.action[1].checked == false);
+ }
+}
+</script>
+
+[%###########################################################################%]
+[%# Block for SELECT fields - pinched from search/form.html.tmpl #%]
+[%###########################################################################%]
+
+[% BLOCK series_select %]
+ <td align="left">
+ <select name="[% sel.name %]" id="[% sel.name %]"
+ size="[% sel.size %]" style="width: 15em"
+ [%+ 'multiple="multiple"' IF sel.multiple %]
+ [%+ "disabled=\"disabled\"" UNLESS ${sel.name}.keys.size || newtext %]
+ [%+ "onchange=\"$sel.onchange\"" IF sel.onchange %]>
+ [% FOREACH x = ${sel.name}.keys.sort %]
+ [% value = sel.value_in_hash ? ${sel.name}.$x : x %]
+ <option value="[% value FILTER html %]"
+ [% " selected" IF default.${sel.name} == value %]>
+ [% x FILTER html %]</option>
+ [% END %]
+ [% IF newtext %]
+ <option value="">[% newtext FILTER html %]</option>
+ [% ELSIF NOT ${sel.name}.keys.size %]
+ <option value="" disabled="disabled"></option>
+ [% END %]
+ </select>
+ </td>
+[% END %]
diff --git a/template/en/default/reports/series.html.tmpl b/template/en/default/reports/series.html.tmpl
new file mode 100644
index 0000000..a6bf0d9
--- /dev/null
+++ b/template/en/default/reports/series.html.tmpl
@@ -0,0 +1,85 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # default: hash. Defaults for category, subcategory, name etc.
+ # button_name: string. What the button will say.
+ # category: hash (keyed by category) of hashes (keyed by subcategory) of
+ # hashes (keyed by name), with value being the series_id of the
+ # series. Contains details of all series the user can see.
+ #%]
+
+[% PROCESS "reports/series-common.html.tmpl"
+ newtext = "New (name below)"
+ %]
+
+<table cellpadding="2" cellspacing="2" border="0"
+ style="text-align: left; margin-left: 20px">
+ <tbody>
+ <tr>
+ <th>Category:</th>
+ <th></th>
+ <th>Sub-category:</th>
+ <th>Name:</th>
+ <td></td>
+ </tr>
+ <tr>
+ [% PROCESS series_select sel = { name => 'category',
+ size => 5,
+ onchange => "catSelected()" } %]
+ <td>
+ <noscript>
+ <input type="submit" name="action-edit" value="Update --&gt;"
+ id="action-edit">
+ </noscript>
+ </td>
+
+ [% PROCESS series_select sel = { name => 'subcategory',
+ size => 5,
+ onchange => "checkNewState()" } %]
+
+ <td valign="top" name="name">
+ <input type="text" name="name" maxlength="64"
+ value="[% default.name.0 FILTER html %]" size="25">
+ </td>
+
+ <td valign="top">
+ <span style="font-weight: bold;">Run every</span> &nbsp;
+ <input type="text" size="2" name="frequency"
+ value="[% (default.frequency.0 OR 7) FILTER html %]">
+ <span style="font-weight: bold;">&nbsp;day(s)</span><br>
+ [%# Change 'admin' here and in Series.pm, or remove the check
+ completely, if you want to change who can make series public. %]
+ [% IF user.in_group('admin') %]
+ <input type="checkbox" name="public"
+ [%+ "checked='checked'" IF default.public.0 %]>
+ <span style="font-weight: bold;">Visible to all<br>
+ (within group restrictions)</span>
+ [% END %]
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <input type="text" style="width: 100%" name="newcategory"
+ maxlength="64" value="[% default.newcategory.0 FILTER html %]">
+ </td>
+ <td></td>
+ <td>
+ <input type="text" style="width: 100%" name="newsubcategory"
+ maxlength="64"
+ value="[% default.newsubcategory.0 FILTER html %]">
+ </td>
+ <td></td>
+ <td>
+ <input type="submit" name="submit-button" id="submit-button"
+ value="[% button_name FILTER html %]">
+ </td>
+ </tr>
+ </tbody>
+</table>
diff --git a/template/en/default/request/queue.html.tmpl b/template/en/default/request/queue.html.tmpl
new file mode 100644
index 0000000..bac0b84
--- /dev/null
+++ b/template/en/default/request/queue.html.tmpl
@@ -0,0 +1,263 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+[% PROCESS global/header.html.tmpl
+ title="Request Queue"
+ onload="var f = document.request_form; selectProduct(f.product, f.component, null, null, 'Any');"
+ javascript_urls=["js/productform.js", "js/field.js"]
+ style_urls = ['skins/standard/buglist.css']
+ yui = ['autocomplete']
+%]
+
+<script type="text/javascript">
+ var useclassification = false; // No classification level in use
+ var first_load = true; // Is this the first time we load the page?
+ var last_sel = []; // Caches last selection
+ var cpts = new Array();
+ [% n = 1 %]
+ [% IF Param('useclassification') %]
+ [% FOREACH clas = user.get_selectable_classifications %]
+ [% FOREACH prod = user.get_selectable_products(clas.id) %]
+ [%+ PROCESS js_comp %]
+ [% END %]
+ [% END %]
+ [% ELSE %]
+ [% FOREACH prod = user.get_selectable_products %]
+ [%+ PROCESS js_comp %]
+ [% END %]
+ [% END %]
+</script>
+
+[% BLOCK js_comp %]
+ cpts['[% n %]'] = [
+ [%- FOREACH comp = prod.components %]'[% comp.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%]];
+ [% n = n+1 %]
+[% END %]
+
+<p>
+When you are logged in, only requests made by you or addressed to you
+are shown by default. You can change the criteria using the form below.
+When you are logged out, all pending requests that are not restricted
+to some group are shown by default.
+</p>
+
+<form id="request_form" name="request_form" action="request.cgi" method="get">
+ <input type="hidden" name="action" value="queue">
+
+ <table id="filtering">
+ <tr>
+ <th>Requester:</th>
+ <td>
+ [% INCLUDE global/userselect.html.tmpl
+ id => "requester"
+ name => "requester"
+ value => cgi.param('requester')
+ size => 20
+ emptyok => 1
+ field_title => "Requester's email address"
+ %]
+ </td>
+ <th>Product:</th>
+ <td>
+ <select name="product" onchange="selectProduct(this, this.form.component, null, null, 'Any');">
+ <option value="">Any</option>
+ [% IF Param('useclassification') %]
+ [% FOREACH c = user.get_selectable_classifications %]
+ <optgroup label="[% c.name FILTER html %]">
+ [% FOREACH p = user.get_selectable_products(c.id) %]
+ <option value="[% p.name FILTER html %]"
+ [% " selected" IF cgi.param('product') == p.name %]>
+ [% p.name FILTER html %]
+ </option>
+ [% END %]
+ </optgroup>
+ [% END %]
+ [% ELSE %]
+ [% FOREACH p = user.get_selectable_products %]
+ <option value="[% p.name FILTER html %]"
+ [% " selected" IF cgi.param('product') == p.name %]>
+ [% p.name FILTER html %]
+ </option>
+ [% END %]
+ [% END %]
+ </select>
+ </td>
+ <th>Flag:</th>
+ <td>
+ [% PROCESS "global/select-menu.html.tmpl"
+ name="type"
+ options=types
+ default=cgi.param('type') %]
+ </td>
+
+ [%# We could let people see a "queue" of non-pending requests. %]
+ <!--
+ <th>Status:</th>
+ <td>
+ [%# PROCESS "global/select-menu.html.tmpl"
+ name="status"
+ options=["all", "?", "+-", "+", "-"]
+ default=cgi.param('status') %]
+ </td>
+ -->
+
+ </tr>
+ <tr>
+ <th>Requestee:</th>
+ <td>
+ [% INCLUDE global/userselect.html.tmpl
+ id => "requestee"
+ name => "requestee"
+ value => cgi.param('requestee')
+ size => 20
+ emptyok => 1
+ hyphenok => 1
+ field_title => "Requestee's email address or \"-\" (hyphen) for requests with no requestee"
+ %]
+ </td>
+ <th>Component:</th>
+ <td>
+ <select name="component">
+ <option value="">Any</option>
+ [% FOREACH comp = components %]
+ <option value="[% comp FILTER html %]" [% "selected" IF cgi.param('component') == comp %]>
+ [% comp FILTER html %]</option>
+ [% END %]
+ </select>
+ </td>
+ <th>Group By:</th>
+ <td>
+ [% groups = {
+ "Requester" => 'requester' ,
+ "Requestee" => 'requestee',
+ "Flag" => 'type' ,
+ "Product/Component" => 'category'
+ } %]
+ [% PROCESS "global/select-menu.html.tmpl" name="group" options=groups default=cgi.param('group') %]
+ </td>
+ </tr>
+ <tr>
+ <th></th>
+ <td>
+ <select id="do_union" name="do_union">
+ <option value="0">Match the requester AND requestee</option>
+ <option value="1" [% 'selected="selected"' IF cgi.param('do_union') %]>
+ Match the requester OR requestee</option>
+ </select>
+ </td>
+ <td colspan="3"></td>
+ <td><input type="submit" id="filter" value="Filter"></td>
+ </tr>
+ </table>
+</form>
+
+[% column_headers = {
+ "type" => "Flag" ,
+ "status" => "Status" ,
+ "bug" => "$terms.Bug" ,
+ "attachment" => "Attachment" ,
+ "requester" => "Requester" ,
+ "requestee" => "Requestee" ,
+ "created" => "Created" ,
+ "category" => "Product/Component" } %]
+
+[% DEFAULT display_columns = ["requester", "requestee", "type", "bug", "attachment", "created"]
+ group_field = "Requestee"
+ group_value = ""
+%]
+
+[% IF debug %]
+ <p>[% query FILTER html %]</p>
+[% END %]
+
+[% IF requests.size == 0 %]
+ <p>
+ No requests.
+ </p>
+[% ELSE %]
+ [% FOREACH request = requests %]
+ [% IF request.$group_field != group_value || loop.first %]
+ [% group_value = request.$group_field %]
+ [% PROCESS display_buglist UNLESS loop.first %]
+ [% PROCESS start_new_table %]
+ [% END %]
+ [% buglist.${request.bug_id} = 1 %]
+ <tr>
+ [% FOREACH column = display_columns %]
+ [% NEXT IF column == group_field || excluded_columns.contains(column) %]
+ <td>
+ [% PROCESS "display_$column" %]
+ [% Hook.process('after_column') %]
+ </td>
+ [% END %]
+ </tr>
+ [% END %]
+ [% PROCESS display_buglist %]
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
+
+[% BLOCK start_new_table %]
+ [% buglist = {} %]
+
+ <h3>[% column_headers.$group_field %]:
+ [%+ (request.$group_field || "None") FILTER email FILTER html %]</h3>
+ <table class="requests" cellspacing="0" cellpadding="4" border="1">
+ <tr>
+ [% FOREACH column = display_columns %]
+ [% NEXT IF column == group_field || excluded_columns.contains(column) %]
+ <th>[% column_headers.$column %]</th>
+ [% END %]
+ </tr>
+[% END %]
+
+[% BLOCK display_type %]
+ [% request.type FILTER html %]
+[% END %]
+
+[% BLOCK display_status %]
+ [% request.status %]
+[% END %]
+
+[% BLOCK display_bug %]
+ <a href="show_bug.cgi?id=[% request.bug_id %]"
+ [%- ' class="bz_secure"' IF request.restricted %]>
+ [% request.bug_id %]: [%+ request.bug_summary FILTER html %]</a>
+[% END %]
+
+[% BLOCK display_attachment %]
+ [% IF request.attach_id %]
+ <a href="attachment.cgi?id=[% request.attach_id %]&amp;action=edit">
+ [% request.attach_id %]: [%+ request.attach_summary FILTER html %]</a>
+ [% ELSE %]
+ N/A
+ [% END %]
+[% END %]
+
+[% BLOCK display_requestee %]
+ [% request.requestee FILTER email FILTER html %]
+[% END %]
+
+[% BLOCK display_requester %]
+ [% request.requester FILTER email FILTER html %]
+[% END %]
+
+[% BLOCK display_created %]
+ [% request.created FILTER time %]
+[% END %]
+
+[% BLOCK display_buglist %]
+ </table>
+ [% NEXT UNLESS buglist.keys.size %]
+ <a href="buglist.cgi?bug_id=
+ [%- buglist.keys.nsort.join(",") FILTER html %]">(view as
+ [%+ terms.bug %] list)</a>
+[% END %]
diff --git a/template/en/default/search/boolean-charts.html.tmpl b/template/en/default/search/boolean-charts.html.tmpl
new file mode 100644
index 0000000..508e11c
--- /dev/null
+++ b/template/en/default/search/boolean-charts.html.tmpl
@@ -0,0 +1,185 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% types = [
+ "noop",
+ "equals",
+ "notequals",
+ "anyexact",
+ "substring",
+ "casesubstring",
+ "notsubstring",
+ "anywordssubstr",
+ "allwordssubstr",
+ "nowordssubstr",
+ "regexp",
+ "notregexp",
+ "lessthan",
+ "lessthaneq",
+ "greaterthan",
+ "greaterthaneq",
+ "anywords",
+ "allwords",
+ "nowords",
+ "changedbefore",
+ "changedafter",
+ "changedfrom",
+ "changedto",
+ "changedby",
+ "matches",
+ "notmatches",
+] %]
+
+<div class="bz_section_title" id="custom_search_filter">
+ <div id="custom_search_query_controller" class="arrow">&#9660;</div>
+ <a id="chart" href="javascript:TUI_toggle_class('custom_search_query')" >
+ Custom Search</a> <span class="section_help">Didn't find what
+ you're looking for above? This area allows for ANDs, ORs,
+ and other more complex searches.</span>
+</div>
+<div id="custom_search_filter_section"
+ class="bz_search_section custom_search_query">
+ [% SET indent_level = 0 %]
+ [% SET cond_num = 0 %]
+ [% FOREACH condition = default.custom_search %]
+ [% SET cond_num = loop.count - 1 %]
+ [% PROCESS one_condition with_buttons = 0 %]
+ [% END %]
+ [% PROCESS one_condition
+ with_buttons = 1
+ condition = { f => 'noop' }
+ cond_num = cond_num + 1 %]
+ <script type="text/javascript">
+ TUI_alternates['custom_search_query'] = '&#9658;';
+ TUI_hide_default('custom_search_query');
+ TUI_alternates['custom_search_advanced'] = "Show Advanced Features";
+ TUI_hide_default('custom_search_advanced');
+ </script>
+ <script type="text/javascript" src="[% 'js/custom-search.js' FILTER mtime %]"></script>
+ <script type="text/javascript">
+ redirect_html4_browsers();
+ [%# These are alternative labels for the AND and OR options in and_all_select %]
+ var cs_and_label = 'Match ALL of the following:';
+ var cs_or_label = 'Match ANY of the following:';
+ cs_reconfigure('custom_search_last_row');
+ </script>
+ <script type="text/javascript" src="[% 'js/history.js/native.history.js' FILTER mtime %]"></script>
+</div>
+
+
+[% BLOCK one_condition %]
+ [%# Skip any conditions that don't have a field defined. %]
+ [% RETURN IF !condition.f %]
+
+ [% IF !top_level_any_shown %]
+ [% INCLUDE any_all_select
+ name = "j_top" selected = default.j_top.0
+ with_advanced_link = 1 %]
+ [% top_level_any_shown = 1 %]
+ [% END %]
+
+ [% IF condition.f == "CP" %]
+ [% indent_level = indent_level - 1 %]
+ [% END %]
+
+ <div class="custom_search_condition"
+ [% ' style="margin-left: ' _ (indent_level * 2) _ 'em"' IF indent_level %]
+ [% ' id="custom_search_last_row"' IF with_buttons %]>
+
+ [% IF previous_condition.f == "OP" %]
+ [% INCLUDE any_all_select
+ name = "j" _ (cond_num - 1)
+ selected = previous_condition.j %]
+ [% END %]
+
+ [% IF with_buttons %]
+ <button id="op_button" type="button" class="custom_search_advanced"
+ title="Start a new group of criteria, including this row"
+ onclick="custom_search_open_paren()">(</button>
+ [% END %]
+
+ [% UNLESS condition.f == "CP" %]
+ [%# This only gets hidden via custom_search_advanced if it isn't set. %]
+ <span id="custom_search_not_container_[% cond_num FILTER html %]"
+ class="custom_search_not_container
+ [%- ' custom_search_advanced' UNLESS condition.n %]"
+ title="Search for the opposite of the criteria here">
+ <input type="checkbox" id="n[% cond_num FILTER html %]"
+ class="custom_search_form_field"
+ name="n[% cond_num FILTER html %]" value="1"
+ onclick="custom_search_not_changed([% cond_num FILTER js %])"
+ [% ' checked="checked"' IF condition.n %]>
+ <label for="n[% cond_num FILTER html %]">Not</label>
+ </span>
+ [% END %]
+
+ [% IF condition.f == "OP" %]
+ <input type="hidden" name="f[% cond_num FILTER html %]"
+ id="f[% cond_num FILTER html %]" value="OP">
+ (
+ [% indent_level = indent_level + 1 %]
+ [% ELSIF condition.f == "CP" %]
+ <input type="hidden" name="f[% cond_num FILTER html %]"
+ id="f[% cond_num FILTER html %]" value="CP">
+ )
+ [% ELSE %]
+ <select name="f[% cond_num FILTER html %]" title="Field"
+ id="f[% cond_num FILTER html %]"
+ onchange="fix_query_string(this)"
+ class="custom_search_form_field">
+ [% FOREACH field = fields %]
+ <option value="[% field.name FILTER html %]"
+ [%~ ' selected="selected"' IF field.name == condition.f %]>
+ [% field_descs.${field.name} || field.description FILTER html %]
+ </option>
+ [% END %]
+ </select>
+
+ [% INCLUDE "search/type-select.html.tmpl"
+ name = "o${cond_num}", class = "custom_search_form_field"
+ types = types, selected = condition.o %]
+
+ <input name="v[% cond_num FILTER html %]" title="Value"
+ class="custom_search_form_field"
+ onchange="fix_query_string(this)"
+ value="[% condition.v FILTER html %]">
+ [% END %]
+
+ [% IF with_buttons %]
+ <button class="custom_search_add_button" type="button"
+ id="add_button" title="Add a new row"
+ onclick="custom_search_new_row()">+</button>
+ <span id="cp_container" [% ' class="bz_default_hidden"' IF !indent_level %]>
+ <button id="cp_button" type="button"
+ title="End this group of criteria"
+ onclick="custom_search_close_paren()">)</button>
+ </span>
+ [% END %]
+ </div>
+
+ [% previous_condition = condition %]
+[% END %]
+
+[% BLOCK any_all_select %]
+ <div class="any_all_select">
+ <select name="[% name FILTER html %]" id="[% name FILTER html %]"
+ onchange="fix_query_string(this)">
+ <option value="AND">Match ALL of the following separately:</option>
+ <option value="OR" [% ' selected="selected"' IF selected == "OR" %]>
+ Match ANY of the following separately:</option>
+ <option value="AND_G" [% ' selected' IF selected == "AND_G" %]>
+ Match ALL of the following against the same field:</option>
+ </select>
+ [% IF with_advanced_link %]
+ <a id="custom_search_advanced_controller"
+ href="javascript:TUI_toggle_class('custom_search_advanced')">
+ Hide Advanced Features
+ </a>
+ [% END %]
+ </div>
+[% END %]
diff --git a/template/en/default/search/field.html.tmpl b/template/en/default/search/field.html.tmpl
new file mode 100644
index 0000000..45c3650
--- /dev/null
+++ b/template/en/default/search/field.html.tmpl
@@ -0,0 +1,184 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% SWITCH field.type %]
+ [% CASE [ constants.FIELD_TYPE_FREETEXT,
+ constants.FIELD_TYPE_TEXTAREA,
+ constants.FIELD_TYPE_UNKNOWN ] %]
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = field
+ tag_name = "span"
+ editable = 1
+ %]
+ [% INCLUDE "search/type-select.html.tmpl"
+ name = field.name _ "_type",
+ types = types,
+ selected = type_selected
+ %]
+ <input name="[% field.name FILTER html %]"
+ id="[% field.name FILTER html %]" size="40"
+ [% IF onchange %] onchange="[% onchange FILTER html %]"[% END %]
+ value="[% value FILTER html %]">
+ [% CASE constants.FIELD_TYPE_KEYWORDS %]
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = field
+ tag_name = "span"
+ editable = 1
+ %]
+ [% INCLUDE "search/type-select.html.tmpl"
+ name = field.name _ "_type",
+ types = types,
+ selected = type_selected
+ %]
+ <div id="[% field.name FILTER html %]_container">
+ <input name="[% field.name FILTER html %]"
+ id="[% field.name FILTER html %]" size="40"
+ [% IF onchange %] onchange="[% onchange FILTER html %]"[% END %]
+ value="[% value FILTER html %]">
+ <div id="[% field.name FILTER html %]_autocomplete"></div>
+ </div>
+ <script type="text/javascript" defer="defer">
+ if (typeof YAHOO.bugzilla.field_array === "undefined")
+ YAHOO.bugzilla.field_array = [];
+ YAHOO.bugzilla.field_array["[% field.name FILTER js %]"] = [
+ [%- FOREACH val = possible_values %]
+ [%-# %]"[% val FILTER js %]"
+ [%- "," IF NOT loop.last %][% END %]];
+ YAHOO.bugzilla.fieldAutocomplete.init('[% field.name FILTER js %]',
+ '[% field.name FILTER js %]_autocomplete');
+ </script>
+ [% CASE constants.FIELD_TYPE_DATETIME %]
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = field
+ tag_name = "span"
+ editable = 1
+ %]
+ from <input name="[% field.name FILTER html %]from"
+ id="[% field.name FILTER html %]"
+ size="10" maxlength="10"
+ value="[% value.0 FILTER html %]"
+ onchange="updateCalendarFromField(this);[% onchange FILTER html %]">
+ <button type="button" class="calendar_button"
+ id="button_calendar_[% field.name FILTER html %]"
+ onclick="showCalendar('[% field.name FILTER js %]')">
+ <span>Calendar</span>
+ </button>
+ <span id="con_calendar_[% field.name FILTER html %]"></span>
+ to <input name="[% field.name FILTER html %]to"
+ id="[% field.name FILTER html %]to" size="10" maxlength="10"
+ value="[% value.1 FILTER html %]"
+ onchange="updateCalendarFromField(this);[% onchange FILTER html %]">
+ <button type="button" class="calendar_button"
+ id="button_calendar_[% field.name FILTER html %]to"
+ onclick="showCalendar('[% field.name FILTER js %]to')">
+ <span>Calendar</span>
+ </button>
+ <small>(YYYY-MM-DD or relative dates)</small>
+
+ <span id="con_calendar_[% field.name FILTER html %]to"></span>
+ <script type="text/javascript">
+ <!--
+ [%+ PROCESS "global/calendar.js.tmpl" id = field.name %]
+ [% PROCESS "global/calendar.js.tmpl" id = field.name _ 'to' %]
+ //--></script>
+ [% CASE [ constants.FIELD_TYPE_SINGLE_SELECT,
+ constants.FIELD_TYPE_MULTI_SELECT ] %]
+ <div id="container_[% field.name FILTER html %]" class="search_field_grid">
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = field
+ editable = 1
+ tag_name = "span"
+ %]
+ <select name="[% field.name FILTER html%]"
+ id="[% field.name FILTER html %]"
+ [% IF onchange %] onchange="[% onchange FILTER html %]"[% END %]
+ multiple="multiple" size="7">
+ [% legal_values = ${field.name} %]
+ [% IF field.name == "component" %]
+ [% legal_values = ${"component_"} %]
+ [% END %]
+ [% FOREACH current_value = legal_values %]
+ [% SET v = current_value.name OR '---' -%]
+ [% SET display = display_value(field.name, current_value.name) %]
+ <option value="[% v FILTER html %]"
+ id="v[% current_value.id FILTER html %]_[% field.name FILTER html %]"
+ [% ' selected="selected"' IF value.contains( v ) %]>
+ [%~ display FILTER html ~%]
+ </option>
+ [% END %]
+ </select>
+ </div>
+
+ [% IF value_controllers.${field.name}.defined %]
+ <script type="text/javascript"><!--
+ [%+ FILTER collapse %]
+ [% FOREACH accessor = value_controllers.${field.name}.keys %]
+ [% PROCESS controller_js %]
+ [% END %]
+ [%~ END ~%]
+ // --></script>
+ [% END %]
+ [% IF duplicates.${field.name}.keys.size %]
+ [% SET field_dups = duplicates.${field.name} %]
+ [% SET dup_counts = duplicate_count.${field.name} %]
+ <script type="text/javascript">
+ [%+ FILTER collapse %]
+ bz_option_duplicates['[% field.name FILTER js %]'] = {
+ [% FOREACH dup = field_dups.keys %]
+ [% dup FILTER js %]:[% field_dups.$dup.id FILTER js %]
+ [%~ ',' UNLESS loop.last %]
+ [% END ~%]
+ };
+ bz_option_duplicate_count['[% field.name FILTER js %]'] = {
+ [% FOREACH dup_target = dup_counts.keys %]
+ [% dup_target FILTER js %]:[% dup_counts.$dup_target FILTER js %]
+ [%~ ',' UNLESS loop.last %]
+ [% END %]
+ };
+ [% END %]
+ </script>
+ [% END %]
+
+ [% END %]
+[%# END OF SWITCH %]
+
+[% BLOCK controller_js %]
+ [%# If there are selected values already, we need to fire the
+ # "change" event once the page has loaded, so we can set all
+ # the values in all the other <select>s properly.
+ #%]
+ YAHOO.util.Event.onDOMReady(function() {
+ var field = document.getElementById('[% field.name FILTER js %]');
+ if (field.selectedIndex != -1) bz_fireEvent(field, 'change');
+ });
+
+ [% SET sub_field = value_controllers.${field.name}.$accessor %]
+ [% SET prod_per_class = {} %]
+ [% IF field.name == "classification" %]
+ [% FOREACH p = product %]
+ [% prod_per_class.${p.classification_id}.${p.id} = 1 %]
+ [% END %]
+ [% END %]
+
+ [% FOREACH legal_value = legal_values %]
+ [% SET controlled_ids = [] %]
+ [% IF field.name == "classification" %]
+ [% controlled_ids = prod_per_class.${legal_value.id}.keys %]
+ [% ELSE %]
+ [% FOREACH sub_value = legal_value.$accessor %]
+ [% controlled_ids.push(sub_value.id) %]
+ [% END %]
+ [% END %]
+ [% NEXT IF !controlled_ids.size %]
+ showValueWhen('[% sub_field.name FILTER js %]',
+ [[% controlled_ids.join(',') FILTER js %]],
+ '[% field.name FILTER js %]',
+ [% legal_value.id FILTER js %],
+ true);
+ [% END %]
+[% END %]
diff --git a/template/en/default/search/form.html.tmpl b/template/en/default/search/form.html.tmpl
new file mode 100644
index 0000000..8cfb12a
--- /dev/null
+++ b/template/en/default/search/form.html.tmpl
@@ -0,0 +1,341 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+
+<input type="hidden" id="no_redirect" name="no_redirect" value="0">
+<script type="text/javascript">
+ if (history && history.replaceState) {
+ var no_redirect = document.getElementById("no_redirect");
+ no_redirect.value = 1;
+ }
+
+// Hide the Advanced Fields by default, unless the user has a cookie
+// that specifies otherwise.
+// &#9656; and &#9662; are both utf8 escaped characters for right
+// and down facing arrows respectivly.
+TUI_alternates['history_query'] = '&#9658;';
+TUI_alternates['people_query'] = '&#9658;';
+TUI_alternates['information_query'] = '&#9658;';
+
+TUI_hide_default('history_query');
+TUI_hide_default('people_query');
+TUI_hide_default('information_query');
+</script>
+
+[% query_types = [
+ "allwordssubstr",
+ "anywordssubstr",
+ "substring",
+ "casesubstring",
+ "allwords",
+ "anywords",
+ "regexp",
+ "notregexp",
+] %]
+
+[%# If we resubmit to ourselves, we need to know if we are using a format. %]
+[% thisformat = query_format != '' ? query_format : format %]
+<input type="hidden" name="query_format" value="[% thisformat FILTER html %]">
+
+[%# *** Summary *** %]
+
+ <div class="search_field_row" id="summary_field">
+ [% INCLUDE "search/field.html.tmpl"
+ field = bug_fields.short_desc
+ types = query_types
+ value = default.short_desc.0
+ type_selected = default.short_desc_type.0
+ accesskey = "s"
+ %]
+ <script type="text/javascript"> <!--
+ document.getElementById('short_desc').focus();
+ // -->
+ </script>
+
+ [% IF button_name %]
+ <input type="submit" id="[% button_name FILTER css_class_quote %]_top"
+ value="[% button_name FILTER html %]">
+ [% END %]
+ </div>
+
+[%# *** Classification Product Component *** %]
+
+[% value_controllers = {
+ 'classification' => { 'products' => bug_fields.product },
+ 'product' => { 'components' => bug_fields.component,
+ 'versions' => bug_fields.version,
+ 'milestones' => bug_fields.target_milestone },
+} %]
+
+[% Hook.process('before_selects_top') %]
+[% IF Param('useclassification') %]
+ [% INCLUDE "search/field.html.tmpl"
+ field => bug_fields.classification
+ accesskey => "c"
+ value => default.classification
+ %]
+[% END %]
+
+[% INCLUDE "search/field.html.tmpl"
+ field => bug_fields.product
+ accesskey => "p"
+ value => default.product
+%]
+[% INCLUDE "search/field.html.tmpl"
+ field => bug_fields.component
+ accesskey => "m"
+ value => default.component
+%]
+[% INCLUDE "search/field.html.tmpl"
+ field => bug_fields.bug_status
+ accesskey => "a"
+ value => default.bug_status
+%]
+[% INCLUDE "search/field.html.tmpl"
+ field => bug_fields.resolution
+ accesskey => "r"
+ value => default.resolution
+%]
+
+[% Hook.process('after_selects_top') %]
+
+<div id="detailed_information" class="bz_section_title">
+ <div id="information_query_controller" class="arrow">&#9660;</div>
+ <a href="javascript:TUI_toggle_class('information_query')">
+ Detailed [% terms.Bug %] Information
+ </a>
+ <span class="section_help">Narrow results by the following fields:
+ [%+ field_descs.longdesc FILTER html %]s, [%+ field_descs.bug_file_loc FILTER html %],
+ [% IF Param('usestatuswhiteboard') %] [%+ field_descs.status_whiteboard FILTER html %], [%+ END %]
+ [% IF use_keywords %] [%+ field_descs.keywords FILTER html %], [%+ END %]
+ [% IF user.is_timetracker %] [%+ field_descs.deadline FILTER html %], [%+ END %]
+ [% terms.Bug %] Numbers, [%+ field_descs.version FILTER html %],
+ [% IF Param('usetargetmilestone') %] [%+ field_descs.target_milestone FILTER html %], [%+ END %]
+ [% field_descs.bug_severity FILTER html %], [%+ field_descs.priority FILTER html %], [%+ field_descs.rep_platform FILTER html %],
+ [%+ field_descs.op_sys FILTER html %]
+ </span>
+</div>
+[%# *** Comment URL Whiteboard Keywords *** %]
+<div id="detailed_information_section" class="bz_search_section information_query">
+ [% SET freetext_fields = [
+ { field => bug_fields.longdesc, accesskey => 'c' },
+ { field => bug_fields.bug_file_loc, accesskey => 'u' },
+ { field => bug_fields.status_whiteboard, accesskey => 'w' },
+ { field => bug_fields.keywords, accesskey => 'k',
+ qtypes => ['allwords', 'anywords', 'nowords', 'regexp', 'notregexp'] }
+ ] %]
+ [% Hook.process('before_freetext_fields') %]
+
+ [%# loop through a bunch of free text fields and print out their text stuff %]
+ [% FOREACH field_container = freetext_fields %]
+ [% NEXT IF field_container.field.name == 'status_whiteboard'
+ AND NOT Param('usestatuswhiteboard')
+ %]
+ [% NEXT IF field_container.field.name == 'keywords'
+ AND NOT use_keywords
+ %]
+ <div class="search_field_row">
+ [% type = field_container.field.name _ "_type" %]
+ [% possible_values = field_container.field.name == 'keywords' ? all_keywords : [] %]
+ [% INCLUDE "search/field.html.tmpl"
+ field => field_container.field
+ types => field_container.qtypes || query_types
+ accesskey => field_container.accesskey
+ value => default.${field_container.field.name}.0
+ type_selected => default.$type.0
+ %]
+ </div>
+ [% END %]
+
+ [%# Deadline %]
+ [% IF user.is_timetracker %]
+ <div class="search_field_row">
+ [% INCLUDE "search/field.html.tmpl"
+ field = bug_fields.deadline
+ accesskey = "l"
+ value = [ default.deadlinefrom.0, default.deadlineto.0 ]
+ %]
+ </div>
+ [% END %]
+
+ <div class="search_field_row">
+ <span class="field_label"><label for="bug_id">[% terms.Bugs %] numbered</label></span>
+ <div id="bug_id_container" >
+ <input type="text" name="bug_id" id="bug_id"
+ value="[% default.bug_id.0 FILTER html %]" size="20">
+ <div class="field_help">(comma-separated list)</div>
+ </div>
+ should be
+ <select name="bug_id_type" id="bug_id_type">
+ <option value="anyexact"[% " selected" IF default.bug_id_type.0 == "anyexact" %]>only included in</option>
+ <option value="nowords"[% " selected" IF default.bug_id_type.0 == "nowords" %]>excluded from</option>
+ </select> the results
+ </div>
+
+ [% Hook.process('after_freetext_fields') %]
+
+ [%# *** Status Resolution Severity Priority Hardware OS *** %]
+ <div>
+ [% Hook.process('before_selects_bottom') %]
+ [% fake_version_field = { name => bug_fields.version.name,
+ type => constants.FIELD_TYPE_SINGLE_SELECT }%]
+ [% INCLUDE "search/field.html.tmpl"
+ field => fake_version_field
+ value => default.version
+ %]
+ [% IF Param('usetargetmilestone') %]
+ [% fake_target_milestone_field = { name => bug_fields.target_milestone.name ,
+ type => constants.FIELD_TYPE_SINGLE_SELECT } %]
+ [% INCLUDE "search/field.html.tmpl"
+ field => fake_target_milestone_field
+ value => default.target_milestone
+ %]
+ [% END %]
+ [% INCLUDE "search/field.html.tmpl"
+ field => bug_fields.bug_severity
+ accesskey=> "v"
+ value => default.bug_severity
+ %]
+ [% INCLUDE "search/field.html.tmpl"
+ field => bug_fields.priority
+ accesskey => "i"
+ value => default.priority
+ %]
+ [% INCLUDE "search/field.html.tmpl"
+ field => bug_fields.rep_platform
+ accesskey =>"h"
+ value => default.rep_platform
+ %]
+ [% INCLUDE "search/field.html.tmpl"
+ field => bug_fields.op_sys
+ accesskey =>"o"
+ value => default.op_sys
+ %]
+ [% Hook.process('after_selects_bottom') %]
+ </div>
+</div>
+[%# *** Email Numbering *** %]
+ <div class="bz_section_title" id="people_filter">
+ <div id="people_query_controller" class="arrow">&#9660;</div>
+ <a href="javascript:TUI_toggle_class('people_query')">Search By People</a>
+ <span>Narrow results to a role (i.e. [% field_descs.assigned_to FILTER html %],
+ [%+ field_descs.reporter FILTER html %], [% field_descs.commenter FILTER html %],
+ etc.) a person has on [% terms.abug %]
+ </span>
+ </div>
+ <div id="people_filter_section" class="bz_search_section people_query">
+ [% FOREACH n = [1, 2, 3] %]
+ <div class="search_email_fields">
+ Any of:
+ [% PROCESS role_types field = { count => n, name => "emailassigned_to",
+ label=> "the ${terms.Bug} ${field_descs.assigned_to}" } %]
+ [% PROCESS role_types field = { count => n, name => "emailreporter",
+ label=> "the ${field_descs.reporter}" } %]
+ [% IF Param('useqacontact') %]
+ [% PROCESS role_types field = { count => n, name => "emailqa_contact",
+ label=> "the ${field_descs.qa_contact}" } %]
+ [% END %]
+ [% PROCESS role_types field = { count => n, name => "emailcc",
+ label=> "a ${field_descs.cc} list member" } %]
+ [% PROCESS role_types field = { count => n, name => "emaillongdesc",
+ label=> " a ${field_descs.commenter}" } %]
+ <select name="emailtype[% n %]">
+ [% FOREACH qv = [
+ { name => "substring", description => "contains" },
+ { name => "notsubstring", description => "doesn't contain" },
+ { name => "exact", description => "is" },
+ { name => "notequals", description => "is not" },
+ { name => "regexp", description => "matches regexp" },
+ { name => "notregexp", description => "doesn't match regexp" } ] %]
+ <option value="[% qv.name %]"
+ [% " selected" IF default.emailtype.$n == qv.name %]>[% qv.description %]</option>
+ [% END %]
+ </select>
+ [% IF feature_enabled('jsonrpc') && Param('ajax_user_autocompletion') %]
+ <div id="email[% n %]_autocomplete">
+ [% END %]
+ <input name="email[% n %]" class="email" id="email[% n %]"
+ value="[% default.email.$n FILTER html %]">
+ [% IF feature_enabled('jsonrpc') && Param('ajax_user_autocompletion') %]
+ <div id="email[% n %]_autocomplete_container"></div>
+ </div>
+ <script type="text/javascript">
+ YAHOO.bugzilla.userAutocomplete.init( "email[% n %]",
+ "email[% n %]_autocomplete_container");
+ </script>
+ [% END %]
+ </div>
+ [% END %]
+ [% Hook.process('email_numbering_end') %]
+ </div>
+[%# *** Bug Changes *** %]
+<div class="bz_section_title" id="history_filter">
+ <div id="history_query_controller" class="arrow">&#9660;</div>
+ <a href="javascript:TUI_toggle_class('history_query')" >Search By Change History</a>
+ <span>Narrow results to how fields have changed during a specific time period</span>
+</div>
+<ul class="bug_changes bz_search_section history_query" id="history_filter_section" >
+ <li>
+ <label for="chfield">where ANY of the fields:</label>
+ [%# Create array, so we can sort it by description #%]
+ [% chfields = [] %]
+ [% FOREACH field = chfield %]
+ [% chfields.push({value => field, desc => (field_descs.$field || field) }) %]
+ [% END %]
+ <select name="chfield" id="chfield" multiple="multiple" size="4">
+ [% FOREACH field = chfields.sort('desc') %]
+ <option value="[% field.value FILTER html %]"
+ [% " selected" IF default.chfield.contains(field.value) %]>
+ [% field.desc FILTER html %]</option>
+ [% END %]
+ </select>
+ </li>
+ <li>
+ <label for="chfieldvalue">[% search_descs.changedto FILTER html %]:</label>
+ <input name="chfieldvalue" id="chfieldvalue"
+ size="20" value="[% default.chfieldvalue.0 FILTER html %]">
+ </li>
+ <li>
+ <label for="chfieldfrom">between:</label>
+ <input name="chfieldfrom" id="chfieldfrom" size="10"
+ value="[% default.chfieldfrom.0 FILTER html %]" onchange="updateCalendarFromField(this)">
+ <button type="button" class="calendar_button"
+ id="button_calendar_chfieldfrom"
+ onclick="showCalendar('chfieldfrom')"><span>Calendar</span></button>
+ and
+ <div id="con_calendar_chfieldfrom"></div>
+ <input name="chfieldto" size="10" id="chfieldto"
+ value="[% default.chfieldto.0 || "Now" FILTER html %]"
+ onchange="updateCalendarFromField(this)">
+ <button type="button" class="calendar_button"
+ id="button_calendar_chfieldto"
+ onclick="showCalendar('chfieldto')"><span>Calendar</span></button>
+ <div id="con_calendar_chfieldto"></div>
+ (YYYY-MM-DD or relative dates)
+ <script type="text/javascript">
+ <!--
+ [%+ PROCESS "global/calendar.js.tmpl" id = 'chfieldfrom' %]
+ [% PROCESS "global/calendar.js.tmpl" id = 'chfieldto' %]
+ //--></script>
+ </li>
+</ul>
+
+[%############################################################################%]
+[%# Block for email role type use to select which email to search through #%]
+[%############################################################################%]
+[% BLOCK role_types %]
+ <div class="role_type">
+ <input type="checkbox" name="[% field.name _ field.count FILTER html %]"
+ id="[% field.name _ field.count FILTER html %]" value="1"
+ [% " checked" IF default.${field.name}.${field.count} %]>
+ <label for="[% field.name _ field.count FILTER html%]">
+ [% field.label FILTER html%]
+ </label>
+ </div>
+[% END %]
diff --git a/template/en/default/search/knob.html.tmpl b/template/en/default/search/knob.html.tmpl
new file mode 100644
index 0000000..e9e3daa
--- /dev/null
+++ b/template/en/default/search/knob.html.tmpl
@@ -0,0 +1,74 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # (incomplete!)
+ # ...
+ # known_name: string. Possibly known stored name for the query being
+ # edited. This value is just passed through in a
+ # hidden field.
+ #%]
+
+[%# This is not necessary for English templates, but useful for localizers. %]
+[% ordersdesc = {
+ "Reuse same sort as last time" => "Reuse same sort as last time",
+ "Bug Number" => "$terms.Bug Number",
+ "Importance" => "Importance",
+ "Assignee" => "Assignee",
+ "Last Changed" => "Last Changed" } %]
+
+<input type="hidden" name="cmdtype" value="doit">
+[% IF user.id %]
+ <input type="hidden" name="token" value="[% issue_hash_token(['searchknob']) FILTER html %]">
+[% END %]
+
+<p>
+ <label for="order">Sort results by</label>:
+ <select name="order" id="order">
+ [% FOREACH order = orders %]
+ <option value="[% order FILTER html %]"
+ [% " selected" IF default.order.0 == order %]>
+ [% ordersdesc.$order FILTER html %]</option>
+ [% END %]
+ </select>
+</p>
+
+<p>
+ <input type="submit" id="[% button_name FILTER html %]"
+ value="[% button_name FILTER html %]">
+ [% IF known_name %]
+ [%# We store known_name in case the user adds a boolean chart. %]
+ <input type="hidden" name="known_name" value="[% known_name FILTER html %]">
+
+ [%# The name of the existing query will be passed to buglist.cgi. %]
+ <input type="hidden" name="query_based_on" value="[% known_name FILTER html %]">
+ [% END %]
+ [%# Preserve any custom column list that might be set. %]
+ [% IF columnlist %]
+ <input type="hidden" name="columnlist" value="[% columnlist FILTER html %]">
+ [% END %]
+</p>
+
+[% IF user.id %]
+ <p>
+ &nbsp;&nbsp;&nbsp;
+ <input type="checkbox" id="remasdefault"
+ name="remtype" value="asdefault">
+ <label for="remasdefault">
+ and remember these as my default search options
+ </label>
+ </p>
+[% END %]
+
+[% IF userdefaultquery %]
+ <p>
+ <a href="query.cgi?nukedefaultquery=1&amp;token=
+ [%- issue_hash_token(['nukedefaultquery']) FILTER uri %]">
+ Set my default search back to the system default</a>.
+ </p>
+[% END %]
diff --git a/template/en/default/search/search-advanced.html.tmpl b/template/en/default/search/search-advanced.html.tmpl
new file mode 100644
index 0000000..2bff834
--- /dev/null
+++ b/template/en/default/search/search-advanced.html.tmpl
@@ -0,0 +1,55 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # This template has no interface. However, to use it, you need to fulfill
+ # the interfaces of search/form.html.tmpl, search/knob.html.tmpl and
+ # search/boolean-charts.html.tmpl.
+ #%]
+
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+[% javascript = BLOCK %]
+function remove_token() {
+ if (queryform.token) {
+ var asDefault = document.getElementById('remasdefault');
+ queryform.token.disabled = !asDefault.checked;
+ }
+}
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = "Search for $terms.bugs"
+ yui = [ 'autocomplete', 'calendar' ]
+ javascript = javascript
+ javascript_urls = [ "js/util.js", "js/TUI.js", "js/field.js"]
+ style_urls = [ "skins/standard/search_form.css" ]
+ doc_section = "query.html"
+%]
+
+[% WRAPPER search/tabs.html.tmpl %]
+
+[% button_name = "Search" %]
+
+<p id="search_help">Hover your mouse over each field label to get help for that field.</p>
+
+<form method="post" action="buglist.cgi" name="queryform" id="queryform"
+ onsubmit="remove_token()">
+
+[% PROCESS search/form.html.tmpl %]
+
+[% PROCESS "search/boolean-charts.html.tmpl" %]
+
+[% PROCESS search/knob.html.tmpl %]
+
+</form>
+
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/search/search-create-series.html.tmpl b/template/en/default/search/search-create-series.html.tmpl
new file mode 100644
index 0000000..d2f8f7d
--- /dev/null
+++ b/template/en/default/search/search-create-series.html.tmpl
@@ -0,0 +1,57 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # This template has no interface. However, to use it, you need to fulfill
+ # the interfaces of search/form.html.tmpl, reports/series.html.tmpl and
+ # search/boolean-charts.html.tmpl.
+ #%]
+
+[% js_data = BLOCK %]
+ var queryform = "chartform";
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = "Create New Data Set"
+ onload = "doOnSelectProduct(0);"
+ yui = [ 'autocomplete', 'calendar' ]
+ javascript = js_data
+ javascript_urls = [ "js/util.js", "js/TUI.js", "js/field.js" ]
+ style_urls = [ "skins/standard/search_form.css" ]
+ doc_section = "reporting.html#charts-new-series"
+%]
+
+<form method="get" action="chart.cgi" name="chartform">
+
+[% PROCESS search/form.html.tmpl %]
+
+<p>
+ <input type="submit" id="action-search" name="action-search" value="Run Search">
+ to see which [% terms.bugs %] would be included in this data set.
+</p>
+
+<h3>Data Set Parameters</h3>
+
+[% PROCESS reports/series.html.tmpl
+ button_name = "Create Data Set" %]
+ <input type="hidden" name="action" value="create">
+ <input type="hidden" name="token" value="[% issue_hash_token(['create-series']) FILTER html %]">
+
+<script type="text/javascript">
+ document.chartform.category[0].selected = true;
+ catSelected();
+ checkNewState();
+</script>
+
+<hr>
+
+[% PROCESS "search/boolean-charts.html.tmpl" %]
+
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/search/search-plugin.xml.tmpl b/template/en/default/search/search-plugin.xml.tmpl
new file mode 100644
index 0000000..27f5b77
--- /dev/null
+++ b/template/en/default/search/search-plugin.xml.tmpl
@@ -0,0 +1,19 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+<?xml version="1.0" encoding="UTF-8"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+<ShortName>[% terms.Bugzilla %]</ShortName>
+<Description>[% terms.Bugzilla %] Quick Search</Description>
+<InputEncoding>UTF-8</InputEncoding>
+[% IF favicon %]
+ <Image width="16" height="16">data:image/x-icon;base64,[% favicon FILTER base64 %]</Image>
+[% ELSE %]
+ <Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABGdBTUEAAK%2FINwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAALBSURBVHjaYnxckcEAA3%2F%2B%2FT%2F17LUcH%2Fevf%2F8U%2BHmYGBkZMABAALEgc%2B68%2F3T227cf2tJKKhJLt59n%2FfmbnYnZV1KEhYkJrgYggBghNrz78fPIi3d8uvKBIdb%2FOaWPnzitLc97%2Bc5rFXnhnVO3%2BslLwjUABBDIhnsfPl%2Fj53VO91FX4Gfgkjxw%2Fd%2F6Q49%2FWStqyAj%2B%2B88gZqn%2B9u5rYU52iAaAAGL69%2F%2F%2F2d9%2FYiMclGT4fv76%2BZ9DbO%2FeA39%2BfJHVcvj5l%2Bnh03e%2FWThOvnwLtwEgAAAxAM7%2FBPj8%2FRYkHQYHAf3%2F%2Fv%2F%2B%2Fv8BAVNTUPX18yorLNHE2S8mB%2FT2%2Bq7a4dvu8iUSDgAAAAKICRgUv3%2F8ZGKGeIvpz6eXBvq61lZWLMwMv%2F5zMP7%2FqSAjVFyZ%2FNvZftuT10DnAAQAMQDO%2FwQIBAPz5Or6%2Ff0CBQEAAgT99ubq38z2%2BwT18%2FAM%2F%2BkNDAv6%2FQMCAA1GVVrhMze5h4kCCORpkd9%2F3n74KiHO%2B%2BffX8b%2Ff7m%2BXWP985%2Bf5R%2BPLNdfoK%2F%2F%2Ffv39%2BePj2%2FkZYR0fe0BAgikQZGX%2B9b9FzLS%2FH%2F%2B%2FGVgYGRlZWNlA7nv7z9QuDP8%2B8nw%2FRXjn68Mv4Gu%2FAwQQCCni3FxPLn7nIGZGegfNhYmNjYWZnBMASOakZER6Eumf9%2FYGT4y%2FHx%2F%2BfBFgAAC2cDGzPT99WeGvwzvv%2Fx89vrr%2F39%2FJER4pcT5Gf4z%2FP37D2jtj9%2B%2FL918fmzrKSsWNoAAgiaN%2Fz9%2Fff%2F6S4CP8%2BWbz9vWHfv54aukpAAz0Og%2Ff%2F7%2F%2Bs36668cO3ugED9QJUAAQTUArf7%2F8x87D9vRjcejhPiZhAUYcACAAGI5%2FOHH9ddvXzAxmjz%2B8P8lw4fXn5l4eRlwA4AAYmaTkBFg%2FKvJwfbkwZuXN57y%2Fv%2F34stXGR4uRmxpGwgAAgwA4%2FkfrfCWvLQAAAAASUVORK5CYII%3D</Image>
+[% END %]
+<Url type="text/html" method="GET" template="[% urlbase FILTER xml %]buglist.cgi?quicksearch={searchTerms}"/>
+</OpenSearchDescription>
diff --git a/template/en/default/search/search-report-graph.html.tmpl b/template/en/default/search/search-report-graph.html.tmpl
new file mode 100644
index 0000000..698132e
--- /dev/null
+++ b/template/en/default/search/search-report-graph.html.tmpl
@@ -0,0 +1,128 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # This template has no interface. However, to use it, you need to fulfill
+ # the interfaces of the templates it contains.
+ #%]
+
+[% js_data = BLOCK %]
+var queryform = "reportform"
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = "Generate Graphical Report"
+ onload = "doOnSelectProduct(0); chartTypeChanged()"
+ yui = [ 'autocomplete', 'calendar' ]
+ javascript = js_data
+ javascript_urls = [ "js/util.js", "js/TUI.js", "js/field.js" ]
+ style_urls = [ "skins/standard/search_form.css" ]
+ doc_section = "reporting.html#reports"
+%]
+
+[% PROCESS "search/search-report-select.html.tmpl" %]
+
+<p>
+ Choose one or more fields as your axes, and then refine your set of
+ [% terms.bugs %] using the rest of the form.
+</p>
+
+<script type="text/javascript"><!--
+ [%# The Y-axis fields are not used for pie charts %]
+ function chartTypeChanged() {
+ // format[2] is the pie chart radio button
+ if (document.reportform.format[2].checked == true) {
+ document.reportform.y_axis_field.disabled = true;
+ document.reportform.cumulate[0].disabled = true;
+ document.reportform.cumulate[1].disabled = true;
+ } else {
+ document.reportform.y_axis_field.disabled = false;
+ document.reportform.cumulate[0].disabled = false;
+ document.reportform.cumulate[1].disabled = false;
+ }
+ }
+// -->
+</script>
+
+[% button_name = "Generate Report" %]
+
+<form method="get" action="report.cgi" name="reportform" id="reportform">
+
+<table align="center">
+ <tr>
+ <td valign="middle">
+ <b>Vertical Axis:</b><br>
+ <noscript><small>(not for pie charts)</small><br></noscript>
+ [% PROCESS select name = 'y_axis_field' %]<br>
+ <br>
+ <b>Plot Data Sets:</b><br>
+ <input type="radio" name="cumulate" value="0"
+ [% " checked" IF default.cumulate.0 != "1" %]>
+ Individually<br>
+ <input type="radio" name="cumulate" value="1"
+ [% " checked" IF default.cumulate.0 == "1" %]>
+ Stacked
+ </td>
+ <td width="150" height="150">
+ <table border="1" width="100%" height="100%">
+ <tr>
+ <td align="center" valign="middle">
+ <b>Multiple Images:</b><br>
+ [% PROCESS select name = 'z_axis_field' %]
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td rowspan="2">
+ <b>Format:</b><br>
+ [% chart_formats = [
+ { name => "line", description => "Line Graph" },
+ { name => "bar", description => "Bar Chart" },
+ { name => "pie", description => "Pie Chart" } ] %]
+ [% default.chart_format.0 = default.chart_format.0 || "bar" %]
+
+ [% FOREACH chart_format = chart_formats %]
+ <input type="radio" name="format"
+ value="[% chart_format.name FILTER html %]"
+ onchange="chartTypeChanged()"
+ [% " checked" IF default.chart_format.0 == chart_format.name %]>
+ [% chart_format.description FILTER html %]<br>
+ [% END %]
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ </td>
+ <td align="left">
+ <b>Horizontal Axis:</b>
+ [% PROCESS select name = 'x_axis_field' %]<br>
+ <label for="x_labels_vertical"><b>Vertical labels:</b></label>
+ <input type="checkbox" name="x_labels_vertical" id="x_labels_vertical"
+ value="1"
+ [% " checked" IF default.x_labels_vertical.0 == "1" %]>
+ </td>
+ <td>
+ </td>
+ </tr>
+</table>
+
+<hr>
+
+[% PROCESS search/form.html.tmpl %]
+
+[% PROCESS "search/boolean-charts.html.tmpl" %]
+
+ <div id="knob">
+ <input type="submit" id="[% button_name FILTER css_class_quote %]"
+ value="[% button_name FILTER html %]">
+ <input type="hidden" name="action" value="wrap">
+ </div>
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/search/search-report-select.html.tmpl b/template/en/default/search/search-report-select.html.tmpl
new file mode 100644
index 0000000..93b4c44
--- /dev/null
+++ b/template/en/default/search/search-report-select.html.tmpl
@@ -0,0 +1,29 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # name: string. The name of the select block to output.
+ # default.$name.0: string. The default value for the block, if any.
+ #%]
+
+[% BLOCK select %]
+ [% Hook.process('rep_fields', 'search/search-report-select.html.tmpl') %]
+
+ <select name="[% name FILTER html %]">
+ <option value="">&lt;none&gt;</option>
+
+ [% FOREACH field = report_columns.keys.sort %]
+ [% NEXT IF field == "classification" AND !Param('useclassification') %]
+ [% NEXT IF field == "target_milestone" AND !Param('usetargetmilestone') %]
+ [% NEXT IF field == "qa_contact" AND !Param('useqacontact') %]
+ <option value="[% field FILTER html %]"
+ [% " selected" IF default.$name.0 == field %]>
+ [% field_descs.$field || field FILTER html %]</option>
+ [% END %]
+ </select>
+[% END %]
diff --git a/template/en/default/search/search-report-table.html.tmpl b/template/en/default/search/search-report-table.html.tmpl
new file mode 100644
index 0000000..7e0a002
--- /dev/null
+++ b/template/en/default/search/search-report-table.html.tmpl
@@ -0,0 +1,81 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # This template has no interface. However, to use it, you need to fulfill
+ # the interfaces of the templates it contains.
+ #%]
+
+[% js_data = BLOCK %]
+var queryform = "reportform"
+[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = "Generate Tabular Report"
+ onload = "doOnSelectProduct(0)"
+ yui = [ 'autocomplete', 'calendar' ]
+ javascript = js_data
+ javascript_urls = [ "js/util.js", "js/TUI.js", "js/field.js" ]
+ style_urls = [ "skins/standard/search_form.css" ]
+ doc_section = "reporting.html#reports"
+%]
+
+[% PROCESS "search/search-report-select.html.tmpl" %]
+
+<p>
+ Choose one or more fields as your axes, and then refine your set of
+ [% terms.bugs %] using the rest of the form.
+</p>
+
+[% button_name = "Generate Report" %]
+
+<form method="get" action="report.cgi" name="reportform" id="reportform">
+
+<table align="center">
+ <tr>
+ <td>
+ </td>
+ <td align="center">
+ <b>Horizontal Axis:</b>
+ [% PROCESS select name = 'x_axis_field' %]
+ </td>
+ </tr>
+
+ <tr>
+ <td valign="middle" align="center">
+ <b>Vertical Axis:</b><br>
+ [% PROCESS select name = 'y_axis_field' %]
+ </td>
+ <td width="150" height="150">
+ <table border="1" width="100%">
+ <tr>
+ <td align="center" valign="middle" height="150">
+ <b>Multiple Tables:</b><br>
+ [% PROCESS select name = 'z_axis_field' %]
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</table>
+
+<hr>
+
+ [% PROCESS search/form.html.tmpl %]
+
+ [% PROCESS "search/boolean-charts.html.tmpl" %]
+
+ <div id="knob">
+ <input type="submit" id="[% button_name FILTER css_class_quote %]"
+ value="[% button_name FILTER html %]">
+ <input type="hidden" name="format" value="table">
+ <input type="hidden" name="action" value="wrap">
+ </div>
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/search/search-specific.html.tmpl b/template/en/default/search/search-specific.html.tmpl
new file mode 100644
index 0000000..1093f70
--- /dev/null
+++ b/template/en/default/search/search-specific.html.tmpl
@@ -0,0 +1,122 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Simple Search"
+ style_urls = [ "skins/standard/search_form.css" ]
+%]
+
+[% WRAPPER search/tabs.html.tmpl %]
+
+<p>
+Find a specific [% terms.bug %] by entering words that describe it.
+[% terms.Bugzilla %] will search [% terms.bug %] descriptions and comments
+for those words and return a list of matching [% terms.bugs %] sorted
+by relevance.
+</p>
+
+<p>
+For example, if the [% terms.bug %] you are looking for is a browser crash when you go to a secure web site with an embedded Flash animation, you might search
+for "crash secure SSL flash".
+</p>
+
+<form name="queryform" method="get" action="buglist.cgi">
+<input type="hidden" name="query_format" value="specific">
+<input type="hidden" name="order" value="relevance desc">
+<input type="hidden" id="no_redirect" name="no_redirect" value="0">
+<script type="text/javascript">
+ if (history && history.replaceState) {
+ var no_redirect = document.getElementById("no_redirect");
+ no_redirect.value = 1;
+ }
+</script>
+
+<table summary="Search fields" class="bz_simple_search_form">
+ <tr>
+ <th>
+ <label for="bug_status">[% field_descs.bug_status FILTER html %]:</label>
+ </th>
+ <td>
+ <select name="bug_status" id="bug_status">
+ [% statuses = [ { name = 'open', label = "Open" },
+ { name = 'closed', label = "Closed" },
+ { name = 'all', label = "All" } ] %]
+ [% FOREACH status = statuses %]
+ <option value="__[% status.name %]__"
+ [% " selected" IF default.bug_status.0 == "__${status.name}__" %]>
+ [% status.label FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <th>
+ <label for="product">[% field_descs.product FILTER html %]:</label>
+ </th>
+ <td>
+ <select name="product" id="product">
+ <option value="">All</option>
+ [% IF Param('useclassification') %]
+ [% FOREACH c = classification %]
+ <optgroup label="[% c.name FILTER html %]">
+ [% FOREACH p = user.get_selectable_products(c.id) %]
+ [% IF p.components.size %]
+ <option value="[% p.name FILTER html %]"
+ [% " selected" IF default.product.contains(p.name) %]>
+ [% p.name FILTER html %]
+ </option>
+ [% END %]
+ [% END %]
+ </optgroup>
+ [% END %]
+ [% ELSE %]
+ [% FOREACH p = product %]
+ <option value="[% p.name FILTER html %]"
+ [% " selected" IF default.product.contains(p.name) %]>
+ [% p.name FILTER html %]
+ </option>
+ [% END %]
+ [% END %]
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <th>
+ <label for="content">Words:</label>
+ </th>
+ <td>
+ <input name="content" size="40" id="content"
+ value="[% default.content.0 FILTER html %]">
+ <script type="text/javascript"> <!--
+ document.forms['queryform'].content.focus();
+ // -->
+ </script>
+ </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>
+
+ [% IF Param('search_allow_no_criteria') %]
+ <input type="submit" id="search" value="Search">
+ [% ELSE %]
+ <input type="submit" id="search" value="Search"
+ onclick="if (this.form.content.value == '')
+ {alert('The Words field cannot be empty. You have to ' +
+ 'enter at least one word in your search criteria.');
+ return false;} return true;">
+ [% END %]
+ </td>
+ </tr>
+</table>
+</form>
+
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/search/tabs.html.tmpl b/template/en/default/search/tabs.html.tmpl
new file mode 100644
index 0000000..f7703fd
--- /dev/null
+++ b/template/en/default/search/tabs.html.tmpl
@@ -0,0 +1,23 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # This template has no interface.
+ #%]
+
+[% WRAPPER global/tabs.html.tmpl
+ tabs = [ { name => 'specific', label => "Simple Search",
+ link => "query.cgi?format=specific" },
+ { name => 'advanced', label => "Advanced Search",
+ link => "query.cgi?format=advanced" } ]
+ current_tab_name = query_format || format || "advanced"
+%]
+
+[% content %]
+
+[% END %]
diff --git a/template/en/default/search/type-select.html.tmpl b/template/en/default/search/type-select.html.tmpl
new file mode 100644
index 0000000..b4affbb
--- /dev/null
+++ b/template/en/default/search/type-select.html.tmpl
@@ -0,0 +1,18 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+
+<select name="[% name FILTER html %]" title="Search type"
+ class="[% class FILTER css_class_quote %]">
+ [% FOREACH type = types %]
+ <option value="[% type FILTER html %]"
+ [%- ' selected="selected"' IF type == selected %]>
+ [%- search_descs.$type FILTER html %]</option>
+ [% END %]
+</select>
diff --git a/template/en/default/setup/strings.txt.pl b/template/en/default/setup/strings.txt.pl
new file mode 100644
index 0000000..d134ef4
--- /dev/null
+++ b/template/en/default/setup/strings.txt.pl
@@ -0,0 +1,417 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This Source Code Form is "Incompatible With Secondary Licenses", as
+# defined by the Mozilla Public License, v. 2.0.
+
+# This file contains a single hash named %strings, which is used by the
+# installation code to display strings before Template-Toolkit can safely
+# be loaded.
+#
+# Each string supports a very simple substitution system, where you can
+# have variables named like ##this## and they'll be replaced by the string
+# variable with that name.
+#
+# Please keep the strings in alphabetical order by their name.
+
+%strings = (
+ any => 'any',
+ apachectl_failed => <<END,
+WARNING: We could not check the configuration of Apache. This sometimes
+happens when you are not running checksetup.pl as ##root##. To see the
+problem we ran into, run: ##command##
+END
+ bad_executable => 'not a valid executable: ##bin##',
+ blacklisted => '(blacklisted)',
+ bz_schema_exists_before_220 => <<'END',
+You are upgrading from a version before 2.20, but the bz_schema table
+already exists. This means that you restored a mysqldump into the Bugzilla
+database without first dropping the already-existing Bugzilla database,
+at some point. Whenever you restore a Bugzilla database backup, you must
+always drop the entire database first.
+
+Please drop your Bugzilla database and restore it from a backup that does
+not contain the bz_schema table. If for some reason you cannot do this, you
+can connect to your MySQL database and drop the bz_schema table, as a last
+resort.
+END
+ checking_for => 'Checking for',
+ checking_dbd => 'Checking available perl DBD modules...',
+ checking_optional => 'The following Perl modules are optional:',
+ checking_modules => 'Checking perl modules...',
+ chmod_failed => '##path##: Failed to change permissions: ##error##',
+ chown_failed => '##path##: Failed to change ownership: ##error##',
+ commands_dbd => <<EOT,
+YOU MUST RUN ONE OF THE FOLLOWING COMMANDS (depending on which database
+you use):
+EOT
+ commands_optional => 'COMMANDS TO INSTALL OPTIONAL MODULES:',
+ commands_required => <<EOT,
+COMMANDS TO INSTALL REQUIRED MODULES (You *must* run all these commands
+and then re-run checksetup.pl):
+EOT
+ continue_without_answers => <<'END',
+Re-run checksetup.pl in interactive mode (without an 'answers' file)
+to continue.
+END
+ cpan_bugzilla_home =>
+ "WARNING: Using the Bugzilla directory as the CPAN home.",
+ db_enum_setup => "Setting up choices for standard drop-down fields:",
+ db_schema_init => "Initializing bz_schema...",
+ db_table_new => "Adding new table ##table##...",
+ db_table_setup => "Creating tables...",
+ done => 'done.',
+ enter_or_ctrl_c => "Press Enter to continue or Ctrl-C to exit...",
+ error_localconfig_read => <<'END',
+An error has occurred while reading the ##localconfig## file. The text of
+the error message is:
+
+##error##
+
+Please fix the error in the localconfig file. Alternately, rename your
+localconfig file and re-run checksetup.pl to have it create a new
+localconfig file:
+
+ $ mv -f localconfig localconfig.old
+ $ ./checksetup.pl
+END
+ extension_must_return_name => <<END,
+##file## returned ##returned##, which is not a valid name for an extension.
+Extensions must return their name, not <code>1</code> or a number. See
+the documentation of Bugzilla::Extension for details.
+END
+ feature_auth_ldap => 'LDAP Authentication',
+ feature_auth_radius => 'RADIUS Authentication',
+ feature_graphical_reports => 'Graphical Reports',
+ feature_html_desc => 'More HTML in Product/Group Descriptions',
+ feature_inbound_email => 'Inbound Email',
+ feature_jobqueue => 'Mail Queueing',
+ feature_jsonrpc => 'JSON-RPC Interface',
+ feature_jsonrpc_faster => 'Make JSON-RPC Faster',
+ feature_new_charts => 'New Charts',
+ feature_old_charts => 'Old Charts',
+ feature_mod_perl => 'mod_perl',
+ feature_moving => 'Move Bugs Between Installations',
+ feature_patch_viewer => 'Patch Viewer',
+ feature_smtp_auth => 'SMTP Authentication',
+ feature_smtp_ssl => 'SSL Support for SMTP',
+ feature_updates => 'Automatic Update Notifications',
+ feature_xmlrpc => 'XML-RPC Interface',
+ feature_detect_charset => 'Automatic charset detection for text attachments',
+ feature_typesniffer => 'Sniff MIME type of attachments',
+
+ file_remove => 'Removing ##name##...',
+ file_rename => 'Renaming ##from## to ##to##...',
+ header => "* This is Bugzilla ##bz_ver## on perl ##perl_ver##\n"
+ . "* Running on ##os_name## ##os_ver##",
+ install_all => <<EOT,
+
+To attempt an automatic install of every required and optional module
+with one command, do:
+
+ ##perl## install-module.pl --all
+
+EOT
+ install_data_too_long => <<EOT,
+WARNING: Some of the data in the ##table##.##column## column is longer than
+its new length limit of ##max_length## characters. The data that needs to be
+fixed is printed below with the value of the ##id_column## column first and
+then the value of the ##column## column that needs to be fixed:
+
+EOT
+ install_module => 'Installing ##module## version ##version##...',
+ installation_failed => '*** Installation aborted. Read the messages above. ***',
+ install_no_compiler => <<END,
+ERROR: Using install-module.pl requires that you install a compiler, such as
+gcc.
+END
+ install_no_make => <<END,
+ERROR: Using install-module.pl requires that you install "make".
+END
+ lc_new_vars => <<'END',
+This version of Bugzilla contains some variables that you may want to
+change and adapt to your local settings. The following variables are
+new to ##localconfig## since you last ran checksetup.pl:
+
+##new_vars##
+
+Please edit the file ##localconfig## and then re-run checksetup.pl
+to complete your installation.
+END
+ lc_old_vars => <<'END',
+The following variables are no longer used in ##localconfig##, and
+have been moved to ##old_file##: ##vars##
+END
+ localconfig_create_htaccess => <<'END',
+If you are using Apache as your web server, Bugzilla can create .htaccess
+files for you, which will keep this file (localconfig) and other
+confidential files from being read over the web.
+
+If this is set to 1, checksetup.pl will create .htaccess files if
+they don't exist.
+
+If this is set to 0, checksetup.pl will not create .htaccess files.
+END
+ localconfig_cvsbin => <<'END',
+If you want to use the CVS integration of the Patch Viewer, please specify
+the full path to the "cvs" executable here.
+END
+ localconfig_db_check => <<'END',
+Should checksetup.pl try to verify that your database setup is correct?
+With some combinations of database servers/Perl modules/moonphase this
+doesn't work, and so you can try setting this to 0 to make checksetup.pl
+run.
+END
+ localconfig_db_driver => <<'END',
+What SQL database to use. Default is mysql. List of supported databases
+can be obtained by listing Bugzilla/DB directory - every module corresponds
+to one supported database and the name of the module (before ".pm")
+corresponds to a valid value for this variable.
+END
+ localconfig_db_host => <<'END',
+The DNS name or IP address of the host that the database server runs on.
+END
+ localconfig_db_name => <<'END',
+The name of the database. For Oracle, this is the database's SID. For
+SQLite, this is a name (or path) for the DB file.
+END
+ localconfig_db_pass => <<'END',
+Enter your database password here. It's normally advisable to specify
+a password for your bugzilla database user.
+If you use apostrophe (') or a backslash (\) in your password, you'll
+need to escape it by preceding it with a '\' character. (\') or (\)
+(It is far simpler to just not use those characters.)
+END
+ localconfig_db_port => <<'END',
+Sometimes the database server is running on a non-standard port. If that's
+the case for your database server, set this to the port number that your
+database server is running on. Setting this to 0 means "use the default
+port for my database server."
+END
+ localconfig_db_sock => <<'END',
+MySQL Only: Enter a path to the unix socket for MySQL. If this is
+blank, then MySQL's compiled-in default will be used. You probably
+want that.
+END
+ localconfig_db_user => "Who we connect to the database as.",
+ localconfig_diffpath => <<'END',
+For the "Difference Between Two Patches" feature to work, we need to know
+what directory the "diff" bin is in. (You only need to set this if you
+are using that feature of the Patch Viewer.)
+END
+ localconfig_index_html => <<'END',
+Most web servers will allow you to use index.cgi as a directory
+index, and many come preconfigured that way, but if yours doesn't
+then you'll need an index.html file that provides redirection
+to index.cgi. Setting $index_html to 1 below will allow
+checksetup.pl to create an index.html for you if it doesn't exist.
+NOTE: checksetup.pl will not replace an existing file, so if you
+ wish to have checksetup.pl create one for you, you must
+ make sure that index.html doesn't already exist.
+END
+ localconfig_interdiffbin => <<'END',
+If you want to use the "Difference Between Two Patches" feature of the
+Patch Viewer, please specify the full path to the "interdiff" executable
+here.
+END
+ localconfig_site_wide_secret => <<'END',
+This secret key is used by your installation for the creation and
+validation of encrypted tokens. These tokens are used to implement
+security features in Bugzilla, to protect against certain types of attacks.
+A random string is generated by default. It's very important that this key
+is kept secret. It also must be very long.
+END
+ localconfig_use_suexec => <<'END',
+Set this to 1 if Bugzilla runs in an Apache SuexecUserGroup environment.
+
+If your web server runs control panel software (cPanel, Plesk or similar),
+or if your Bugzilla is to run in a shared hosting environment, then you are
+almost certainly in an Apache SuexecUserGroup environment.
+
+If this is a Windows box, ignore this setting, as it does nothing.
+
+If set to 0, checksetup.pl will set file permissions appropriately for
+a normal webserver environment.
+
+If set to 1, checksetup.pl will set file permissions so that Bugzilla
+works in a SuexecUserGroup environment.
+END
+ localconfig_webservergroup => <<'END',
+The name of the group that your web server runs as. On Red Hat
+distributions, this is usually "apache". On Debian/Ubuntu, it is
+usually "www-data".
+
+If you have use_suexec turned on below, then this is instead the name
+of the group that your web server switches to to run cgi files.
+
+If this is a Windows machine, ignore this setting, as it does nothing.
+
+If you do not have access to the group your scripts will run under,
+set this to "". If you do set this to "", then your Bugzilla installation
+will be _VERY_ insecure, because some files will be world readable/writable,
+and so anyone who can get local access to your machine can do whatever they
+want. You should only have this set to "" if this is a testing installation
+and you cannot set this up any other way. YOU HAVE BEEN WARNED!
+
+If you set this to anything other than "", you will need to run checksetup.pl
+as ##root## or as a user who is a member of the specified group.
+END
+ max_allowed_packet => <<EOT,
+WARNING: You need to set the max_allowed_packet parameter in your MySQL
+configuration to at least ##needed##. Currently it is set to ##current##.
+You can set this parameter in the [mysqld] section of your MySQL
+configuration file.
+EOT
+ min_version_required => "Minimum version required: ",
+
+# Note: When translating these "modules" messages, don't change the formatting
+# if possible, because there is hardcoded formatting in
+# Bugzilla::Install::Requirements to match the box formatting.
+ modules_message_apache => <<END,
+***********************************************************************
+* APACHE MODULES *
+***********************************************************************
+* Normally, when Bugzilla is upgraded, all Bugzilla users have to *
+* clear their browser cache or Bugzilla will break. If you enable *
+* certain modules in your Apache configuration (usually called *
+* httpd.conf or apache2.conf) then your users will not have to clear *
+* their caches when you upgrade Bugzilla. The modules you need to *
+* enable are: *
+* *
+END
+ modules_message_db => <<EOT,
+***********************************************************************
+* DATABASE ACCESS *
+***********************************************************************
+* In order to access your database, Bugzilla requires that the *
+* correct "DBD" module be installed for the database that you are *
+* running. See below for the correct command to run to install the *
+* appropriate module for your database. *
+EOT
+ modules_message_optional => <<EOT,
+***********************************************************************
+* OPTIONAL MODULES *
+***********************************************************************
+* Certain Perl modules are not required by Bugzilla, but by *
+* installing the latest version you gain access to additional *
+* features. *
+* *
+* The optional modules you do not have installed are listed below, *
+* with the name of the feature they enable. Below that table are the *
+* commands to install each module. *
+EOT
+ modules_message_required => <<EOT,
+***********************************************************************
+* REQUIRED MODULES *
+***********************************************************************
+* Bugzilla requires you to install some Perl modules which are either *
+* missing from your system, or the version on your system is too old. *
+* See below for commands to install these modules. *
+EOT
+
+ module_found => "found v##ver##",
+ module_not_found => "not found",
+ module_ok => 'ok',
+ module_unknown_version => "found unknown version",
+ no_such_module => "There is no Perl module on CPAN named ##module##.",
+ mysql_innodb_disabled => <<'END',
+InnoDB is disabled in your MySQL installation.
+Bugzilla requires InnoDB to be enabled.
+Please enable it and then re-run checksetup.pl.
+END
+ mysql_index_renaming => <<'END',
+We are about to rename old indexes. The estimated time to complete
+renaming is ##minutes## minutes. You cannot interrupt this action once
+it has begun. If you would like to cancel, press Ctrl-C now...
+(Waiting 45 seconds...)
+END
+ mysql_utf8_conversion => <<'END',
+WARNING: We are about to convert your table storage format to UTF-8. This
+ allows Bugzilla to correctly store and sort international characters.
+ However, if you have any non-UTF-8 data in your database,
+ it ***WILL BE DELETED*** by this process. So, before
+ you continue with checksetup.pl, if you have any non-UTF-8
+ data (or even if you're not sure) you should press Ctrl-C now
+ to interrupt checksetup.pl, and run contrib/recode.pl to make all
+ the data in your database into UTF-8. You should also back up your
+ database before continuing. This will affect every single table
+ in the database, even non-Bugzilla tables.
+
+ If you ever used a version of Bugzilla before 2.22, we STRONGLY
+ recommend that you stop checksetup.pl NOW and run contrib/recode.pl.
+END
+ no_checksetup_from_cgi => <<END,
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+ <head>
+ <title>checksetup.pl cannot run from a web browser</title>
+ </head>
+
+ <body>
+ <h1>checksetup.pl cannot run from a web browser</h1>
+ <p>
+ You <b>must not</b> execute this script from your web browser.
+ To install or upgrade Bugzilla, run this script from
+ the command-line (e.g. <tt>bash</tt> or <tt>ssh</tt> on Linux
+ or <tt>cmd.exe</tt> on Windows), and follow instructions given there.
+ </p>
+
+ <p>
+ For more information on how to install Bugzilla, please
+ <a href="http://www.bugzilla.org/docs/">read the documentation</a>
+ available on the official Bugzilla website.
+ </p>
+ </body>
+</html>
+END
+ patchutils_missing => <<'END',
+OPTIONAL NOTE: If you want to be able to use the 'difference between two
+patches' feature of Bugzilla (which requires the PatchReader Perl module
+as well), you should install patchutils from:
+
+ http://cyberelk.net/tim/patchutils/
+END
+ template_precompile => "Precompiling templates...",
+ template_removal_failed => <<END,
+WARNING: The directory '##template_cache##' could not be removed.
+ It has been moved into '##deleteme##', which should be
+ deleted manually to conserve disk space.
+END
+ template_removing_dir => "Removing existing compiled templates...",
+ update_cf_invalid_name =>
+ "Removing custom field '##field##', because it has an invalid name...",
+ update_flags_bad_name => <<'END',
+"##flag##" is not a valid name for a flag. Rename it to not have any spaces
+or commas.
+END
+ update_nomail_bad => <<'END',
+WARNING: The following users were listed in ##data##/nomail, but do
+not have an account here. The unmatched entries have been moved to
+##data##/nomail.bad:
+END
+ update_summary_truncate_comment =>
+ "The original value of the Summary field was longer than 255"
+ . " characters, and so it was truncated during an upgrade."
+ . " The original summary was:\n\n##summary##",
+ update_summary_truncated => <<'END',
+WARNING: Some of your bugs had summaries longer than 255 characters.
+They have had their original summary copied into a comment, and then
+the summary was truncated to 255 characters. The affected bug numbers were:
+END
+ update_quips => <<'END',
+Quips are now stored in the database, rather than in an external file.
+The quips previously stored in ##data##/comments have been copied into
+the database, and that file has been renamed to ##data##/comments.bak
+You may delete the renamed file once you have confirmed that all your
+quips were moved successfully.
+END
+ update_queries_to_tags => "Populating the new 'tag' table:",
+ webdot_bad_htaccess => <<END,
+WARNING: Dependency graph images are not accessible.
+Delete ##dir##/.htaccess and re-run checksetup.pl.
+END
+);
+
+1;
diff --git a/template/en/default/welcome-admin.html.tmpl b/template/en/default/welcome-admin.html.tmpl
new file mode 100644
index 0000000..0f7626c
--- /dev/null
+++ b/template/en/default/welcome-admin.html.tmpl
@@ -0,0 +1,77 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # none
+ #%]
+
+[% title = BLOCK %]Welcome to [% terms.Bugzilla %][% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+ header_addl_info = "version $constants.BUGZILLA_VERSION"
+ style_urls = [ 'skins/standard/index.css' ]
+%]
+
+<div id="welcome-admin">
+ <p>Welcome, [% user.identity FILTER html %].</p>
+
+ <p>You are seeing this page because some of the core parameters have not been set up yet.
+ The goal of this page is to inform you about the last steps required to set up
+ your installation correctly.</p>
+
+ <p>As an administrator, you have access to all administrative pages, accessible from
+ the <a href="admin.cgi">Administration</a> link visible at the bottom of this page.
+ This link will always be visible, on all pages. From there, you must visit at least
+ the <a href="editparams.cgi">Parameters</a> page, from where you can set all important
+ parameters for this installation; among others:</p>
+
+ <ul>
+ <li><a href="editparams.cgi?section=core#urlbase_desc">urlbase</a>, which is the URL
+ pointing to this installation and which will be used in emails (which is also the
+ reason you see this page: as long as this parameter is not set, you will see this
+ page again and again).</li>
+
+ <li><a href="editparams.cgi?section=core#cookiepath_desc">cookiepath</a> is important
+ for your browser to manage your cookies correctly.</li>
+
+ <li><a href="editparams.cgi?section=general#maintainer_desc">maintainer</a>,
+ the person responsible for this installation if something is
+ running wrongly.</li>
+ </ul>
+
+ <p>Also important are the following parameters:</p>
+
+ <ul>
+ <li><a href="editparams.cgi?section=auth#requirelogin_desc">requirelogin</a>, if turned
+ on, will protect your installation from users having no account on this installation.
+ In other words, users who are not explicitly authenticated with a valid account
+ cannot see any data. This is what you want if you want to keep your data private.</li>
+
+ <li><a href="editparams.cgi?section=auth#createemailregexp_desc">createemailregexp</a>
+ defines which users are allowed to create an account on this installation. If set
+ to ".*" (the default), everybody is free to create his own account. If set to
+ "@mycompany.com$", only users having an account @mycompany.com will be allowed to
+ create an account. If left blank, users will not be able to create accounts themselves;
+ only an administrator will be able to create one for them. If you want a private
+ installation, you must absolutely set this parameter to something different from
+ the default.</li>
+
+ <li><a href="editparams.cgi?section=mta#mail_delivery_method_desc">mail_delivery_method</a>
+ defines the method used to send emails, such as sendmail or SMTP. You have to set
+ it correctly to send emails.</li>
+ </ul>
+
+ <p>
+ After having set up all this, we recommend looking at [% terms.Bugzilla %]'s other
+ parameters as well at some time so that you understand what they do and whether you
+ want to modify their settings for your installation.
+ </p>
+</div>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/whine/mail.html.tmpl b/template/en/default/whine/mail.html.tmpl
new file mode 100644
index 0000000..b581d68
--- /dev/null
+++ b/template/en/default/whine/mail.html.tmpl
@@ -0,0 +1,80 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # subject: subject line of message
+ # body: message body, shown before the query tables
+ # queries: array of hashes containing:
+ # bugs: array containing hashes of fieldnames->values for each bug
+ # title: the title given in the whine scheduling mechanism
+ # name: the name of the query
+ # columnlist: array of fieldnames to display in the mail
+ # author: user object for the person who scheduled this whine
+ # recipient: user object for the intended recipient of the message
+ #%]
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <title>
+ [[% terms.Bugzilla %]] [% subject FILTER html %]
+ </title>
+ </head>
+ <body bgcolor="#FFFFFF">
+
+ <pre>
+ [% body FILTER html %]
+ </pre>
+
+ <p align="left">
+ [% IF author.login == recipient.login %]
+ <a href="[%+ urlbase FILTER html %]editwhines.cgi">Click
+ here to edit your whine schedule</a>
+ [% ELSE %]
+ This search was scheduled by [% author.login FILTER html %].
+ [% END %]
+ </p>
+
+[% IF queries.size %]
+ [% FOREACH query=queries %]
+
+ <h2>[%+ query.title FILTER html %] ([% query.bugs.size %] [%+ terms.bugs %])</h2>
+
+ <table width="100%">
+ <tr>
+ <th align="left">ID</th>
+ [% FOREACH col = query.columnlist %]
+ [% NEXT IF col == 'bug_id' %]
+ <th align="left">[% field_descs.$col FILTER html %]</th>
+ [% END %]
+ </tr>
+
+ [% FOREACH bug=query.bugs %]
+ <tr>
+ <td align="left"><a href="[%+ urlbase FILTER html %]show_bug.cgi?id=
+ [%- bug.bug_id %]">[% bug.bug_id %]</a></td>
+ [% FOREACH col = query.columnlist %]
+ [% NEXT IF col == 'bug_id' %]
+ <td align="left">[% display_value(col, bug.$col) FILTER html %]</td>
+ [% END %]
+ </tr>
+ [% END %]
+ </table>
+
+ [% IF author.login == recipient.login %]
+ <p align="left">
+ <a href="[% urlbase FILTER html %]buglist.cgi?cmdtype=runnamed&amp;namedcmd=[% query.name FILTER uri %]">View as [% terms.bug %] list</a>
+ </p>
+ [% END %]
+ [% END %]
+[% ELSE %]
+
+ <h3>No [% terms.bugs %] were found that matched the search criteria.</h3>
+[% END %]
+ </body>
+</html>
diff --git a/template/en/default/whine/mail.txt.tmpl b/template/en/default/whine/mail.txt.tmpl
new file mode 100644
index 0000000..845869d
--- /dev/null
+++ b/template/en/default/whine/mail.txt.tmpl
@@ -0,0 +1,61 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # subject: subject line of message
+ # body: message body, shown before the query tables
+ # queries: array of hashes containing:
+ # bugs: array containing hashes of fieldnames->values for each bug
+ # title: the title given in the whine scheduling mechanism
+ # name: the name of the query
+ # columnlist: array of fieldnames to display in the mail
+ # author: user object for the person who scheduled this whine
+ # recipient: user object for the intended recipient of the message
+ #%]
+
+[% body %]
+
+[% IF author.login == recipient.login %]
+ To edit your whine schedule, visit the following URL:
+ [%+ urlbase %]editwhines.cgi
+[% ELSE %]
+ This search was scheduled by [% author.login %].
+[% END %]
+
+[% IF queries.size %]
+ [% FOREACH query=queries %]
+
+[%+ query.title +%] ([% query.bugs.size %] [%+ terms.bugs %])
+[%+ "-" FILTER repeat(query.title.length) %]
+
+ [% FOREACH bug=query.bugs %]
+ [% terms.Bug +%] [%+ bug.bug_id %]:
+ [%+ urlbase %]show_bug.cgi?id=[% bug.bug_id +%]
+ [% largest_title = 0 %]
+ [% FOREACH col = query.columnlist %]
+ [% NEXT IF col == 'bug_id' %]
+ [% IF field_descs.${col}.length > largest_title %]
+ [% largest_title = field_descs.${col}.length %]
+ [% END %]
+ [% END %]
+ [% FOREACH col = query.columnlist %]
+ [% NEXT IF col == 'bug_id' %]
+ [%+ " " FILTER repeat(largest_title - field_descs.${col}.length) %]
+ [% field_descs.$col %]: [% display_value($col, bug.$col) %]
+ [% END %]
+
+ [% END %]
+
+ [% IF author.login == recipient.login %]
+View as [% terms.bug %] list: [% urlbase %]buglist.cgi?cmdtype=runnamed&namedcmd=[% query.name FILTER uri %]
+ [% END %]
+ [% END %]
+[% ELSE %]
+
+ No [% terms.bugs %] were found that matched the search criteria.
+[% END %]
diff --git a/template/en/default/whine/multipart-mime.txt.tmpl b/template/en/default/whine/multipart-mime.txt.tmpl
new file mode 100644
index 0000000..d28f4ce
--- /dev/null
+++ b/template/en/default/whine/multipart-mime.txt.tmpl
@@ -0,0 +1,39 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # subject: subject line of message
+ # alternatives: array of hashes containing:
+ # type: MIME type
+ # content: verbatim content
+ # boundary: a string that has been generated to be a unique boundary
+ # recipient: user object for the intended recipient of the message
+ # from: Bugzilla system email address
+ #%]
+
+From: [% from %]
+To: [% recipient.email %]
+Subject: [[% terms.Bugzilla %]] [% subject %]
+MIME-Version: 1.0
+Content-Type: multipart/alternative; boundary="[% boundary %]"
+X-Bugzilla-Type: whine
+
+
+This is a MIME multipart message. It is possible that your mail program
+doesn't quite handle these properly. Some or all of the information in this
+message may be unreadable.
+
+
+[% FOREACH part=alternatives %]
+
+--[% boundary %]
+Content-type: [% part.type +%]
+
+[%+ part.content %]
+[%+ END %]
+--[% boundary %]--
diff --git a/template/en/default/whine/schedule.html.tmpl b/template/en/default/whine/schedule.html.tmpl
new file mode 100644
index 0000000..dd58fc5
--- /dev/null
+++ b/template/en/default/whine/schedule.html.tmpl
@@ -0,0 +1,432 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[%# INTERFACE:
+ # events: hash, keyed by event_id number. Values are anonymous hashes of:
+ # schedule: array of hashes containing schedule info:
+ # day: value in day column
+ # time: value selected in time column
+ # mailto_type: 0=user 1=group
+ # mailto: recipient's id (profile or group)
+ # queries: as with schedule, an anonymous array containing hashes of:
+ # name: the named query's name
+ # title: title to be displayed on the results
+ # sort: integer that sets execution order on named queries
+ #%]
+
+[% title = "Set up whining" %]
+[% PROCESS global/header.html.tmpl
+ title = title
+ style_urls = ['skins/standard/admin.css']
+ doc_section = "whining.html"
+%]
+
+<p>
+ "Whining" is when [% terms.Bugzilla %] executes a saved query at a regular interval
+ and sends the resulting list of [% terms.bugs %] via email.
+</p>
+
+<p>
+ To set up a new whine event, click "Add a new event." Enter a subject line
+ for the message that will be sent, along with a block of text that will
+ accompany the [% terms.bug %] list in the body of the message.
+</p>
+
+<p>
+ Schedules are added to an event by clicking on "Add a new schedule." A schedule
+ consists of a day, a time of day or interval of times
+ (e.g., every 15 minutes), and a target email address that may or may not be
+ alterable, depending on your privileges. Events may have more than one schedule
+ in order to run at multiple times or for different users.
+</p>
+
+<p>
+ Searches come from saved searches, which are created by executing a <a
+ href="query.cgi">search</a>, then telling [% terms.Bugzilla %] to remember
+ the search under a particular name. Add a query by clicking "Add a new
+ query", and select the desired saved search name under "Search" and add a
+ title for the [% terms.bug %] table. The optional number entered under
+ "Sort" will determine the execution order (lowest to highest) if multiple
+ queries are listed. If you check "One message per [% terms.bug %]," each [%
+ terms.bug %] that matches the search will be sent in its own email message.
+</p>
+
+<p>
+ All times are server local time ([% local_timezone FILTER html %]).
+</p>
+
+<form method="post" action="editwhines.cgi">
+[%# This hidden submit button must be here to set default behavior when
+ the user presses return on a form input field #%]
+<input type="submit" value="Update / Commit" name="commit"
+ style="display: none;" id="commit">
+<input type="hidden" name="update" value="1">
+<input type="hidden" name="token" value="[% token FILTER html %]">
+
+[% FOREACH event = events %]
+
+<table cellspacing="2" cellpadding="2" style="border: 1px solid;">
+ <tr>
+ <th align="left">
+ Event:
+ </th>
+ <td align="right" colspan="2">
+ <input type="submit" value="Remove Event"
+ name="remove_event_[% event.key %]"
+ id="remove_event_[% event.key %]">
+ </td>
+ </tr>
+
+ <tr>
+ <td valign="top" align="right">
+ Email subject line:
+ </td>
+ <td colspan="2">
+ <input type="text" name="event_[% event.key %]_subject"
+ size="60" maxlength="128" value="
+ [%- event.value.subject FILTER html %]">
+ </td>
+ </tr>
+
+ <tr>
+ <td valign="top" align="right">
+ Descriptive text sent within whine message:
+ </td>
+ <td colspan="2">
+ [% INCLUDE global/textarea.html.tmpl
+ name = "event_${event.key}_body"
+ minrows = 3
+ maxrows = 10
+ defaultrows = 5
+ cols = 80
+ defaultcontent = event.value.body
+ %]
+ </td>
+ </tr>
+
+ <tr>
+ <td valign="top" align="right">
+ Send a message even if there are no [% terms.bugs %] in the search result:
+ </td>
+ <td colspan="2">
+ <input type="checkbox" name="event_[% event.key %]_mailifnobugs"
+ [%- IF event.value.mailifnobugs == 1 %] checked [% END %]>
+ </td>
+ </tr>
+
+ [% IF event.value.schedule.size == 0 %]
+
+ <tr>
+ <td valign="top" align="right">
+ Schedule:
+ </td>
+ <td class="unset" colspan="2">
+ Not scheduled to run<br>
+ <input type="submit" value="Add a new schedule"
+ name="add_schedule_[% event.key %]"
+ id="add_schedule_[% event.key %]">
+ </td>
+ </tr>
+
+ [% ELSE %]
+
+ <tr>
+ <td valign="top" align="right">
+ Schedule:
+ </td>
+ <td class="set" colspan="2">
+
+ <table>
+ <tr>
+ <th>
+ Interval
+ </th>
+ <th>
+ [% IF mail_others %]
+ Mail to
+ [% END %]
+ </th>
+ <th>
+ </th>
+ </tr>
+ [% FOREACH schedule = event.value.schedule %]
+ <tr>
+ <td align="left">
+
+ [%# these hidden fields allow us to compare old values instead
+ of reading the database to tell if a field has changed %]
+
+ <input type="hidden" value="[% schedule.day FILTER html %]"
+ name="orig_day_[% schedule.id %]">
+ <input type="hidden" value="[% schedule.time FILTER html %]"
+ name="orig_time_[% schedule.id %]">
+ [% PROCESS day_field val=schedule.day %]
+ [% PROCESS time_field val=schedule.time %]
+ </td>
+ <td align="left">
+ [% IF mail_others %]
+ <input type="hidden" name="orig_mailto_type_[% schedule.id %]"
+ value="[% schedule.mailto_type FILTER html %]">
+ <select name="mailto_type_[% schedule.id %]">
+ <option value="0" [% IF schedule.mailto_type == 0 %]
+ selected
+ [% END %]>User</option>
+ <option value="1" [% IF schedule.mailto_type == 1 %]
+ selected
+ [% END %]>Group</option>
+ </select>
+ <input type="hidden" name="orig_mailto_[% schedule.id %]"
+ value="[% schedule.mailto FILTER html %]">
+ <input type="text" name="mailto_[% schedule.id %]"
+ value="[% schedule.mailto FILTER html %]" size="30">
+ [% END %]
+ </td>
+ <td align="left">
+ <input type="submit" value="Remove"
+ name="remove_schedule_[% schedule.id %]"
+ id="remove_schedule_[% schedule.id %]">
+ </td>
+ </tr>
+ [% END %]
+
+ <tr>
+ <td colspan="3">
+ <input type="submit" value="Add a new schedule"
+ name="add_schedule_[% event.key %]"
+ id="add_schedule_[% event.key %]">
+ </td>
+ </tr>
+ </table>
+
+ </td>
+ </tr>
+
+ [% END %]
+
+ [% IF event.value.queries.size == 0 %]
+
+ <tr>
+ <td valign="top" align="right">
+ Searches:
+ </td>
+ <td align="left">
+ No searches <br>
+ <input type="submit" value="Add a new query"
+ name="add_query_[% event.key %]"
+ id="add_query_[% event.key %]">
+ </td>
+ <td align="right" valign="bottom">
+ <input type="submit" value="Update / Commit" name="commit" id="update">
+ </td>
+ </tr>
+
+ [% ELSE %]
+
+ <tr>
+ <td valign="top" align="right">
+ Searches:
+ </td>
+ <td align="left" colspan="2">
+
+ <table>
+ <tr>
+ <th>Sort</th>
+ <th>Search</th>
+ <th>Title</th>
+ <th></th>
+ <th></th>
+ </tr>
+
+ [% FOREACH query = event.value.queries %]
+
+ <tr>
+ <td align="left">
+ <input type="text" name="query_sort_[% query.id %]"
+ size="3" value="[% query.sort %]">
+ <input type="hidden" value="[% query.sort %]"
+ name="orig_query_sort_[% query.id %]">
+ </td>
+ <td align="left">
+ <input type="hidden" value="[% query.name FILTER html %]"
+ name="orig_query_name_[% query.id %]">
+ [% PROCESS query_field thisquery=query.name %]
+ </td>
+ <td align="left">
+ <input type="hidden" value="[% query.title FILTER html %]"
+ name="orig_query_title_[% query.id %]">
+ <input type="text" name="query_title_[% query.id %]"
+ size="50" value="[% query.title FILTER html %]"
+ maxlength="64">
+ </td>
+ <td align="left">
+ <input type="hidden" value="[% query.onemailperbug FILTER html %]"
+ name="orig_query_onemailperbug_[% query.id %]">
+ <input type="checkbox" [% IF query.onemailperbug == 1 %] checked [% END %]
+ id="query_onemailperbug_[% query.id %]"
+ name="query_onemailperbug_[% query.id %]">
+ <label for="query_onemailperbug_[% query.id %]">One message per [% terms.bug %]</label>
+ </td>
+ <td align="right">
+ <input type="submit" value="Remove"
+ name="remove_query_[% query.id %]"
+ id="remove_query_[% query.id %]">
+ </td>
+ </tr>
+
+ [% END %]
+
+ <tr>
+ <td colspan="3">
+ <input type="submit" value="Add a new query"
+ name="add_query_[% event.key %]"
+ id="add_query_[% event.key %]">
+ </td>
+ <td align="right" colspan="2">
+ <input type="submit" value="Update / Commit" name="commit" id="update">
+ </td>
+ </tr>
+ </table>
+
+ </td>
+ </tr>
+
+ [% END %]
+
+</table>
+
+[% END %]
+
+<p align="left">
+ <input type="submit" value="Add a new event" name="add_event" id="add_event">
+</p>
+
+</form>
+
+[% PROCESS global/footer.html.tmpl %]
+
+[% BLOCK query_field +%]
+
+ [% IF available_queries.size > 0 %]
+
+ <select name="query_name_[% query.id %]">
+ [% FOREACH q = available_queries %]
+ <option [% "selected" IF q == thisquery %] value="[% q FILTER html %]">
+ [% q FILTER html %]
+ </option>
+ [% END %]
+ </select>
+
+ [% ELSE %]
+ Please visit the <a href="query.cgi">Search</a> page and save a query
+ [% END %]
+
+[%+ END %]
+
+[% BLOCK day_field +%]
+ <select name="day_[% schedule.id %]">
+ [%
+ options = [
+ ['All', 'Each day', ],
+ ['MF', 'Monday through Friday', ],
+ ['Sun', 'Sunday', ],
+ ['Mon', 'Monday', ],
+ ['Tue', 'Tuesday', ],
+ ['Wed', 'Wednesday', ],
+ ['Thu', 'Thursday', ],
+ ['Fri', 'Friday', ],
+ ['Sat', 'Saturday', ],
+ ['1', 'On the 1st of the month', ],
+ ['2', 'On the 2nd of the month', ],
+ ['3', 'On the 3rd of the month', ],
+ ['4', 'On the 4th of the month', ],
+ ['5', 'On the 5th of the month', ],
+ ['6', 'On the 6th of the month', ],
+ ['7', 'On the 7th of the month', ],
+ ['8', 'On the 8th of the month', ],
+ ['9', 'On the 9th of the month', ],
+ ['10', 'On the 10th of the month', ],
+ ['11', 'On the 11th of the month', ],
+ ['12', 'On the 12th of the month', ],
+ ['13', 'On the 13th of the month', ],
+ ['14', 'On the 14th of the month', ],
+ ['15', 'On the 15th of the month', ],
+ ['16', 'On the 16th of the month', ],
+ ['17', 'On the 17th of the month', ],
+ ['18', 'On the 18th of the month', ],
+ ['19', 'On the 19th of the month', ],
+ ['20', 'On the 20th of the month', ],
+ ['21', 'On the 21st of the month', ],
+ ['22', 'On the 22nd of the month', ],
+ ['23', 'On the 23rd of the month', ],
+ ['24', 'On the 24th of the month', ],
+ ['25', 'On the 25th of the month', ],
+ ['26', 'On the 26th of the month', ],
+ ['27', 'On the 27th of the month', ],
+ ['28', 'On the 28th of the month', ],
+ ['29', 'On the 29th of the month', ],
+ ['30', 'On the 30th of the month', ],
+ ['31', 'On the 31st of the month', ],
+ ['last', 'Last day of the month', ],
+ ]
+ %]
+
+ [% FOREACH option = options %]
+ <option value="[% option.0 %]"
+ [%- IF val == option.0 +%] selected[% END %]>
+ [%- option.1 -%]
+ </option>
+ [% END %]
+
+ </select>
+[%+ END %]
+
+[% BLOCK time_field +%]
+<select name="time_[% schedule.id %]">
+
+ [%
+ options = [
+ [ '0', 'at midnight', ],
+ [ '1', 'at 01:00', ],
+ [ '2', 'at 02:00', ],
+ [ '3', 'at 03:00', ],
+ [ '4', 'at 04:00', ],
+ [ '5', 'at 05:00', ],
+ [ '6', 'at 06:00', ],
+ [ '7', 'at 07:00', ],
+ [ '8', 'at 08:00', ],
+ [ '9', 'at 09:00', ],
+ [ '10', 'at 10:00', ],
+ [ '11', 'at 11:00', ],
+ [ '12', 'at 12:00', ],
+ [ '13', 'at 13:00', ],
+ [ '14', 'at 14:00', ],
+ [ '15', 'at 15:00', ],
+ [ '16', 'at 16:00', ],
+ [ '17', 'at 17:00', ],
+ [ '18', 'at 18:00', ],
+ [ '19', 'at 19:00', ],
+ [ '20', 'at 20:00', ],
+ [ '21', 'at 21:00', ],
+ [ '22', 'at 22:00', ],
+ [ '23', 'at 23:00', ],
+ [ '60min', 'every hour', ],
+ [ '30min', 'every 30 minutes', ],
+ [ '15min', 'every 15 minutes', ],
+ ]
+ %]
+
+ [% FOREACH option = options %]
+ <option value="[% option.0 %]"
+ [%- IF val == option.0 +%] selected[% END %]>
+ [%- option.1 -%]
+ </option>
+ [% END %]
+
+</select>
+
+[%+ END %]