Last updated 2 May 2017. Created on 3 March 2015.
Edited by dalin, nerdcore, robertoperuzzo. Log in to edit this page.

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.

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

stefanotabarelli’s picture

Thanks so much for your work, this was exactly what I was trying to build and it worked perfectly.