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.
| Comment | File | Size | Author |
|---|---|---|---|
| #51 | 202404-181019.png | 32.61 KB | avpaderno |
| #47 | After_patch.png | 44.33 KB | vikashsoni |
| #45 | added_existing_content_type_as_an existing_orig_type.png | 14.65 KB | kotoponus |
| #40 | node_type_disappears_if_its_type_has_already_been_used(7.34)-515454-40.patch | 1.26 KB | thedut |
| #36 | screenshot_node_type_issue2.png | 30.16 KB | thedut |
Issue fork drupal-515454
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
Comment #1
gpk commentedLet's see what testbot makes of this..
Comment #3
mackh commentedRerolled
Comment #4
mackh commentedThis needs to be tested before we commit this....
Comment #5
jim0203 commentedThe 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:
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:
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.
Comment #6
sunI 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.
Comment #7
jim0203 commentedAs 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:
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.
Comment #8
gpk commented@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.Comment #9
jim0203 commentedThose 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.
Comment #10
sunReading 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.
Comment #11
gpk commented@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!
Comment #12
sunRight. And that's the part that needs to merged into the patch in #10. Plus tests.
Comment #13
gpk commentedHmmm http://api.drupal.org/api/function/node_schema/6 defines orig_type as follows:
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!
Comment #14
jim0203 commentedChanging status.
Comment #15
sun#10: drupal.node-type-orig.patch queued for re-testing.
Comment #16
sunI 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.
Comment #17
mrfelton commentedSubscribe. I'm now left with an unusable namespace, that I want to use.
Comment #18
larowlanUpdating version so this gets on the radar
Comment #19
larowlanComments 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).
Comment #20
thedut commentedHere is the patch for the validation node type for drupal 6.22.
Comment #22
thedut commentedMy first patch, ... creating a patch is not so easy.
Comment #23
thedut commentedHere 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.
Comment #24
thedut commentedComment #25
thedut commentedHere 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.
Comment #26
thedut commentedHere is the patch for drupal 6.25.
This bug exists on D5, D6, D7 and D8 !
Patch for D7 and D8 below.
Comment #27
thedut commentedHere 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.
Comment #28
thedut commentedHere 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.
Comment #29
thedut commentedUpdating version to the current Drupal major release.
Comment #30
albert volkman commentedThis needs to be resolved upstream first to limit regression.
Comment #31
albert volkman commented*bump*
Comment #32
thedut commentedFor 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 !
Comment #35
thedut commentedTested 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.
Comment #36
thedut commentedHere 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 :
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.
Comment #37
thedut commentedComment #38
thedut commentedComment #39
thedut commentedPatch for Drupal 6.34
Comment #40
thedut commentedPatch for Drupal 7.34
Comment #41
thedut commentedComment #43
thedut commentedComment #44
thedut commentedI have create a distinct issue for Drupal 6 :
https://www.drupal.org/node/2397793
Comment #45
kotoponus commentedI 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:
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!)
Comment #46
vikashsoni commentedComment #47
vikashsoni commented@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
Comment #48
thedut commentedHello vikashsoni,
I guess that thanks to the #40 patch you get your nodes back.
The work arround to come back to test1 is :
The patch is still interessting because it prevents from loosing an entire content type !
I guess you could mark this issue as "reviewed".
Comment #49
avpadernoI can confirm this is still an issue on the latest 7.x branch.
Comment #51
avpadernoI tested my MR on simplytest.me. It fixes the issue reported here.