]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 349369: Allow unused custom fields to be deleted from editfields.cgi - Patch...
authorlpsolit%gmail.com <>
Wed, 6 Feb 2008 22:15:34 +0000 (22:15 +0000)
committerlpsolit%gmail.com <>
Wed, 6 Feb 2008 22:15:34 +0000 (22:15 +0000)
Bugzilla/DB.pm
Bugzilla/Field.pm
docs/xml/administration.xml
editfields.cgi
template/en/default/admin/custom_fields/edit.html.tmpl
template/en/default/admin/custom_fields/list.html.tmpl
template/en/default/global/messages.html.tmpl
template/en/default/global/user-error.html.tmpl

index 4a0303287d73d05046152ab238eefd8a23889288..6763da06bc4373e82c21b885dd402328a65b5ef5 100644 (file)
@@ -687,6 +687,13 @@ sub bz_add_field_tables {
 
 }
 
+sub bz_drop_field_tables {
+    my ($self, $field) = @_;
+    if ($field->type == FIELD_TYPE_MULTI_SELECT) {
+        $self->bz_drop_table('bug_' . $field->name);
+    }
+    $self->bz_drop_table($field->name);
+}
 
 sub bz_drop_column {
     my ($self, $table, $column) = @_;
index 5ad5e51d3fad6c7a63c147258c8d6d6cabab5a52..5272f0ed679b88ac998ef4c37b5ca30aecc47814 100644 (file)
@@ -415,6 +415,89 @@ sub set_in_new_bugmail { $_[0]->set('mailhead',    $_[1]); }
 
 =pod
 
+=head2 Instance Method
+
+=over
+
+=item C<remove_from_db>
+
+Attempts to remove the passed in field from the database.
+Deleting a field is only successful if the field is obsolete and
+there are no values specified (or EVER specified) for the field.
+
+=back
+
+=cut
+
+sub remove_from_db {
+    my $self = shift;
+    my $dbh = Bugzilla->dbh;
+
+    my $name = $self->name;
+
+    if (!$self->custom) {
+        ThrowCodeError('field_not_custom', {'name' => $name });
+    }
+
+    if (!$self->obsolete) {
+        ThrowUserError('customfield_not_obsolete', {'name' => $self->name });
+    }
+
+    $dbh->bz_start_transaction();
+
+    # Check to see if bug activity table has records (should be fast with index)
+    my $has_activity = $dbh->selectrow_array("SELECT COUNT(*) FROM bugs_activity
+                                      WHERE fieldid = ?", undef, $self->id);
+    if ($has_activity) {
+        ThrowUserError('customfield_has_activity', {'name' => $name });
+    }
+
+    # Check to see if bugs table has records (slow)
+    my $bugs_query = "";
+
+    if ($self->type == FIELD_TYPE_MULTI_SELECT) {
+        $bugs_query = "SELECT COUNT(*) FROM bug_$name";
+    }
+    else {
+        $bugs_query = "SELECT COUNT(*) FROM bugs WHERE $name IS NOT NULL
+                                AND $name != ''";
+        # Ignore the default single select value
+        if ($self->type == FIELD_TYPE_SINGLE_SELECT) {
+            $bugs_query .= " AND $name != '---'";
+        }
+        # Ignore blank dates.
+        if ($self->type == FIELD_TYPE_DATETIME) {
+            $bugs_query .= " AND $name != '00-00-00 00:00:00'";
+        }
+    }
+
+    my $has_bugs = $dbh->selectrow_array($bugs_query);
+    if ($has_bugs) {
+        ThrowUserError('customfield_has_contents', {'name' => $name });
+    }
+
+    # Once we reach here, we should be OK to delete.
+    $dbh->do('DELETE FROM fielddefs WHERE id = ?', undef, $self->id);
+
+    my $type = $self->type;
+
+    # the values for multi-select are stored in a seperate table
+    if ($type != FIELD_TYPE_MULTI_SELECT) {
+        $dbh->bz_drop_column('bugs', $name);
+    }
+
+    if ($type == FIELD_TYPE_SINGLE_SELECT
+        || $type == FIELD_TYPE_MULTI_SELECT)
+    {
+        # Delete the table that holds the legal values for this field.
+        $dbh->bz_drop_field_tables($self);
+    }
+
+    $dbh->bz_commit_transaction()
+}
+
+=pod
+
 =head2 Class Methods
 
 =over
index 6a692c2640eefe9c9e77041334e915a5cd636741..b7897215d5b871799f92abadd9b88a0f2510a71d 100644 (file)
@@ -1679,10 +1679,10 @@ foo: ENTRY, MANDATORY/MANDATORY, CANEDIT
       <title>Deleting Custom Fields</title>
 
       <para>
-        At this point, it is not possible to delete custom fields from
-        your web browser. If you don't want to make one available anymore,
-        mark it as obsolete. This way, you will preserve your DB
-        referential integrity.
+        It is only possible to delete obsolete custom fields 
+        if the field has never been used in the database.
+        If you want to remove a field which already has content,
+        mark it as obsolete.
       </para>
     </section>
   </section>
index 50564c19094a1d5f43c74d62f1368951dde85619..138c6b72959baba9462a2f57de6e44b5f9715e45 100644 (file)
@@ -117,6 +117,49 @@ elsif ($action eq 'update') {
     $template->process('admin/custom_fields/list.html.tmpl', $vars)
         || ThrowTemplateError($template->error());
 }
+elsif ($action eq 'del') {
+    my $name = $cgi->param('name');
+
+    # Validate field.
+    $name || ThrowUserError('field_missing_name');
+    # Custom field names must start with "cf_".
+    if ($name !~ /^cf_/) {
+        $name = 'cf_' . $name;
+    }
+    my $field = new Bugzilla::Field({'name' => $name});
+    $field || ThrowUserError('customfield_nonexistent', {'name' => $name});
+
+    $vars->{'field'} = $field;
+    $vars->{'token'} = issue_session_token('delete_field');
+
+    $template->process('admin/custom_fields/confirm-delete.html.tmpl', $vars)
+            || ThrowTemplateError($template->error());
+}
+elsif ($action eq 'delete') {
+    check_token_data($token, 'delete_field');
+    my $name = $cgi->param('name');
+
+    # Validate fields.
+    $name || ThrowUserError('field_missing_name');
+    # Custom field names must start with "cf_".
+    if ($name !~ /^cf_/) {
+        $name = 'cf_' . $name;
+    }
+    my $field = new Bugzilla::Field({'name' => $name});
+    $field || ThrowUserError('customfield_nonexistent', {'name' => $name});
+
+    # Calling remove_from_db will check if field can be deleted.
+    # If the field cannot be deleted, it will throw an error.
+    $field->remove_from_db();
+    
+    $vars->{'field'}   = $field;
+    $vars->{'message'} = 'custom_field_deleted';
+    
+    delete_token($token);
+
+    $template->process('admin/custom_fields/list.html.tmpl', $vars)
+        || ThrowTemplateError($template->error());
+}
 else {
     ThrowUserError('no_valid_action', {'field' => 'custom_field'});
 }
index 596e7e704eb49be59cb7b8eb860bc54337b6dc9f..02334ab13b9199cd9d3b2680e1a3d63c6d083c7a 100644 (file)
   <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>
index acb3f680d35a205c757a75772db4d07fdb69ace2..6f2e68be73a4b4f11a8948209f5a266ee84e2277 100644 (file)
@@ -24,6 +24,8 @@
   doc_section = "custom-fields.html"
 %]
 
+[% delete_contentlink = BLOCK %]editfields.cgi?action=del&amp;name=%%name%%[% END %]
+
 [% columns = [
      {
        name => "name"
      {
        name => "obsolete"
        heading => "Is Obsolete"
+     },
+     {
+       name => "action"
+       heading => "Action"
+       content => ""
      }
    ]
 %]
   %]
 [% END %]
 
+
+[% overrides.action = [ {
+     match_value => 1
+     match_field => 'obsolete'
+     override_content => 1
+     content => "Delete"
+     override_contentlink => 1
+     contentlink => delete_contentlink
+   } ]
+%] 
+
 [% PROCESS admin/table.html.tmpl
      columns = columns
      overrides = overrides
index 007aab4d4f47d3558eb11c1e7cd16d0701c52245..dfa4f78f46207040346ac98bf728934c0cc031bb 100644 (file)
     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
index 73d0f1d1fb74e69b4e33317a085b37a57124330a..8b3b5e20e22faf486c01a682914400d088132410 100644 (file)
     [% 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"