I have a vocabulary that is organized hierarchically. Like so:

-Parent item
--Child item 1
--Child Item 2

If I uncheck "automatic alias" on the children terms, I can give them a specific (non-automatic) alias. However, if I then edit the Parent item (which is automatically aliased) and click "Save", it reverts all the child terms back to automatically aliased, and discards my specific paths.

I traced this to line 522 of pathauto.module, in pathauto_taxonomy_term_update():

/**
* Implements hook_taxonomy_term_update().
*/
function pathauto_taxonomy_term_update($term) {
  pathauto_taxonomy_term_update_alias($term, 'update', array('alias children' => TRUE));
}

The part that says "array('alias children' => TRUE)" is what's causing this bug. If I set it to FALSE then it respects the child paths.

I looked at pathauto_taxonomy_term_update_alias() and saw that it is essentially a recursive function: first it updates the term in question, then it runs the same function for each of the child terms. And at the beginning of the function, it checks to see if it should update the path or not:

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

However, running a dpm($term) at the beginning of that function shows that $term->path is not set at that point, so this function will always run in full, and will always override the paths of child terms.

So first... why? Is there a reason child terms should always be automatically aliased whenever the parent term is being saved? Shouldn't this only happen when running a bulk-update?

And second... how can we fix this? Where should $term->path be getting set so that it can tell this function not to run?

I'm happy to provide a patch to fix this... I just want to make sure I understand what's going on first.

Files: 
CommentFileSizeAuthor
#3 1374094-3.patch444 bytesm.stenta
PASSED: [[SimpleTest]]: [MySQL] 322 pass(es).
[ View ]

Comments

Version:7.x-1.0» 7.x-1.x-dev
Priority:Normal» Major

Changing to 7.x-1.x-dev and increasing priority. I would love to get some feedback on this so I can provide a patch that fixes it.

It would be getting set if you are using the http://drupal.org/project/pathauto_persist module.

Status:Active» Needs review
StatusFileSize
new444 bytes
PASSED: [[SimpleTest]]: [MySQL] 322 pass(es).
[ View ]

I'm not using pathauto_persist. Like I said in the summary, it's being set in pathauto's implementation of hook_taxonomy_term_update().

Attached is a patch that fixes it. I'm not sure if it's the "right" way to do it, but sometimes you have to shoot first and ask questions later. ;-)

The only reason I'm unsure about it is I don't know if there was some reason that 'alias children' => TRUE is being used in the first place in that hook.

Take a look and let me know what you think.

Yes, but if you want Pathauto to not interfere with non-aliased term children, then really you need to install the pathauto_persist module. We're working on merging it into Pathauto proper.

Priority:Major» Minor

Ok, I see what you mean. That module makes sense, and I'll follow along at #936222: Merge in pathauto_persist module functionality to prevent losing manual aliases with node_save() calls. (downgrading this issue to minor)

I'm still curious as to why child paths would be automatically updated when a parent is saved, however. I suppose it would be helpful if you had a pathauto setting along the lines of "category/[term:parent]/[term:name]"... you may want the parent part to be updated for all the child paths. Is that the intended use-case, then?