This document describes additional functionality to be added to the Bugzilla bug tracking system. Definition ========== Currently, Bugzilla offers a fixed number of named fields to describe bugs. These fields are shared by every product in the system. The proposed additional functionality is the ability to define additional fields. These additional fields are called "custom fields". Each custom field has the following properties: * An internal name, consisting of from 1 to 255 alphanumeric characters, beginning with an alphabetic character. A field is unambiguously identified by its internal name, which must be unique among all other custom fields. In addition, no custom field may have the same name as an existing Bugzilla query parameter. * A display name, which is presented to users. There is no restriction on the characters which make up this name. * A type, one of Integer, String, Date, or Selection. * A scope, which is either a product or a field group (qv). Some field types have additional properties, as described below. Once created, a field's display name and type may be changed, but its internal name and scope may not--or at least, no such capability will be provided by the custom field administrator interface. The following sections describe each of the four field types. All scalar fields can be set to a special "undefined" value in additional to the valid values described below. Each section describes the default manner in which fields of that type are represented in a user's browser. An enterprising administrator may modify these defaults by editing the appropriate template(s). Integer ------- An integer custom field contains values which are integers. Such fields must be able to store at least the range of integers which are typically represented as a signed four-byte quantity. An Integer field is presented on Bugzilla's web interface as a single-line text form element. When a user enters text into an Integer form element, Bugzilla will signal an error condition if the text does not conform to the usual string format for integers (a sequence of digit characters optionally preceded by a plus or minus sign), or if the resulting number falls outside of the allowed range. Leading and trailing whitespace is trimmed from the text before the conversion to an integer is attempted. If no text remains after whitespace is trimmed, the field will be set to the undefined value. String ------ A String field contains text which is intended to be readable by humans. However, for i18n reasons, any binary data may be stored in a string field. Each string field is flagged as belonging to one of two varieties: short or long. A short string field can hold a maximum of 255 characters, and may contain no vertical whitespace characters. It is presented on Bugzilla's Web interface as a single-line text form element. A long string field can hold up to 65535 arbitrary characters. It is presented on Bugzilla's Web interface as a multiline textarea form element. If the users enters no text at all (including whitespace) into a String form element, the field will be set to the undefined value. Date ---- A Date field describes a particular moment of time. Each such field is of one of two varieties: date-only or date/time. On output, a date-only Date field is represented using the format 'YYYY-MM-DD'; a date/time Date field is represented using the format 'YYYY-MM-DD HH24:MI:SS'. When a user enters text into a Date form element, the text must be parseable by the Perl module Date::Parse. If the user enters no text at all, the field will be set to the undefined value. Bugzilla will signal an error condition if a user attempts to store an illegal date value in a date field. Selection --------- A selection field derives its value from a set of distinct string values, called the field's "value set" or "domain". No element of any Selection field's value set may contain vertical whitespace, begin or end with whitespace, or exceed 255 characters in length. Each selection field comes in one of two varieties: "single-selection" and "multiselection". A single-selection field's value is a subset of the field's value set of size either zero or one. It is represented on Bugzilla's web interface as a drop-down listbox form element. A field whose value is the empty set is represented on the Web interface by a special "unset" string which is defined when the field is created. A multiselection field's value is an arbitrary subset of the field's value set. It is represented on Bugzilla's web interface as a multiline listbox, seven lines in size, in which multiple selections are allowed. Field Groups ============ A field group is a named, ordered list of custom fields. A field group's name must be distinct from those of all other field groups. No custom field may belong to more than one field group. A field group may be assigned to one or more products. A product inherits the custom fields in all field groups that have been assigned to it. A special unnamed field group is provided by default. Fields in this global field group are inherited by all products. Each product contains an ordered list of children, each of which is either a custom field or a custom field group. When a full list of a product's custom fields is needed, the product's children are iterated over. If a child is a custom field, it is output; if it is a custom field group, the fields of that group are output in the order defined for that group. Logging ======= Whenever a user edits a bug and changes one or more custom fields, the changes must be logged. Every change to a bug must be tagged with a unique ID, so that it is possible to later determine which changes were made during the same transaction. Information logged with each transaction must include the identity of the user who made the changes and the date and time of the changes. The old and new values of each field modified during a transaction must be logged. When a bug's activity is shown, each of the transactions applied to it since its creation must be shown. Presentation ============ Custom fields are to be presented on each Bugzilla page that presents the standard Bugzilla fields. These pages include at least the following: On "show_bug.cgi" and "post_bug.cgi", the custom fields will be shown just prior to the list of attachments. On "enter_bug.cgi" and "long_list.cgi", the custom fields will be shown just after the "Description" text box. The Bugzilla administrator may edit Bugzilla's templates to display the custom fields at some other location on the page, or to display individual custom fields at chosen locations. The template for each page must be intelligent enough to display at the default location only those fields which have not been set to be displayed elsewhere on the page. When a bug is being created or edited, custom fields are represented as per the field type descriptions above. When a bug is being displayed but not edited, scalar fields and single-selection fields are represented as text inside a preformatted (
) block; multiselection fields are represented using unnamed multiline listboxes. The query.cgi page requires more extensive modifications. Currently query.cgi knows only about Bugzilla's standard fields. Since all components share the same set of standard fields, these fields can be displayed before the user has chosen a Product at the top of the page. To add the capability to search on custom fields, a straightforward approach would be to require the user to first specify the products within which to search, then display the usual query page augmented with the custom fields which exist in those products. However, this is too invasive for products which don't use custom fields, and also for queries which don't care about custom fields. Here is an alternate approach. Fields in the global field group are always displayed. A button is to be added to the query page, to the right of the "Product", "Component", and "Version" listboxes, labelled "Show custom fields for these products". If the user clicks it, the query form is redisplayed, augmented with all custom fields and custom field groups in all of the selected products. If no products were selected, or if no selected product has any custom fields, the page is simply redisplayed as it was before. The user may freely change the target products and press the "Show custom fields" button again. The query page will be redisplayed with new form elements for the most recently chosen products. If the user selects one or more target products, shows the custom fields in those products, changes the target products, and initiates a search without refreshing the custom fields, then form elements which are not associated with any of the newly-chosen products are ignored; other form elements--those that are associated with at least one of the old set of products and at least one of the new set of products--are treated normally. Custom fields are displayed in the following order: * First, fields in the first selected product; * Then, fields in the second product (if any) which are not shared with the first selected product; * Then, fields in the third product (if any) which are not shared with either of the first two products; ...and so on. No special precautions are made to distinguish custom fields that have the same display name; it is the responsibility of the administrator not to give fields identical display names. Custom string fields may be queried in the same manner as the stock fields "Comment" and "URL". That is, they may be matched against a user-supplied string using any of the following predicates: * contains all of the words/strings * contains any of the words/strings * contains the string * contains the string (exact case) * contains all of the words * contains any of the words * matches the regexp * doesn't match the regexp Custom integer fields may be queried against a user-supplied string (which must obey the proper format for Integers, as described above) using the following predicates: * is equal to * is less than * is greater than * is less than or equal to * is greater than or equal to Custom date fields may be queried against a user-supplied string which must be parseable by Date::Parse. The available predicates are: * is exactly * is at or earlier than * is at or later than If the user supplies a time component when querying against a date-only field, the time component is ignored. Custom single-selection selection fields may be queried against a multiline listbox containing the field's value set, one element per line. Multiple selections within this listbox are allowed. A bug matches this query term if this field's value is a subset of the user-selected values. Custom multiselection selection fields may be queried against a multiline listbox containing all valid values for the fields. Multiple selections within this listbox are allowed. A pair of radiobuttons is placed next to the listbox which present two choices: "Any" and "All". Initially, "Any" is selected. If the "Any" button is selected at the time the query is initiated, then a bug matches this query term if the intersection of the field's value and the user-selected values is nonempty. If the "All" button is selected instead, then a bug matches this query term if the field's value is a subset of the user-selected values. Administration ============== A new CGI program for managing custom fields, editcustomfields.cgi, will be created. The program is only accessible to the Bugzilla administrator. The initial page served by editcustomfields.cgi will present a pair of drop-down, single-selection listboxes, the first of which enumerates all existing products, and the second of which enumerates all existing field groups. A button underneath the first listbox is labelled "Edit this product"; a button under the second listbox is labelled "Edit this field group". Below all of these elements is a third button labelled "View custom fields in the global scope". If, for whatever reason, no products exist, then the product listbox and button are suppressed. If no field groups exist, then the groups listbox and button are suppressed. If no products were selected when the "Edit this product" button was pressed, or if no groups were selected when the "Edit this field group" button was pressed, the initial page is redisplayed. Otherwise, if the user pressed the "Edit this product" button, a page is presented which contains the following elements. See the accompanying file editcustomfields.html for a concrete visualization of the following page format. The product "Test Product" shown on this page contains five children: 1. A field group "String Group", containing a short string field "Short String Field" and a long string field "Long String Field". 2. A single-selection field "Single Selection Field". 3. A multiselection field "Multiselection Field". 4. An integer field "Integer Field". 5. A field group "Date Group", containing a date-only field "Date Field" and a date/time field "Date/Time Field". (Unshown as yet on this page is the internal name of each field.) First, a six-column table for describing each child of the selected product is shown, both fields and field groups. The first column is untitled; the others are "Name", "Type", "Default", and "Value Set". For every custom field, the Name column contains the display name of the field. The Type column contains one of the following strings: * string (short) * string (long) * selection (single) * selection (multiple) * integer * date * date (with time) The Default column describes the default value of the field. If a field has no default value, the content of this column is the italicized word "none". This includes multiselection fields whose default value is the empty set. Nontrivial multiselection field default values are presented via a multiline selection element; the default values of all other field types are text enclosed in a preformatted () block. The Value Set column is empty for all fields other than those of the Selection type. For such fields, the value set is presented via a multiline selection element. Fields which are members of field groups are grouped together in the table; they are collectively labelled with the name of their enclosing field group in the first, unnamed column. The field group name is a hyperlink that will take the administrator to a page for editing the fields in that field group, just as if the "Edit this field group" button had been pressed on the initial page. When the administrator edits a field group rather than a product, the editing interface is identical except that the first, unnamed column in the above table is omitted. Below the field table is a sequence of five HTML paragraphs. Each paragraph describes one operation that may be carried out, and includes appropriate form elements to specify the important parameters of the operation and a button to initiate the operation. The available operations include the following: * Edit one of the fields. * Insert a new field, of any type, at the beginning of the list, the end of the list, or between any two existing fields. * Move a field to a different position in the list. * Rename a field. * Remove a field. Fields which are members of field groups may not be edited from the "Edit this product" page; the administrator must edit such fields from the appropriate "Edit this field group" page. If a product has no unshared fields--that is, if all of its fields are members of field groups--then the "Edit", "Move", "Rename", and "Remove" paragraphs are suppressed. Pressing any of the buttons causes a new page to be displayed, as described below. Each of the pages includes a "Cancel" button, which will abort the operation and return the user to this page. Editing a custom field ---------------------- The only aspect of a string, integer, or date field that may be edited (other than its name, handled by a separate Rename operation) is its default value. Thus, the Edit page presents only a single form element for such fields: a multiline textarea element for long string fields, and a single-line text element for the others. Pressing the form's submit button initiates the change. The default value of a selection field may also be edited, via either a drop-down listbox element (for single-selection fields) or a multiline listbox element (for multiselection fields). In addition, the field's set of valid selection values may be edited. The field's value set is presented in a multiline textarea element, one element per line. The administrator is free to cut and paste elements around within the textarea, insert new values, or delete old values. Pressing the submit button on a selection field's Edit page initiates sanity checking as follows. * If any elements were removed from the field's value set, the administrator is warned that those elements will be removed from the value of that field in each bug. * If any of the field's default values were removed from the field's value set, the administrator is warned that the deleted values will be removed from the field's default value. If either of the above warnings are issued, the administrator must explicitly confirm that the operation should be carried out. Inserting a new field --------------------- For a new Integer or Date field, a single-line text element is provided into which the user may enter the new field's default value. When the user presses the page's "Create field" button, the field will be created, assuming the supplied default value is appropriate for the chosen field type. For a new String field, the first page presented includes only a pair of radiobuttons, labelled "Long string (multiline, up to 64K characters)" and "Short string (single line, up to 255 characters)". Pressing a "Continue field creation" button produces a page which allows the user to enter the field's default value, using an appropriate form element (single-line text element for short strings, multiline textarea element for long strings). A "Create field" button starts the field creation process. For a new Selection field, the first page presented includes a pair of radiobuttons, labelled "Single selection" and "Multiple selection". The page also includes a multiline textarea element into which the administrator may enter the field's value set, one element per line. Pressing the page's "Continue field creation" produces a second page which allows the administrator to select the field's default value, via either a drop-down listbox element (for single-selection fields) or a multiline listbox element (for multiselection fields). A second form element is provided for single-selection fields, a single-line text element into which the "unset" label for the field may be entered. (If the administrator did not enter any selection values before pressing the "Continue field creation" button, the first page is redisplayed with a warning.) A "Create field" button is provided on the second page. Pressing the "Create field" button in any of these cases initiates field creation. The field is added to every bug in the selected product--or every bug in the entire Bugzilla installation, if the field was created in the global scope. The field's value in every case is set to the new field's default value. In addition, the field ordering for the selected product (or global scope) is rearranged so that the new field will appear in the position specified by the administrator. Moving a field to a different position -------------------------------------- This action is performed immediately. The field ordering for the selected product (or for the global scope) is rearranged so that the fields and groups appear in the new order specified by the administrator. The initial editcustomfields.cgi page is redisplayed, showing the items in their new order. Since this action is easily reversible, no confirmation step is required. Rename a field -------------- A page is presented into which the user may enter the new name for the selected field into a single-line text element. Pressing a button labelled "Change field name" causes the field to assume the new name. The initial editcustomfields.cgi page is redisplayed, showing the selected field with its new name. Since this action is easily reversible, no confirmation step is required. Remove a field -------------- A page is presented which warns the administrator that deleting a custom field causes the irrecoverable loss of data. The number of bugs which will be affected by the removal operation is described. If the administrator pushes the "Confirm field removal" button, the field is expunged from the database.