Right now the bulk update only lets the user target an entity type (e.g. node, taxonomy term) but on large sites it would be good to be able to target a specific bundle (e.g. blog post) so as to speed up path updates.

Issue fork pathauto-3138032

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

jonathan_hunt created an issue. See original summary.

rokzabukovec’s picture

StatusFileSize
new3.77 KB

Hi I created a patch that should solve this issue. You can select bundles on generate and update functions. I hope you can review the patch.
Best regards.

rokzabukovec’s picture

Status: Active » Needs review

Status: Needs review » Needs work

The last submitted patch, 2: 3138032-2.patch, failed testing. View results

berdir’s picture

Issue tags: +Needs tests

Thanks for starting this, useful feature indeed, but it does need quite some more work :)

  1. +++ b/src/Form/PathautoBulkUpdateForm.php
    @@ -79,6 +79,22 @@ class PathautoBulkUpdateForm extends FormBase {
     
    +    // Display all available bundles in a checkbox form element.
    +    $bundle_names = \Drupal::service('entity_type.bundle.info')->getBundleInfo('node');
    +    $bundle_options = [];
    +    foreach ($bundle_names as $key => $bundle) {
    +      $bundle_options[$key] = $bundle['label'];
    +    }
    +
    +    $config = \Drupal::config('pathauto.settings');;
    +    $bundles_to_update = $config->get('bundles_to_update');
    +    $form['bundles'] = [
    +      '#type' => 'checkboxes',
    +      '#title' => $this->t('Select bundles for which to generate/update URL aliases'),
    +      '#options' => $bundle_options,
    +      '#default_value' => $bundles_to_update,
    +    ];
    +
         $definitions = $this->aliasTypeManager->getVisibleDefinitions();
    

    This only includes node, we should include the bundles for each entity type, probably using #state to only see the bundles for enabled entity types.

    Also, storing this in configuration doesn't make sense. We should pass it along as a new argument to the batch operation.

  2. +++ b/src/Form/PathautoBulkUpdateForm.php
    @@ -121,6 +137,15 @@ class PathautoBulkUpdateForm extends FormBase {
       public function submitForm(array &$form, FormStateInterface $form_state) {
    +    $bundles = array_filter($form_state->getValue('bundles'), function ($bundle) {
    +      if ($bundle['label'] != "0") {
    +        return $bundle;
    +      }
    +    });
    +
    

    You don't need a function here, the default behavior of array_filter() works fine.

  3. +++ b/src/PathautoGenerator.php
    @@ -154,6 +154,17 @@ class PathautoGenerator implements PathautoGeneratorInterface {
       public function createEntityAlias(EntityInterface $entity, $op) {
    +    $bundle = $entity->bundle();
    +    $config = $this->configFactory->get('pathauto.settings');
    +    $bundles_to_update = $config->get('bundles_to_update');
    +
    +    // If the entity is of type 'node', at least one bundle was selected
    +    // and the user checked the bundle of this entity to be updated,
    +    // then create aliases.
    +    if ($entity->getEntityType()->id() === 'node' && !empty($bundles_to_update) && !array_key_exists($bundle, $bundles_to_update)) {
    +      return NULL;
    +    }
    +
    

    The logic should be in the batch operation query that selects entities to update. This means we would still test all of them and just abort when trying to set the alias. And it is persisted, which means once you save the form, it would then keep respecting that and no longer generate any other aliases.

rokzabukovec’s picture

Assigned: Unassigned » rokzabukovec

@Berdir thank you for the review. I will continue to improve the solution.

rokzabukovec’s picture

Assigned: rokzabukovec » Unassigned
Status: Needs work » Needs review
StatusFileSize
new7.07 KB

Hi,
I created a patch that enables the user to specify which bundle to generate aliases for. In this patch only the content bundles are selectable but someone could extend this for other bundles. I also wrote a test for this behavior.

Status: Needs review » Needs work

The last submitted patch, 7: 3138032-7.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

mostepaniukvm’s picture

StatusFileSize
new12.63 KB

Extended #7 patch and added bundles argument to drush command.

What about extending deriver and get derivatives for every bundle? As I remember in most cases I usually add or change some bundle-specific pattern and get need to regenerate aliases only for specific bundle. What about plugins like canonical_entities:taxonomy_term:channel?

a.milkovsky’s picture

Drush command changes worked good for me. A minor note:

+++ b/src/Form/PathautoBulkUpdateForm.php
@@ -80,4 +80,20 @@ class PathautoBulkUpdateForm extends FormBase {
+    $node_bundles = \Drupal::service('entity_type.bundle.info')->getBundleInfo('node');

DI

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

sokru’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests

Updated the patch so that the PathautoBulkUpdateForm supports selecting bundles for other entities than nodes.

The MR has tests that pass, so removed the "needs tests" tag.

korn3000’s picture

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

mably’s picture

Summary

Allow the Pathauto bulk update to target specific entity bundles rather than regenerating aliases for all bundles of an entity type.

Problem

Previously, the "Bulk generate" form and the drush pathauto:aliases-generate command only allowed selecting entity types (e.g. all nodes, all users). On sites with many content types and thousands of nodes, regenerating aliases for all node bundles when only one bundle's pattern changed was unnecessarily slow and could produce unwanted side effects on other bundles' aliases.

Changes

  • AliasTypeBatchUpdateInterface.php: Added a $bundles parameter to the batchUpdate() method signature.
  • EntityAliasTypeBase.php: Implemented bundle filtering in batchUpdate() — when $bundles is non-empty and the entity type has a bundle key, the batch query adds an IN condition to restrict processing to the selected bundles only.
  • PathautoBulkUpdateForm.php: Injected the entity_type.bundle.info service. The form now dynamically renders a set of bundle checkboxes per entity type, shown/hidden via #states when the corresponding entity type is selected. On submit, selected bundles are passed through to batchProcess().
  • PathautoCommands.php: Added an optional bundles argument to the drush pathauto:aliases-generate command (comma-separated list of bundles, only valid when a single alias type is specified). Includes a validateBundles() hook that checks bundles exist and enforces the single-type constraint. Injected EntityTypeBundleInfoInterface for bundle discovery.
  • PathautoBulkUpdateTest.php: Added testCreateBundlePath() functional test — creates both an Article and an Event node, runs bulk update selecting only the Article bundle, and asserts that only 1 alias is generated (the Article), confirming the Event was correctly excluded.
mably’s picture

Assigned: Unassigned » berdir