Make WordPress Core

Opened 2 years ago

Last modified 2 years ago

#56171 new defect (bug)

Unexpected behaviour and data loss with a post type called 'link' and Link Manager plugin active

Reported by: manfcarlo's profile manfcarlo Owned by:
Milestone: Awaiting Review Priority: normal
Severity: critical Version:
Component: Taxonomy Keywords: close
Focuses: Cc:

Description (last modified by sabernhardt)

Steps to reproduce:

  1. Install a fresh site (this will be easier to reproduce if the posts table has a low auto_increment value)
  2. Install the Link Manager plugin (prior to version 3.5 this plugin was not required)
  3. Register a post type called link (you can use the default args)

3. Observe that "Link Categories" is added under the newly registered post type in the admin menu

  1. Publish a post through the link post type and take note of its numeric ID
  2. Add enough links through the Link Manager until you reach the same numeric ID observed in step 4 (if it's a fresh site it shouldn't be too many)
  3. Assign a link category to the link with the same numeric ID observed in step 4

7. Go back to the link post type and observe that the published post has received the link category that was assigned to the link in step 6

  1. Now delete the post permanently

9. Go back to the Link Manager and observe that the link has lost its category that was assigned in step 6

This bug is caused because the taxonomy link_category is registered for the string link. (See code)

Interestingly, the function register_taxonomy_for_object_type rejects any string that is not registered as a post type. Of course, if the same check were included for immediate registration through register_taxonomy, link categories could not exist at all.

I discovered this while trying to get a clear answer on whether taxonomies were actually supported for non-post entities. I was nearly convinced they were not, until I noticed that link categories exist, and now it looks to me that no one knows the answer.

Change History (4)

#1 @manfcarlo
2 years ago

I can't edit the ticket description but (if it's a fresh site it shouldn't be too many) should actually be under point 5 not point 6.

#2 @sabernhardt
2 years ago

  • Description modified (diff)

#3 @peterwilsoncc
2 years ago

  • Keywords close added

link remains a reserved term in WordPress due to the link manager. Registering a post type with this name is expected to cause some strange behavior, especially if the Link Manager is active.

Instead of link, I recommend giving the post type a prefix; eg manfcarlo_link.

I'm inclined to close this as I don't think allowing the use of reserved terms is something that can be fixed.

#4 @manfcarlo
2 years ago

I think you're missing the point. The unexpected effects are not caused because link is on a disallowed list. They are caused because core specifies link as the object type for a taxonomy but does not register it as a post type.

That brings me back to this part:

Interestingly, the function register_taxonomy_for_object_type rejects any string that is not registered as a post type. Of course, if the same check were included for immediate registration through register_taxonomy, link categories could not exist at all.

If it is deemed acceptable for core to specify a string as the object type for a taxonomy without registering it as a post type, then why the early return?

One would expect that the $object_type parameter has an identical domain of accepted values for the register_taxonomy_for_object_type and register_taxonomy functions. Not only does the domain of accepted $object_type values differ between the two functions, but the difference in the domain of accepted values is practically undocumented, there is only one instance of core passing an $object_type to register_taxonomy that would not be accepted by register_taxonomy_for_object_type, and it's within a feature that has been hidden for 10 years.

These are some of the solution options that I can think of:

Option 1: Remove the early return from register_taxonomy_for_object_type and fully allow (and document) the use of taxonomies for non-post entities. This may seem appealingly simple, but note that the ultimate hiding of links in #21307 appears to have been catalysed by the proposal to convert links to a post type in #14339 and #18781. In other words, if plugins are to be invited to use taxonomies for non-post entities, core is not leading by example by coming very close to making its one and only usage of the feature redundant.

Option 2: Add the early return to register_taxonomy, explicitly disallow the use of taxonomies for non-post entities and convert links to a post type as was originally proposed. This is likely to be uncontroversial but it would be strange to upgrade a feature that remains hidden after 10 years.

Option 3: Add the early return to register_taxonomy, explicitly disallow the use of taxonomies for non-post entities and implement link categories in some clever way without using a taxonomy. This could potentially be an effective solution but also likely very costly to engineer for a low benefit.

Option 4: Add the early return to register_taxonomy, explicitly disallow the use of taxonomies for non-post entities and stop supporting the Link Manager. This would be simple but likely controversial.

Option 5: Add the early return to register_taxonomy, explicitly disallow the use of taxonomies for non-post entities but allow link as an explicit exception, e.g. if ( 'link' !== $object_type && ! get_post_type_object( $object_type ) ) return false;. I lean towards this option as it is a good balance between simple and effective.

With shared terms and global terms, taxonomies already have a history of feature discontinuation. I'm not familiar with the details of those discontinuations, particularly how legacy compatibility was handled, but if it can be done for shared terms and global terms, then why not for this?

Note: See TracTickets for help on using tickets.