Hi,

I have a node type that generally speaking relies on pathauto to maintain the aliases. However, for some specific nodes our administrators will chose to uncheck 'Generate automatic URL alias' and provide a custom URL.

The problem is that we have a process which runs on cron and programmatically loads, updates and saves nodes. The issue is that pathauto ignores the fact that 'Generate automatic URL alias' has previously been checked and overwrites custom URLs.

The nodes are loaded using node_load_multiple and saved using node_save.

As a temporary fix I have used the following code just before I save the node:

// Hack to prevent pathauto from updating the alias
$node->path = array('pathauto' => '');

Pathauto seems to expect the path property to be set on the node, but it isn't when I load it, only if its saved via the node form.

Any suggestions on a better fix, workaround, or even acceptance on whether this is a bug or not would be much appreciated.

:wq
Greg.

Comments

ben.kyriakou’s picture

Status: Active » Postponed (maintainer needs more info)

Hi Greg. Testing this in Pathauto 7.x-1.3 this is behaving as I'd expect. When running this snippet of code:

$nids = array(2, 3);
$nodes = node_load_multiple($nids);

foreach ($nodes as $node) {
  $node->title .= ' Updated';
  node_save($node);
}

Where node 2 has a manually created alias, and node 3 has an automatically generated alias, both retain their correct status after being updated.

I'd recommend updating to 7.x-1.3 if possible and checking to see if this is still an issue. If you're still experiencing problems, please provide any additional detail you can as to the operation of your code and your module setup, and move this back to Active.

In the interim this doesn't seem to be a completely non-standard way of achieving your desired behaviour, since this is almost exactly what the Pathauto test suite does when it changes the state of Pathauto aliasing on a node. The most idiomatic way to do it would be:

$node->path['pathauto'] = FALSE;
jsst’s picture

Status: Postponed (maintainer needs more info) » Needs work

I've made some progress debugging this issue. I'm using pathauto 1.3. In my MySQL database, I have a node with pathauto disabled and a custom URL alias:

mysql> select * from url_alias where source = 'node/1000';
+-------+------------+-------------------------------------------------+----------+
| pid   | source     | alias                                           | language |
+-------+------------+-------------------------------------------------+----------+
| 15289 | node/1000 | grootzakelijk/custom/alias                       | nl       |
+-------+------------+-------------------------------------------------+----------+
1 row in set (0.01 sec)

mysql> select * from pathauto_state where entity_id=1000;
Empty set (0.00 sec)

Then I perform an update programmatically similar to what the reporter did:

$node = node_load(1000);

assert(!isset($node->path)); // path is not set!

node_save($node);

After this update, I re-run the queries:

mysql> select * from url_alias where source = 'node/1000';
+-------+------------+-------------------------------------------------+----------+
| pid   | source     | alias                                           | language |
+-------+------------+-------------------------------------------------+----------+
| 15289 | node/1000 | grootzakelijk/custom-alias-is-gone               | nl       |
+-------+------------+-------------------------------------------------+----------+
1 row in set (0.01 sec)

mysql> select * from pathauto_state where entity_id=1000;
Empty set (0.00 sec)

Viewing the node in the web interface, the checkbox for automatic alias creation is now checked and the custom alias is indeed gone.

Digging a little deeper, the offending code in pathauto seems to be in pathauto_node_update_alias():


function pathauto_node_update_alias(stdClass $node, $op, array $options = array()) {
// Skip processing if the user has disabled pathauto for the node.
if (isset($node->path['pathauto']) && empty($node->path['pathauto']) && empty($options['force'])) {
return FALSE;
}
// ...
}

That function checks for $node->path['pathauto'] to be FALSE, but in our case, $node->path isn't set at all.

Please let me know if you need more information. I'd appreciate any feedback on how to fix this problem. I'm afraight my client keeps running into issues whenever a module update decides to load/save nodes.

jsst’s picture

Version: 7.x-1.2 » 7.x-1.3
erichomanchuk’s picture

Priority: Normal » Critical

I'm having the same issue. I noticed it when updating a webform attached to a node and saving I would lose my custom path alias and revert back to auto generate setting. All webforms is doing is a node_load($nid) and a node_save($nid). I notice that no path data is added to the node when it is loaded so when its saved, as @jsst pointed out in pathauto_node_update_alias, a new auto generated alias is created for it deleting my custom alias.

If path auto handles a node_load and a node_save without deleting custom path then perhaps its some other code to blame but for now moving this to Critical as its very damaging to the website.

Liam Morland’s picture