AliasStorage::preloadPathAlias() incorrectly prioritizes und aliases

Created on 9 June 2016, over 8 years ago
Updated 24 January 2024, 11 months ago

Problem/Motivation

If you add a language-unspecified alias for a page that already has an alias in the default language, the language-unspecified alias will sporadically appear around the site.

Steps to reproduce

use Drupal\Core\Language\LanguageInterface;

// Generate paths to test with.
$source = '/' . uniqid('alias_test');
$base = '/' . uniqid('alias_test') . '_';

/** @var \Drupal\Core\Path\AliasStorageInterface $storage */
$storage = \Drupal::service('path.alias_storage');

// Save a couple of aliases.
$storage->save($source, $base . 'en', 'en');
$storage->save($source, $base . 'und', LanguageInterface::LANGCODE_NOT_SPECIFIED);

// Search for an individual alias. Should find the en alias we added above.
$found_one = $storage->lookupPathAlias($source, 'en');
print "$found_one\n";

// Search for multiple aliases. Should also find the en alias from above.
$found_multi = $storage->preloadPathAlias([$source], 'en');
print "$found_multi[$source]\n";
// Woops, it found the und alias instead!

// Cleanup.
$storage->delete(['source' => $source]);

Proposed resolution

Change the sort order of the query prepared in \Drupal\path_alias\AliasRepository::preloadPathAlias so that the in:: addLanguageFallback applies its sorts in the correct order too.

This will also require changing slightly how the results are fetched from the query by this method.

Fix is in

MR 5250

All others MRs can be closed

Remaining tasks

None that I'm aware of.

User interface changes

URL paths should now be consistent, rather than depend on the unpredictable nature of what methods were called first, what was cached etc. So this might introduce some change for path aliases on some sites, but should do so in a consistent way, fixing the essentially non-deterministic way it was working before.

API changes

None.

Data model changes

None

πŸ› Bug report
Status

Fixed

Version

10.2 ✨

Component
PathΒ  β†’

Last updated 6 days ago

  • Maintained by
  • πŸ‡¬πŸ‡§United Kingdom @catch
Created by

πŸ‡¨πŸ‡¦Canada vasi

Live updates comments and jobs are added and updated live.
  • D8MI

    (Drupal 8 Multilingual Initiative) is the tag used by the multilingual initiative to mark core issues (and some contributed module issues). For versions other than Drupal 8, use the i18n (Internationalization) tag on issues which involve or affect multilingual / multinational support. That is preferred over Translation.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡¬πŸ‡§United Kingdom steven jones

    Coming here from #3135440 where language hierarchy needs to solve basically the same problem/bug that core has, but for multiple languages instead of two.

    Moving the target version to 11, and will open a issue fork to work on this.

  • πŸ‡¬πŸ‡§United Kingdom steven jones

    So as mentioned in #27 the code has moved on a bit, so I've focused on bringing over the tests from #16 that tested out \Drupal\path_alias\AliasRepository::preloadPathAlias.

    And then I've implemented a fix.

    The real problem here is that preloadPathAlias processes the result set and prefers aliases at the end, whereas all the other methods use the first row in the result set.

    This is explained when setting the sort order of the base_table.id field:

        // We order by ID ASC so that fetchAllKeyed() returns the most recently
        // created alias for each source. Subsequent queries using fetchField() must
        // use ID DESC to have the same effect.
        $select->orderBy('base_table.id', 'ASC');
    

    But this change in ordering is never made in addLanguageFallback so I've introduced a badly named parameter that'll reverse the ordering when appropriate.

  • @steven-jones opened merge request.
  • Status changed to Needs review about 1 year ago
  • πŸ‡¬πŸ‡§United Kingdom steven jones
  • πŸ‡¬πŸ‡§United Kingdom steven jones

    ...and I've just read that I'm supposed to be using patches β†’ , unless I explain why I'd like to change over to MRs:

    It's been 7 years since the last patch, and the world has moved on, MRs are more/faster/better. Hope that's enough!

  • πŸ‡¬πŸ‡§United Kingdom steven jones

    There we go, as expected the MR tests pass, but the tests-only version fails.

  • Status changed to Needs work about 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Thanks for reviving this one. Think we will need a change record for the new parameter, examples are always good too in the CR.

    Searching http://grep.xnddx.ru/search?text=addLanguageFallback&filename=

    https://www.drupal.org/project/variants β†’ or https://www.drupal.org/project/language_hierarchy β†’ may be doing something with this. Lightly took a look.

  • πŸ‡¬πŸ‡§United Kingdom steven jones

    @smustgrave thanks, do you happen to have an example of a CR for documenting adding a new parameter to a protected method?

    As for language hierarchy, yes, we're all over this in πŸ› LH limits to 1 alias when preloading multiple aliases Needs review :)

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    This is a pretty basic one https://www.drupal.org/node/3372008 β†’

  • Status changed to Needs review about 1 year ago
  • πŸ‡¬πŸ‡§United Kingdom steven jones

    I was writing out the change notice, when I thought that actually this all seems really ugly: that for one method that wants the results in a different order we need to thread this parameter around etc. Seems a lot like tail wagging the dog.
    Then I realised that it was only because preloadPathAlias wants to use fetchAllKeyed that we need to do this at all.

    If this method does a fraction more work, then everything can be nice and consistent and actually all the queries generated by the \Drupal\path_alias\AliasRepository class can actually have the same order by clauses, meaning that everything is consistent and easier to reason about anyway.

    So...I've added that approach to the MR, which now means there's no API change.

    I'm also not sure if I agree with @GΓ‘bor Hojtsy in #18 that this change is now* a BC break, since, at the moment, depending on your configuration results are simply inconsistent. If preloadPathAlias is called, you'll get one set of aliases, but if you were to call lookupBySystemPath then you might get a different one for the same set of data.
    Core has no control over the order and use of these functions really, so I don't think you can consider this weird bug a feature that can't be fixed in a minor or even patch release.

    *: Also when @GΓ‘bor Hojtsy wrote #18 the patch on this issue was essentially inverting the sort to shift the problem to the methods that only seek to return on alias, so yeah, that would have been the same bug, but a different presentation.

    Setting this back to Needs review to get some more feedback on this change of tack.

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Not sure I can speak on it but if a new solution is taken the issue summary will need ot be updated to reflect that.

  • πŸ‡¬πŸ‡§United Kingdom steven jones
  • Status changed to RTBC about 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    So circled back to this one

    1) Drupal\Tests\path_alias\Kernel\AliasTest::testPreloadPathAlias
    Failed asserting that two arrays are equal.
    --- Expected
    +++ Actual
    @@ @@
     Array (
         '/und/src' => '/und/alias'
         '/en/src' => '/en/alias'
    -    '/en-und/src' => '/en-und/en'
    +    '/en-und/src' => '/en-und/und'
         '/en-xx-lolspeak/src' => '/en-xx-lolspeak/en-dup'
    -    '/en-xx-lolspeak-und/src' => '/en-xx-lolspeak-und/en'
    +    '/en-xx-lolspeak-und/src' => '/en-xx-lolspeak-und/und'
     )
    

    Test-only feature shows the issue.

    Hiding patches as fix is in MR, also highlighted it in the IS.

    Looking at the change itself nothing seems glaring so going to mark it.

    • catch β†’ committed e829c1e3 on 10.2.x
      Issue #2745755 by vasi, Steven Jones, smustgrave, mvc, Wim Leers, james....
    • catch β†’ committed 94e37fd5 on 11.x
      Issue #2745755 by vasi, Steven Jones, smustgrave, mvc, Wim Leers, james....
  • Status changed to Fixed 12 months ago
  • πŸ‡¬πŸ‡§United Kingdom catch

    Committed/pushed to 11.x and cherry-picked to 10.2.x, thanks!

    I deleted the change record because it was for a different approach to the final one.

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024