Problem/Motivation

When e.g. creating a new content type e.g. 'article', and you create a pathauto pattern for the 'article' content type, the config for the pattern is still present when removing the content type.

Proposed resolution

  • Add a dependency to the config entity for the configured entity.
  • Add an update hook to fix this for existing config.
  • Test coverage.

Steps to reproduce

  1. Create a new content type, e.g. 'article'
  2. Enable pathauto
  3. Add a pathauto pattern for 'article'
  4. Remove the article content type.
  5. The pattern is still present in the configuration

Similar issue for rabbit hole: #2851441: Config for a specific content type is still available after deleting the content type.

CommentFileSizeAuthor
#3 3072876-2.patch2.72 KBidebr

Issue fork pathauto-3072876

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

JeroenT created an issue. See original summary.

jeroent’s picture

Issue summary: View changes
idebr’s picture

Status: Active » Needs review
StatusFileSize
new2.72 KB

Pathauto patterns are a little different compared to Rabbit hole behavior settings in the way that a Pathauto pattern without a node type condition is still a valid pattern, since the bundle field is optional and can have multiple values as well. This means it cannot outright be deleted when a node type is removed.

That being said, the pathauto pattern still requires updating when a dependency is removed. HEAD already merges the dependencies of its plugins, but the CTools node_type and entity_bundle plugins currently return an empty array in their ::calculateDependencies() method.

That leaves us with two options for adding these configuration dependencies:

  1. Calculate the configuration dependencies ourselves in \Drupal\pathauto\Entity\PathautoPattern::calculateDependencies()
  2. Patch the currently supported condition plugins: language (Core), node_type (Core, overwritten by Ctools), entity_bundle:* (CTools)

Option #2 has my preference, so we don't have a do additional work in Pathauto and remove it later when the condition plugins are correctly listing their dependencies.

Attached patch provides a proof-of-concept for #2 assuming a correct implementation of ::calculateDependencies() of the node_type condition plugin. I'll try to flesh this out a bit more at a later time.

berdir’s picture

> This means it cannot outright be deleted when a node type is removed.

That is technically true, but this is problematic. what happens if it's the last/only bundle? Does it mean the pattern is applied to no bundles or all bundles? entity reference fields in core now make a difference between NULL (all) and [] (none) for that.

An explicit test might be useful?

mably made their first commit to this issue’s fork.

mably’s picture

First try at throwing this issue at Claude.

Here's a summary of what was implemented:

PathautoPattern::calculateDependencies() — Now adds config dependencies for bundle entities referenced in entity_bundle selection conditions (e.g., node.type.article). Uses the standard EntityType::getBundleConfigDependency() method.

PathautoPattern::onDependencyRemoval() — New method that handles bundle deletion:

  • If a deleted bundle is one of several in a condition → removes just that bundle
  • If it was the last bundle → removes the entire condition
  • The pattern itself always survives (becomes a catch-all)
  • Returns TRUE so Drupal doesn't delete the pattern

4 kernel tests in PathautoPatternDependencyTest:

  1. Dependencies correctly include bundle config entities
  2. Removing one bundle from a multi-bundle condition updates the condition
  3. Removing the last bundle removes the condition entirely
  4. Pattern is never deleted, only updated
mably’s picture

May be we could at least disable the pattern if no condition are left.

All ideas welcome.

berdir’s picture

A pattern without conditions must be deleted or disabled, without condition it would be applied to anything. I think it would be fine to disable it, the UI should warn you that this is going to happen, doesn't seem different than other depending configuration, such the view/form displays and fields of a node type.

mably’s picture

Pattern is now disabled and a warning message displayed to the user.

mably’s picture

Assigned: Unassigned » berdir

Global summary

Pathauto patterns were not cleaned up when their corresponding content type (or other bundle entity) was deleted, leaving orphaned configuration in the system.

Problem

Pathauto patterns did not declare configuration dependencies on the bundles they reference in their selection conditions. This meant Drupal's configuration dependency system had no way to notify the pattern when a bundle was removed. Deleting a content type like "article" left its Pathauto pattern intact — and worse, the pattern silently became a catch-all applying to all nodes, since it no longer had any bundle condition to restrict it.

Fix

  • PathautoPattern.php — calculateDependencies(): Now iterates selection conditions looking for entity_bundle:* and node_type condition plugins, retrieves each referenced bundle's config dependency (e.g. node.type.article), and registers it. This hooks the pattern into Drupal's dependency tracking system.
  • PathautoPattern.php — onDependencyRemoval(): When a bundle entity is deleted, the pattern responds gracefully:
    • If the condition references multiple bundles: only the deleted bundle is removed from the condition.
    • If it was the last bundle: the entire condition is removed and the pattern is disabled (not deleted), with a warning message shown to the user.

Test coverage

  • PathautoPatternDependencyTest.php (new): Kernel test with four scenarios:
    • testCalculateDependenciesIncludesBundles() — verifies node.type.article and node.type.page appear in the pattern's config dependencies.
    • testRemoveSingleBundleFromMultiple() — deletes article from a two-bundle pattern, asserts only page remains in the condition and dependencies are updated.
    • testRemoveLastBundleRemovesCondition() — deletes the only bundle, asserts the condition is removed entirely.
    • testPatternNotDeletedOnBundleRemoval() — asserts the pattern still exists but is disabled after losing all bundle conditions.
berdir’s picture

Status: Needs review » Needs work

Reviewed.

mably’s picture

Thanks a lot @berdir for the review.

Implemented all your suggestions.

Created a new MR 163 to enable Tugboat and facilitate testing.

Added the newly created "Entity condition dependencies" core issue #3573747 to the list of related issue.

Review fixes

Addresses @berdir's review comments on MR !128:

PathautoPattern.php — calculateDependencies():

  • Removed the node_type condition check — this plugin was removed in Drupal 10.
  • Merged the bundle dependency logic into the existing getSelectionConditions() loop instead of iterating twice. Added a @todo noting that condition plugins should implement calculateDependencies() themselves (filed as #3573747).

PathautoPattern.php — onDependencyRemoval():

  • Removed the node_type condition check (same reason).
  • Removed the messenger()->addWarning() call that informed the user the pattern had been disabled. The delete confirmation form shows the pattern under "Configuration updates" before deletion, but this only indicates the pattern will be modified — not that it will be disabled. This is a trade-off: cleaner UX (no extra status message) at the cost of less explicit feedback. The user can still see the pattern is disabled on the patterns list page afterwards.

New test — PathautoPatternDependencyWebTest:

  • Added a functional test testDeleteBundleShowsPatternAsAffected() that creates a pattern with an article bundle condition, visits the article content type delete form, and asserts the pattern appears under "Configuration updates".

mably changed the visibility of the branch 3072876-pattern-not-removed to hidden.

anybody’s picture

Nice @mably LGTM! Thanks for pushing all these important thins forward here that much!

berdir’s picture

Assigned: berdir » Unassigned

One minor note on the test. I'll leave it to you if you want to address that, then fine to merge.

FWIW, I still think it would be OK to delete this, but if you prefer disabling, that's fine with me. core has various issues on views being deleted being a pain for users, but this isn't really a view that takes you possibly a long time to re-create and the dependency chain is pretty clear.

  • mably committed 89f022a9 on 8.x-1.x
    fix: #3072876 Pattern not removed when deleting the corresponding entity...
mably’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

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