Have found this bug 1 or 2 month ago. The problem arrived when I was developing user frinedly URLs using custom URL rewrite. Have found this bug within beta 4 & as far as I see its beta5 & 6th issue too.

So. Take a look at the followinf code in path.module (function path_nodeapi()):

      case 'load':
        $path = "node/$node->nid";
        $alias = drupal_get_path_alias($path);
        if ($alias != $path) {
          $node->path = $alias;
        }
        break;

It compares alias with path & if we have them different, it assigns node->path member to an alias. Then node->path will be appearing in node edit form. If I have my custom url rewrite changing path --> my custom url rewrite will appear in that edit box. And after user applies changes to node, this alias would be added to DB. It was my alias, not yours...:)

I have fixed the problem with the next code changes (if some core developers are interested):

Change path.module path_nodeapi callback to next:

function path_nodeapi(&$node, $op, $arg) {
  if (user_access('create url aliases') || user_access('administer url aliases')) {
    switch ($op) {
      case 'validate':
        $node->path = trim($node->path);
        if ($node->path && !valid_url($node->path)) {
          form_set_error('path', t('The path is invalid.'));
        }
        else if (db_result(db_query("SELECT COUNT(dst) FROM {url_alias} WHERE dst = '%s' AND src != '%s'", $node->path, "node/$node->nid"))) {
          form_set_error('path', t('The path is already in use.'));
        }
        break;

      case 'load':
        $path = "node/$node->nid";
// doques: update
//        $alias = drupal_get_path_alias($path);
        $in_database = FALSE;
        $alias = drupal_get_path_alias($path, &$in_database);
// The next code from Drupal 4.7b4 is incorrect, because I can change
// path alias using custom_url_rewrite() callback for example.
//        if ($alias != $path) {
        if ($in_database && $alias != $path) {
// -- doques: update
          $node->path = $alias;
        }
        break;

      case 'insert':
        // Don't try to insert if path is NULL.  We may have already set
        // the alias ahead of time.
        if ($node->path) {
          path_set_alias("node/$node->nid", $node->path);
        }
        break;

      case 'update':
        path_set_alias("node/$node->nid", $node->path, $node->pid);
        break;

      case 'delete':
        $path = "node/$node->nid";
        if (drupal_get_path_alias($path) != $path) {
          path_set_alias($path);
        }
        break;
    }
  }
}

Also, you'll need to alter your drupal_get_path_alias in path.inc (altered beta4 code):

function drupal_get_path_alias($path, $in_database = FALSE) {
// $in_database is a helper parameter for path_nodeapi() callback.
// -- doques: update
  $result = $path;
  if ($alias = drupal_lookup_path('alias', $path)) {
// doques: add
    if($result != $alias) {
      $in_database = TRUE;
    }
// -- doques: add
    $result = $alias;
  }
  if (function_exists('custom_url_rewrite')) {
    $result = custom_url_rewrite('alias', $result, $path);
  }

// doques: add
//  $result = drupal_invoke_url_rewrite_('alias', $result, $path);
// -- doques: add

  return $result;
}
CommentFileSizeAuthor
#11 path_right.patch517 byteschx
#10 path_ref.patch982 byteschx
#9 path.module.patch.txt507 bytesdoq
#8 path.inc.patch.txt746 bytesdoq

Comments

doq’s picture

Version: 4.7.0-beta6 » 4.7.0-rc1
Priority: Normal » Critical

somebody?

Marked it critical.

Zen’s picture

Priority: Critical » Normal

Please:
a) state the problem clearly.
b) detail steps to reproduce this accurately in RC1.
c) post code relevant to the version associated with the issue.

From what I understood, I tried:
a) Creating a node.
b) Setting a URL alias.
c) Editing the node again.
d) Setting the URL alias to something else.

All worked as expected. Followed changes in the url_alias table.. was fine.

-K

doq’s picture

When I create my own custom_rewrite_url callback function and it redirects e.g. node/18 to node/bla, path module will print node/bla in edit box. It can print it there, ćos node/bla is not from url_alias table. Its from some mine table.

doq’s picture

mean ¨can´t print it there¨.

tomsys’s picture

Version: 4.7.0-rc1 » 4.7.0-rc2
Priority: Normal » Critical

Hello,

Yes indeed ... there is that bug what @doq is talking about and he is right ..

a) there is an option in path.module to rewrite URL's with custom_url_rewrite( ... function. What is very usefull when we want to replace standard word [node] to [something_else] .. by default Drupal uses [node] and it looks like this

... with a little help of custom_url_rewrite( ... function we can transform those mentioned URL's to ..

custom_url_rewrite( ... function will look like this

function custom_url_rewrite($type, $path, $original) {
  // This path was already aliased, skip rewriting it
  if ($path != $original) {
    return $path;
  }
  if ($type == 'source') { // URL coming from a client
    return preg_replace('!^something_else/(\d+)$!', 'node/\1', $path);
  }
  elseif ($type == 'alias') { // URL going out to a client
    return preg_replace('!^node/(\d+)$!', 'something_else/\1', $path);
  }
}

... and that function can be defined anywhere, but usually goes into [settings.php].

So, there is this option in core and some of us are using it and what @doq is saying that it's not handled properly in case if we use that option.. without that function being present in your site config everything will work fine and you will never notice any problems at all.

I'd love to see this fixed, that's why I changed the priority setting, especially if there is a patch available.

Greeeeeeetz,
T.

doq’s picture

Thanx for support.

Zen’s picture

Status: Active » Needs work

doq: Can you please submit your changes in patch form?

Thanks,
-K

doq’s picture

Status: Needs work » Reviewed & tested by the community
StatusFileSize
new746 bytes

Here you go.

doq’s picture

StatusFileSize
new507 bytes
chx’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new982 bytes

Well. Maybe this way. There is one more problem though -- if I give an alias to a node and there is a custom_url_rewrite then custom_url_rewrite "wins" which is IMO another bug. But first, let's fix this.

chx’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new517 bytes

Very nice solution by Steven, even corrects my problem in the above comment.

Steven’s picture

Status: Reviewed & tested by the community » Needs review

Too complicated IMO. You're adding a special syntax and complicated reference handling to drupal_get_path_alias(), a function which is called from every url() and l() statement. And all that just for an action which is needed by an optional module when you are editing a node. There are orders of magnitude of difference in usage here.

All we really need to know at that point is: is there an entry in the database for this path. Because that is exactly the same condition that path_set_alias() uses when it saved the alias. There is nothing wrong with querying the database at this point.

Steven’s picture

Status: Needs review » Fixed

For reference: #12 replied to #10. #11 is the proposed solution to my comments ;).

Committed to HEAD with some more comments.

Anonymous’s picture

Status: Fixed » Closed (fixed)