How to programmatically bulk create/update aliases in Drupal 7
Asked Answered
L

4

6

How to programmatically bulk alias node urls by using only drupal 7 core (with it's great batch API !)?

My question is actually how to make drupal use and recognise the aliases stored in url_alias table?

Background:

The project I work on has more than 200,000 nodes (Drupal 7) and aliasing the system default url of all those nodes would literally take years with pathauto module (10 aliases every 20 minutes). I tried everything to improve those performances but failed (tried different servers, different mysql optimisations, different patterns).

I have already the batch process functions up and ready, they alias 200,000 nodes in 20 minutes, they create clean aliases stored in table "url_alias". I took lots of time looking at pathauto code, but couldn't find or understand how the module was giving drupal the order to recognize the bulk updated paths.

Thank you for your hints, answers or ideas..much appreciated!

Lederer answered 16/5, 2012 at 9:19 Comment(0)
C
8

Here is function that will update aliases for all nodes of specified type

<?php
  module_load_include('inc', 'pathauto');
  module_load_include('inc', 'pathauto.pathauto');

  // Get all nodes that need to be updated
  $query = db_select('node', 'n');
  $query->addField('n', 'nid');
  $query->condition('n.type', array('TYPE1', 'TYPE2'), 'IN');

  $nids = $query->execute()->fetchCol();

  // Save current action for new aliases and change it to delete old one.
  $alias_action = variable_get('pathauto_update_action', 0);
  variable_set('pathauto_update_action', PATHAUTO_UPDATE_ACTION_DELETE);

  pathauto_node_update_alias_multiple($nids, 'bulkupdate');

  // Restore original action for new aliases.
  variable_set('pathauto_update_action', $alias_action);

?>
Cuirass answered 30/8, 2012 at 15:44 Comment(1)
Don't ever use variable_set() to temporarily modify a value during a request -- race conditions can easily bite you. Instead set and restore $conf['pathauto_update_action'], which cannot affect other requests.Lagena
S
2

If you do this in a hook_node_update or in a Rule or something, the new $node will not be available to other modules like token, pathauto, etc., and so you won't get expected results. A solution is to reset the cached $node:

<?php
// Reset the cached $node.
entity_get_controller('node')->resetCache(array($node->nid));

// Get all nids that reference this node. This is just an example.
$nids = db_query("SELECT entity_id FROM field_data_field_reference WHERE field_reference_target_id = {$node->nid}")->fetchCol();

// Include necessary Pathauto files.
module_load_include('inc', 'pathauto');
module_load_include('inc', 'pathauto.pathauto');

// Save current action for new aliases and change it to delete old one.
$alias_action = variable_get('pathauto_update_action', 0);
variable_set('pathauto_update_action', PATHAUTO_UPDATE_ACTION_DELETE);

pathauto_node_update_alias_multiple($nids, 'bulkupdate');

// Restore original action for new aliases.
variable_set('pathauto_update_action', $alias_action);

// Clear path cache. 
cache_clear_all('*', 'cache_path', TRUE);
?>
Swacked answered 10/1, 2013 at 21:13 Comment(0)
B
1

Check to make sure the variable is set for that bundle for pathauto.

The variable name is pathauto_[entity]_[bundle]_pattern, so pathauto_node_[bundle]_pattern

Bernat answered 16/5, 2012 at 21:49 Comment(0)
I
1

This code is based off of Eugene Fidelin's but uses $conf global instead of variable sets.

  module_load_include('inc', 'pathauto');
  module_load_include('inc', 'pathauto.pathauto');

  // Get all nodes that need to be updated.
  $query = db_select('node', 'n');
  $query->addField('n', 'nid');
  $query->condition('n.type', array('TYPE1', 'TYPE2'), 'IN');

  $nids = $query->execute()->fetchCol();

  global $conf;
  // Store old value.
  $old_pathauto_var = $conf['pathauto_update_action'];
  // Set new value.
  $conf['pathauto_update_action'] = PATHAUTO_UPDATE_ACTION_DELETE;

  // Generate aliases.
  pathauto_node_update_alias_multiple($nids, 'bulkupdate');

  // Restore original action for new aliases.
  $conf['pathauto_update_action'] = $old_pathauto_var;
Influent answered 30/3, 2016 at 19:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.