Scenario:

I have a node at:
normal path: node/36
url alias: property/test-property

I have a link on this page to a 'subpage' I've created by testing the 3rd argument in the node template to change display a bit.
normal path: node/36/tenants

I wanted to create a link like so:
url alias: property/test-property/tenants

so I have done this:

        $normal_path = $_GET['q'];
        path_set_alias($normal_path . '/tenants', drupal_get_path_alias($normal_path) . '/tenants');
        print l(($num_tenants ? $num_tenants : 0) . ' tenants', $normal_path . '/tenants');

Which works fine for what I've said so far.

Here comes the problem:

Change the title of the node to "Blackwood Apartments".

now the node paths become:
normal path: node/36
url alias: property/blackwood-apartments

and the following error message appears:

user warning: Duplicate entry 'property/blackwood-apartments/tenants-' for key 2 query: INSERT INTO url_alias (src, dst, language) VALUES ('node/36/tenants', 'property/blackwood-apartments/tenants', '') in .../modules/path/path.module on line 112.

It seems to me the problem is this:

FROM path_set_alias() in path.module:

<?php

  else if ($path && $alias) {
    // Check for existing aliases.
    if ($alias == drupal_get_path_alias($path, $language)) {
      // There is already such an alias, neutral or in this language.
      // Update the alias based on alias; setting the language if not yet done.
      db_query("UPDATE {url_alias} SET src = '%s', dst = '%s', language = '%s' WHERE dst = '%s'", $path, $alias, $language, $alias);
    }
    else {
      // A new alias. Add it to the database.
      db_query("INSERT INTO {url_alias} (src, dst, language) VALUES ('%s', '%s', '%s')", $path, $alias, $language);
    }
  }


?>

$alias == drupal_get_path_alias($path, $language) evalutes to FALSE because the existing alias does not match what it should be and thus does not go into the sql that prevents duplicates, but rather the sql to insert a new alias is executed.

Or am I doin it wrong??

CommentFileSizeAuthor
#7 path_set_alias-documentation-7.x.patch805 bytesAnonymous (not verified)

Comments

danielb’s picture

Category: bug » feature

I have found a solution I can use (but would rather not)

<?php

        $pid = db_result(db_query("SELECT pid FROM {url_alias} WHERE src = '%s'", $normal_path . '/tenants'));
        path_set_alias($normal_path . '/tenants', drupal_get_path_alias($normal_path) . '/tenants', $pid);

?>

It would be good if path set alias itself handled this situation ?

Gurpartap Singh’s picture

Could http://drupal.org/node/327535 be in any way related to this?

danielb’s picture

Status: Active » Closed (duplicate)

indeed

Anonymous’s picture

Category: feature » bug
Priority: Minor » Normal
Status: Closed (duplicate) » Postponed (maintainer needs more info)

No, it isn't the same because of the version difference. The coding for D6 was totally refactored.

The question I have is why the alias returning from drupal_get_path_alias (ultimately drupal_lookup_path) is empty.

Gurpartap Singh’s picture

Status: Postponed (maintainer needs more info) » Active

When is drupal_get_path_alias() returning empty?

Do you mean at the $alias == drupal_get_path_alias($path, $language) check? That's so because it tries to verify is the existing alias is the same as the alias supplied into currently running path_set_alias(). Please let me know if I didn't get you.

danielb's query is a good feature request, but if this isn't already there, it might be produced as a bug as well.

Anyhow, daniel, you could simply use path_set_alias('node/123/tenets'); to delete existing aliases for it and then set a new one.

danielb’s picture

Cheers earnie.

Yes the inner 'if' test there does a check to decide whether to do an Insert or Update, and the test itself must not account for the same things the database constraints do, so there is a duplicates problem.

pid - PRIMARY
dst, language - UNIQUE
src - INDEX

If changing my usage to call the function twice, once to clear the path, and once to set it, is what it takes to fix then perhaps really all that is needed is a documentation patch so this behaviour is known from reading the api page.

Anonymous’s picture

Version: 6.6 » 7.x-dev
Component: path.module » documentation
Status: Active » Needs review
StatusFileSize
new805 bytes

Something like the attached?

danielb’s picture

Well I was specifically thinking of instructions on how to override the current aliases for a normal path. Whether by calling the function twice, or with an extra parameter etc..

Status: Needs review » Needs work

The last submitted patch failed testing.

lilou’s picture

Status: Needs work » Needs review
catch’s picture

Status: Needs review » Needs work

Apparently it's an urban myth that google penalises for duplicate content - they won't show the same page twice, but they won't not show it because it has two paths. So we shouldn't repeat that myth in core.

danielb’s picture

Regardless of a single web company's policy, it should be up to the developer using the functions whether to allow duplicates or not.

Not all pages on my site are visible to search engines, due to node access. And some sites are run on private networks that google can't reach, etc...

jhodgdon’s picture

Title: Url alias bug » Url alias function should mention SEO
Status: Needs work » Closed (won't fix)

I do not see why the documentation header for path_set_alias() should say anything about SEO. This is a function for modules to use, not something visible to site builders.