Bulk updating Pathauto aliases - Using hook_update_N() and Batch API

Last updated on
30 April 2025

On this page:

To get help completing this task, see the Getting help completing your task page.

Goal

In this page I would like to introduce another way for updating the node's URL Alias, especially when you have to re-build the url for thousands and thousands of nodes.

Skills needed

This solution involves creating a custom module. You should be familiar with Creating custom modules.

You will also need a basic knowledge of Pathauto and Batch API.

Detailed steps

The update scripts implements the hook_update_N function and should be placed into your module or profile .install file.

First of all create your .install file where you'll place the update script. Then, you should insert the following code snippet.

function mymodule_update_7100(&$sandbox)
{
  // We want to update all nodes that have have a new pathauto pattern.
  $node_types = ['blog','feature','infographic', 'map', 'timeline'];

  // Initiatialize our variables to track progress.
  if (!isset($sandbox['nids'])) {
    $result = db_select('node', 'n')
      ->fields('n', array('nid'))
      ->orderBy('n.nid', 'ASC')
      ->condition('type', $node_types)
      ->execute();
    $sandbox['nids'] = $result->fetchCol();

    // The count of nodes updated so far.
    $sandbox['progress'] = 0;
    // Total nodes that must be updated.
    $sandbox['max'] = $result->rowCount();
    // The number of nodes changed.
    $sandbox['changed'] = 0;

    // Exit early if there's nothing to do.
    if (!$sandbox['max']) {
      $sandbox['#finished'] = TRUE;
      return t('No paths to update.');
    }
  }

  $limit = 100;

  // Load pathauto.module from the pathauto module.
  module_load_include('module', 'pathauto', 'pathauto');

  // Process one batch of nodes.
  $nids = array_splice($sandbox['nids'], - $limit);
  $changes = pathauto_node_update_alias_multiple($nids, 'bulkupdate');
  $sandbox['progress'] += $limit;
  $sandbox['changed'] += count(array_filter($changes));

  // Set the "finished" status, to tell batch engine whether this function
  // needs to run again. If you set a float, this will indicate the progress
  // of the batch so the progress bar will update.
  $sandbox['#finished'] = ($sandbox['progress'] >= $sandbox['max'])
    ? TRUE
    : ($sandbox['progress'] / $sandbox['max']);

  $t_args = [
    '!percent' => floor($sandbox['#finished'] * 100),
    '!total' => $sandbox['max'],
    '!changed' => $sandbox['changed'],
  ];
  // This more detailed information only works if the patch from
  // https://www.drupal.org/node/2874993
  // is committed.
  if ($changes) {
    return t('!percent% of !total nodes processed. !changed pathauto paths changed.', $t_args);
  }
  else {
    return t('!percent% of !total nodes processed. Some of which have new pathauto paths.', $t_args);
  }

Background and reference information

This method has been tested on Drupal 7.23 with Pathauto 7.x-1.2 module.

Useful links:

Next steps: moving beyond this task

The next step is improving the computational time for more than 10,000 updates.

Help improve this page

Page status: Not set

You can: