I can't track down why this is happening but it's very frustrating.

Steps to reproduce:

  • Create a feature based on a custom node type.
  • Then on a separate site, copy over the feature and enable it at admin/build/features
  • Disable the feature
  • Navigate to admin/content/types

The node type that was created by the feature is still listed there, but there is no 'delete' button next to it. You have to manually navigate to admin/content/node-type/[typename]/delete to get it to go away (where [typename] is the machine name of the node type).

Comments

Anonymous’s picture

I think the issue is that node types generated through enabling of the Feature are not considered 'custom'.. note that this bug occurs even when the feature is enabled and the node type is created (as opposed to the idea that it's just when one disables the feature that the Delete button disappears)

The magic around what node types have the 'Delete' link seems to happen around line 31 of content_types.inc in the node module in Drupal 6.13

      // Set the delete column.
      if ($type->custom) {
        $row[] = array('data' => l(t('delete'), 'admin/content/node-type/'. $type_url_str .'/delete'));
      }
      else {
        $row[] = array('data' => '');
      }

(as a test removing this check forces the 'Delete' link to appear on the Feature-generated node)

How to set the node type as 'custom' is beyond me, I am trying to work out how to export that as a parameter where the node type is defined in the 'module' that Features generates. Hopefully these are some clues for the developers.

Anonymous’s picture

Found a solution

Edit your $feature.defaults.inc, find the implementation of hook_node_info
Add an attribute to the array 'custom' => '1'

i.e:

/**
 * Helper to implemetation of hook_node_info().
 */
function _product_site_node_info() {
  $items = array(
    'product' => array(
      'name' => t('Product'),
      'module' => 'node',
      'description' => t(''),
      'has_title' => '1',
      'title_label' => t('Product Name'),
      'has_body' => '0',
      'body_label' => t(''),
      'custom' =>'1',
   ),
  );
  return $items;
}

I then installed this feature on a new test site (could've just reinstalled the feature on the same site I spose, but I wanted to test on a completely fresh db where the node type didn't already exist etc) and the 'Delete' button appears.

Hope it helps

Anonymous’s picture

Status: Active » Patch (to be ported)
StatusFileSize
new635 bytes

Here's a patch for HEAD that works for me.

Hope it's ok (it's the first patch I've ever submitted :) )

Anonymous’s picture

Status: Patch (to be ported) » Active

I guess it doesn't address the issue's title of the node type not being removed when the feature is disabled. Maybe this should be two separate issues.

yhahn’s picture

Status: Active » Needs review
StatusFileSize
new2.25 KB

So some sleuthing reveals that the node module has some special logic for node types with node as the value for their module key:

    // Check for node types from disabled modules and mark their types for removal.
    // Types defined by the node module in the database (rather than by a separate
    // module using hook_node_info) have a module value of 'node'.
    if ($type_object->module != 'node' && empty($info_array[$type_object->type])) {
      $type_object->disabled = TRUE;
    }

The fix I'd like to try out is to delegate the hooks provided by the node module for custom content types to the features module for any node types provided by features (see node_content_access(), node_perm() and node_content_form.

I've attached a patch that does just this - the key change is that any exported content types now use 'features' instead of 'node' in their module key. You can update your features using drush or the UI, or if you want to do it by hand do this:

/**
 * Helper to implementation of hook_node_info().
 */
function _myfeature_node_info() {
  $items = array(
    'blog' => array(
      'name' => t('Blog post'),
 -    'module' => 'node',
 +    'module' => 'features',
...

I'd love to get some testing with this before I commit the change.

Anonymous’s picture

I might be doing something wrong.. I installed a fresh site (via Aegir), downloaded features and patched it as above, built a new feature with a simple new node type and applied this feature on another fresh site, that also had the features module patched just in case.

The implementation of hook_node_info does define the 'module' as 'features' as above,

/**
 * Helper to implemetation of hook_node_info().
 */
function _test_node_info() {
  $items = array(
    'test_node' => array(
      'name' => t('Test  Node'),
      'module' => 'features',
      'description' => t(''),
      'has_title' => '1',
      'title_label' => t('Title'),
      'has_body' => '1',
      'body_label' => t('Body'),
    ),
  );
  return $items;
}

but under Content Types on the site I deployed the new feature on, the delete option is still missing until I add 'custom' => '1' to that array and refresh.

Should I be testing this not on the latest stable but HEAD or something? Though the patch did apply cleanly.

Maybe I'm misunderstanding, if so please let me know if there's anything specific you'd like me to try - I'm very keen to help out testing and have lots of resources to do so :)

Anonymous’s picture

However, disabling the feature does now remove that node type, so your fix correctly addresses this issue's title (just not the 'delete' node option that was mentioned in the body, that my patch addressed). sorry for complicating the ticket as these are really two separate issues I guess.

yhahn’s picture

You actually shouldn't be able to delete the feature's content type unless you've overridden it (edit it and save). And if the content type is being removed when the feature is disabled, then it's working as intended : )

Anonymous’s picture

Status: Needs review » Reviewed & tested by the community
q0rban’s picture

Sorry, I just realized I wasn't subscribed to the issues on this module. I'll test this out soon.

q0rban’s picture

Tested, and works as described! leaving as RTBC

q0rban’s picture

The only nice addition would be to have a hook_update_N call that actually changes what's in the node_type table... It doesn't appear that just manually changing a feature to 'module' => 'features' actually updates anything, and features UI doesn't mark it as overridden either. You either have to manually delete the node type, or edit the node_type table manually to change module to features.

Jackinloadup’s picture

subscribing

a_c_m’s picture

ran into this as well, subscribing.

q0rban’s picture

Version: 6.x-1.0-alpha5 » 6.x-1.x-dev
Status: Reviewed & tested by the community » Needs review
StatusFileSize
new3.26 KB

Adding an update call to fix any node types from previous features. This update can be re-run if need be.

yhahn’s picture

Status: Needs review » Fixed

Thanks everyone - committed: http://drupal.org/cvs?commit=261548

q0rban’s picture

Just looked at the code that was committed for this, and think I see a problem:

Line 34 of features.install

    if (module_exists($feature->name) && $types = module_invoke($feature->name, 'node_info')) {

Shouldn't this be:

    if (module_exists($feature->name) && ($types = module_invoke($feature->name, 'node_info'))) {

From my experience, if you don't wrap that in parentheses, $types will be a boolean value.

yhahn’s picture

It's probably best practice to do so (wrap in parens) but believe it or not if the variable assignment is last in the if(), it will work (but if you switch the order $types will indeed be the boolean).

q0rban’s picture

Ah, good to know! :)

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.