Scenario: rename the "type" of a node type, such that the new "type" is alphabetically after the original. Create a new node type whose machine "type" is the same as the original type of the one that has been renamed.

This node type is not listed on the Create content page, nor can it be edited/deleted etc.

The culprit looks to be http://api.drupal.org/api/function/_node_types_build/6 which at the bottom has

      if ($type_object->type != $type_object->orig_type) {
        unset($_node_types[$type_object->orig_type]);
        unset($_node_names[$type_object->orig_type]);
      }

TBH I'm not sure what this code is trying to achieve. It went in to Drupal 5 as part of the patch that gave us configurable node types (http://cvs.drupal.org/viewvc.py/drupal/drupal/modules/node/node.module?v..., #62340: Pave the way for CCK). I've had a quick look through that issue but it would take a bit of time to track down the rational, if stated there.

I wonder if simply removing these lines would work? What would it break? In my case I have a node type currently of type "event_0" that originally had type "event" (yeah, the one created by event.module, that s.o. else installed on the site ;-) ). Had kind of forgotten about it and created a new type "event". What makes this all particularly nasty is that it is only because my new type "event" gets processed before "event_0" that the latter is able to trash it. And if I rename "event_0" to come alphabetically before "event" then indeed my new type does show up, after clearing caches.

Problem also appears to affect 5.x and 7.x.

Issue fork drupal-515454

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

gpk’s picture

Version: 6.10 » 7.x-dev
Status: Active » Needs review
StatusFileSize
new608 bytes

Let's see what testbot makes of this..

Status: Needs review » Needs work

The last submitted patch failed testing.

mackh’s picture

Status: Needs work » Needs review
StatusFileSize
new1022 bytes

Rerolled

mackh’s picture

This needs to be tested before we commit this....

jim0203’s picture

StatusFileSize
new2.13 KB

The problem is certainly there and it's there for the reason stated: the four lines near the end of the function that look like this:

if ($type_object->type != $type_object->orig_type) {
        unset($_node_types->types[$type_object->orig_type]);
        unset($_node_types->names[$type_object->orig_type]);
      }

Imagine that node type with machine type "page" has had its type changed to "zpage", and then a new node type is create with machine type "page". This function parses through all the available machine types alphabetically, so it hits the new "page" first and adds it to $_node_types. Eventually it hits "zpage", and adds that to $_node_types. But then the "if" statement above is triggered and it goes back and unsets what it had added to $_node_types under page.

I think you're right that these lines should be removed, as I can't work out when they would actually be useful. This isn't helped by the complete absence of code comments so I've attached a new patch which both removes the two lines of code and adds some comments.

Here's the argument, though:

$_node_types is reset on line 668. Then nodes which are created using hook_node_info in some module are added to $_node_types on lines 670-675:

$info_array = module_invoke_all('node_info');
  foreach ($info_array as $type => $info) {
    $info['type'] = $type;
    $_node_types->types[$type] = node_type_set_defaults($info);
    $_node_types->names[$type] = $info['name'];
  }

Next the database is queried for all the node types in the node_type table. This is so that node types which haven't shown up in some hook_node_info but are still in the node_type table can be marked as disabled - I think the disabling/deletion is done by node_types_rebuild. At the same time, any node types which aren't created by a module are added to $_node_types.

Finally, the function goes through each node type in the database and, if its machine type has been changed, it removes any reference to the original machine type from $_node_types. But because of the way the function is constructed, it's impossible that the original machine type would have been used incorrectly.

I don't want to spend any time going through the CVS records to work out why this was originally done, but it would be interesting to hear from anyone who can work it out. For the moment, though, I think the argument is clear so those lines should be removed.

sun’s picture

Status: Needs review » Needs work

I like the added comments, but I think the bug is elsewhere. The condition clearly expects that type == orig_type. Hence, orig_type was not updated after type was renamed. Hence, we need to make it update orig_type.

jim0203’s picture

As far as I could see from stepping through this code, those lines didn't serve a purpose. Any idea what they are supposed to do, or why they were originally added? I think that might be the quickest way to get to the bottom of this.

EDIT:

we need to make it update orig_type

Unless I'm missing something, orig_type is never updated: it's the original type of a node created by core or a module, and is stored in the node_type table in the database.

gpk’s picture

@7: my hunch was that those lines were a sort of "mistake" that slipped through somehow..

BTW you have added an extra space after this comment:
// check prevents errors on old (pre-Drupal 7) databases.

jim0203’s picture

Those lines were definitely added on purpose, but since the commenting in the code is non-existent I can't tell what that purpose is supposed to be!

I've posted on the issue that originally gave us this code, to try and ping the people that were working on it - but since that was three years ago it's doubtful any of them will remember what the code is supposed to do.

I'll have a bit more of a look at this later and try and follow the logic through. And I'll sort the extra white space out in the next patch - tks.

sun’s picture

Status: Needs work » Needs review
StatusFileSize
new1.86 KB

Reading the patch in #62340-162: Pave the way for CCK, I think those lines are trying to do what I briefly explained in #6 already.

1) We want to add those comments.

2) But I think the added comments are partially wrong.

3) And we additionally want to fix the underlying issue I mentioned in #6.

4) And we need tests.

New patch with proper comments to use as base for further patches.

gpk’s picture

@10: Are you saying that the "mysterious" lines are to avoid problems with a race condition? i.e. if you rename a node type then this could take some time since lots of nodes might need their type column updating... during this time http://api.drupal.org/api/function/_node_types_build/6 should only return the "new" type...

I think I must be missing something because this doesn't make sense to me:
- firstly, _node_types_build() won't return the "original" type anyway once the updated row has been written to {node_type} by http://api.drupal.org/api/function/node_type_save/6
- secondly, orig_type sounds like it should mean just that - the original type, not temporary storage of the previous name of the node type during a rename
- thirdly it doesn't work consistently anyway, as described above at #5 and in my original post; and as you say, orig_type would then also need to be cleared once the rename is finished

Maybe we need to do a grep of core (and contrib?) and see where else orig_type is used?

Hope I'm not just confusing the issue!

sun’s picture

thirdly it doesn't work consistently anyway, as described above at #5 and in my original post; and as you say, orig_type would then also need to be cleared once the rename is finished

Right. And that's the part that needs to merged into the patch in #10. Plus tests.

gpk’s picture

Hmmm http://api.drupal.org/api/function/node_schema/6 defines orig_type as follows:

'description' => 'The original machine-readable name of this node type. This may be different from the current type name if the locked field is 0.',

which seems inconsistent with our proposed approach :P

Also I've found a "proper" (i.e. one that makes sense to me ;) ) usage of orig_type, in http://api.drupal.org/api/function/node_type_reset/6,

However I'm not sure even that makes complete sense, my suspicion is that you can change the machine-readable name iff "locked" == 0, while the Reset node type option is available iff "locked" != 0, i.e. Resetting a node type will never cause its name to change.

Again, hope I'm not just confusing the issue!

jim0203’s picture

Status: Needs review » Needs work

Changing status.

sun’s picture

Status: Needs work » Needs review

#10: drupal.node-type-orig.patch queued for re-testing.

sun’s picture

I still have this patch in my file system, so let's get this fixed. Any takers? At the very least, we want to commit the comments added in #10.

mrfelton’s picture

Subscribe. I'm now left with an unusable namespace, that I want to use.

larowlan’s picture

Version: 7.x-dev » 8.x-dev

Updating version so this gets on the radar

larowlan’s picture

Status: Needs review » Needs work

Comments from #10 look fine to include.
To do: we need to add some validation to the node types form that tests the machine name 'type' field against the existing 'old types' for when creating a new node type and throws an error if it already exists otherwise the new node type is never usable (without changing the old_type in the db).

thedut’s picture

Version: 8.x-dev » 6.22
Status: Needs work » Needs review
StatusFileSize
new1.29 KB

Here is the patch for the validation node type for drupal 6.22.

Status: Needs review » Needs work

The last submitted patch, node_type_form_validate.patch, failed testing.

thedut’s picture

My first patch, ... creating a patch is not so easy.

thedut’s picture

Here is the patch for the validation node type, checking the orig_type value, for drupal 6.22 (retry).
it edits the node_type_form_validate() function.
EDIT : both patches are indentical, I have uploaded it twice by mistake.

thedut’s picture

Status: Needs work » Needs review
thedut’s picture

Version: 6.22 » 6.24
StatusFileSize
new1.45 KB

Here is the correct patch (on drupal 6.24).
Comparing to my previous patch, it allows a content type to switch back to its origin type value.

thedut’s picture

Version: 6.24 » 6.25
StatusFileSize
new1.48 KB

Here is the patch for drupal 6.25.

This bug exists on D5, D6, D7 and D8 !
Patch for D7 and D8 below.

thedut’s picture

Version: 6.25 » 7.12
StatusFileSize
new1.26 KB

Here is the patch for drupal 7.12.

This bug exists on D5, D6, D7 and D8 !
Patch for D6 in my previous post.
Patch for D8 below.

thedut’s picture

Version: 7.12 » 8.x-dev
StatusFileSize
new1.28 KB

Here is the patch for drupal 8x-dev.

This bug exists on D5, D6, D7 and D8 !
Patch for D6 and D7 in my previous posts.

thedut’s picture

Version: 8.x-dev » 7.12

Updating version to the current Drupal major release.

albert volkman’s picture

Version: 7.12 » 8.x-dev

This needs to be resolved upstream first to limit regression.

albert volkman’s picture

*bump*

thedut’s picture

For your information, I have contributed the LimeSurvey Sync module : It contains the fix for that issue for Drupal 6 and Drupal 7 : All you have to do is to download it and enable the module LimeSurvey Sync Survey (no need to install the LimeSurvey software).

Note : On Drupal 8 this issue causes a fatal error !

Status: Needs review » Needs work
thedut’s picture

Version: 8.0.x-dev » 7.x-dev

Tested on drupal 8.0.0-beta4 : This issue does not exists anymore, since the 'orig_type' is not used on Drupal 8.
Unfortunately, this issue still exists on Drupal 7 and 6,
So I have changed the issue version to 7.x-dev.
I will prepare a patch for the 7.34 version.

thedut’s picture

StatusFileSize
new103.89 KB
new30.16 KB

Here is a full description of this issue, that affects Drupal 5, 6 and 7 :
Drupal 8 is not affected anymore.

When creating a new content type with a type that has already used, the new (or the old) content type disappear everywhere.
The only way to make it back is to delete the dooblon directly into the database.

Steps to reproduce this issue :

  1. go to admin/structure/types/add and create a new content type with machine name (type) = 'test1'.
  2. save it
  3. go to admin/structure/types/manage/test1 and edit the machine name (type) from 'test1' to 'test2' (and edit the human name to).
  4. save it
  5. go to admin/structure/types/add and create a new content type with machine name (type) = 'test1'.
  6. --> the new content type with machine name 'test1' does not appear but it has been created and is present and enabled into the database : see screenshots.

This issue appears because the node_type_form_validate() function does not check for dooblons on the node type orig_type value.

Patches below for Drupal 7.34 and 6.34.

thedut’s picture

Title: Node type cannot be used (sometimes) if its "type" is the same as another node type's "original type" » Node type disappears if its "type" has already be used (same orig_type)
thedut’s picture

Title: Node type disappears if its "type" has already be used (same orig_type) » Node type disappears if its "type" has already been used (same orig_type)
thedut’s picture

thedut’s picture

thedut’s picture

Status: Needs work » Needs review

thedut’s picture

thedut’s picture

I have create a distinct issue for Drupal 6 :
https://www.drupal.org/node/2397793

kotoponus’s picture

I am glad I came across this ticket. Experiencing the same problem in D7.39. Applied #40, and then did the following:

1. Created a new content type "Test A" (machine name: test_a)
2. Updated the name and machine name to: "Test B" and "test_b"
3. Attempted to create a new content type "Test A"

And it gave me the following:

added_existing_content_type_as_an existing_orig_type.png

It seems to behave as thedut intended in the patch. (Although it would have been great if I can actually create a new test_a after the first one!)

vikashsoni’s picture

vikashsoni’s picture

StatusFileSize
new44.33 KB

@thedut i have applied the patch

---- Create a content type with test1 and save and edit it and rename test2 with machine name also

---- now go to create another content type with test1 name so i am getting following error and not able to create content type with test1 name

thedut’s picture

Hello vikashsoni,

I guess that thanks to the #40 patch you get your nodes back.
The work arround to come back to test1 is :

  • either to delete test2 content type from the user interface, But you will loose all your nodes definitively ! So you probably don't want that !
  • or to edit the 'origin_type' value for test2 into the node_type database table from: 'test1 to test2, using PhpMyAdmin for instance.

The patch is still interessting because it prevents from loosing an entire content type !
I guess you could mark this issue as "reviewed".

avpaderno’s picture

I can confirm this is still an issue on the latest 7.x branch.

avpaderno’s picture

StatusFileSize
new32.61 KB

I tested my MR on simplytest.me. It fixes the issue reported here.

screenshot

Status: Needs review » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.