Problem/Motivation

Right now, Pathauto pattern migration skips migrating the pattern stored in the pathauto_forum_pattern variable. But if forum was enabled on the source site, then this pattern can be migrated as a pattern for taxonomy_term with bundle forums (see d7_taxonomy_vocabulary.yml).

Proposed resolution

Refactor the PathautoPattern migration source plugin to migrate this pattern as a taxonomy_term forums pattern.

It would be nice if these patterns can be mapped to a different entity type (and bundle).

Remaining tasks

* patch
* test

User interface changes

API changes

Data model changes

CommentFileSizeAuthor
#32 pathauto-n3179835-31.patch38.74 KBjienckebd
#31 pathauto-n3179835-30.patch38.73 KBdan612
#27 reroll_diff_25-27.txt6.21 KBdan612
#27 pathauto-n3179835-27.patch38.7 KBdan612
#25 pathauto-n3179835-25.patch38.41 KBdamienmckenna
#24 pathauto-n3179835-24.patch38.37 KBdamienmckenna
#22 interdiff-3179835-14-22.txt2.84 KBnarendrar
#22 pathauto-migrate_forum_pattern_if_forum_is_enabled_on_source-3179835-22--complete.patch38.53 KBnarendrar
#14 interdiff-3179835-13-14.txt699 byteshuzooka
#14 pathauto-migrate_forum_pattern_if_forum_is_enabled_on_source-3179835-14--complete.patch39.44 KBhuzooka
#13 interdiff-3179835-11-13.txt2.26 KBhuzooka
#13 pathauto-migrate_forum_pattern_if_forum_is_enabled_on_source-3179835-13--complete.patch39.21 KBhuzooka
#11 pathauto-migrate_forum_pattern_if_forum_is_enabled_on_source-3179835-11--complete.patch38.9 KBhuzooka
#11 interdiff-3179835-9-11.txt822 byteshuzooka
#8 interdiff-3179835-7-8.txt1.49 KBhuzooka
#8 pathauto-migrate_forum_pattern_if_forum_is_enabled_on_source-3179835-8--complete.patch37.75 KBhuzooka
#8 pathauto-migrate_forum_pattern_if_forum_is_enabled_on_source-3179835-8--test-only.patch21.44 KBhuzooka
#7 interdiff-3179835-5-7.txt1.38 KBhuzooka
#7 pathauto-migrate_forum_pattern_if_forum_is_enabled_on_source-3179835-7--complete.patch37.11 KBhuzooka
#5 pathauto-migrate_forum_pattern_if_forum_is_enabled_on_source-3179835-5--complete.patch37.16 KBhuzooka
#2 pathauto-migrate_forum_pattern_if_forum_is_enabled_on_source-3179835-2--complete.patch37.13 KBhuzooka
#2 pathauto-migrate_forum_pattern_if_forum_is_enabled_on_source-3179835-2--test-only.patch20.8 KBhuzooka

Issue fork pathauto-3179835

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

huzooka created an issue. See original summary.

huzooka’s picture

wim leers’s picture

Issue tags: +migrate-d7-d8
huzooka’s picture

Status: Needs review » Needs work
huzooka’s picture

Assigned: huzooka » Unassigned
Status: Needs work » Needs review
StatusFileSize
new37.16 KB

Fixed the new coding standard violations.

I'll post a self-review soon.

huzooka’s picture

Assigned: Unassigned » huzooka
Status: Needs review » Needs work
huzooka’s picture

Assigned: huzooka » Unassigned
Status: Needs work » Needs review
StatusFileSize
new37.11 KB
new1.38 KB
huzooka’s picture

huzooka’s picture

This patch re-uses the logic from the taxonomy term migrations so the forum pattern migration will use the source's forum nav's vocabulary machine name in it derivative ID.

wim leers’s picture

Status: Needs review » Needs work
  1. Hm, #8's test-only patch is failing on assertNodePattern(), not on the forum pathauto pattern migration. Why is that? 🤔
  2. +++ b/migrations/d7_pathauto_patterns.yml
    @@ -8,14 +8,45 @@ source:
    -  label: label
    -  type: type
    -  pattern: pattern
    -  selection_criteria: selection_criteria
    +  entity_type:
    +    plugin: skip_on_empty
    +    source: entity_type
    +    method: row
    +  bundle:
    +    plugin: skip_on_empty
    +    source: bundle
    +    method: process
    +  label:
    +    plugin: pathauto_pattern_label
    +    source:
    +      - '@entity_type'
    +      - '@bundle'
    +  type:
    +    plugin: concat
    +    source:
    +      - constants/type_prefix
    +      - '@entity_type'
    +    delimiter: ':'
    +  pattern:
    +    plugin: callback
    +    source: value
    +    callable: unserialize
    +  selection_criteria:
    +    -
    +      plugin: skip_on_empty
    +      method: process
    +      source: '@bundle'
    +    -
    +      plugin: pathauto_pattern_selection_criteria
    +      source:
    +        - '@entity_type'
    +        - '@bundle'
    

    🤔 So … this is all basically wrong/overly simplistic in HEAD? 🤯

  3. +++ b/migrations/d7_pathauto_patterns.yml
    @@ -8,14 +8,45 @@ source:
    +  weight: weight
    

    🤔 … and this was missing?! 🙈

  4. +++ b/pathauto.api.php
    @@ -157,3 +157,24 @@ function hook_pathauto_punctuation_chars_alter(array &$punctuation) {
    +function hook_pathauto_migration_pattern_variable_id_map_alter(array &$map) {
    +  // In Drupal 7, there was a "pathauto_blog_pattern" variable which cannot
    +  // be migrated into a Drupal 8 or Drupal 9 pathauto pattern, because in later
    +  // Drupal versions there is no such a think like "blog" in Drupal 7.
    +  // However, we have a custom entity (without bundles) which matches.
    +  $map += [
    +    'blog' => [
    +      'entity_type' => 'custom_entity',
    +    ],
    +  ];
    +
    +  // We want to migrate the "forum" pattern ID to "node"s with type "forum".
    +  $map['forum'] = [
    +    'entity_type' => 'node',
    +    'bundle' => 'forum',
    +  ];
    +}
    

    🤩👏 Absolutely superb comments for this very tricky thing.

    🤔 But I wonder … why is this in a sample hook implementation? Why is this not applied automatically, at least the forum node example?

  5. +++ b/src/Plugin/migrate/process/PathautoPatternLabel.php
    @@ -0,0 +1,108 @@
    + * @MigrateProcessPlugin(
    + *   id = "pathauto_pattern_label"
    + * )
    

    👍 Looks great!

  6. +++ b/src/Plugin/migrate/process/PathautoPatternSelectionCriteria.php
    @@ -0,0 +1,51 @@
    + * @MigrateProcessPlugin(
    + *   id = "pathauto_pattern_selection_criteria"
    + * )
    

    👍 Looks great!

  7. +++ b/src/Plugin/migrate/process/PathautoPatternSelectionCriteria.php
    @@ -0,0 +1,51 @@
    +      throw new MigrateSkipProcessException('The entity_type, the bundle or both sources are missing');
    

    🤓 I think s/sources// would be clearer.

  8. +++ b/src/Plugin/migrate/source/PathautoPattern.php
    @@ -18,21 +19,41 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
    +  protected $variableIdEntityTypeMap = [
    +    'forum' => [
    +      'entity_type' => 'taxonomy_term',
    +      'bundle' => 'forums',
    +    ],
    +  ];
    

    🤔 Referring back to my point 4 — why is this in here but not that other example?

    Also, this could use an @see to that hook 🤓

  9. +++ b/src/Plugin/migrate/source/PathautoPattern.php
    @@ -55,10 +76,71 @@ class PathautoPattern extends DrupalSqlBase {
    +    // Exclude forum pattern if forum wasn't enabled on the source site.
    +    if (!$this->moduleExists('forum')) {
    +      $query->condition('name', 'pathauto_forum_pattern', '<>');
    +    }
    

    🤔 So … this pattern would exist even if the forum module was not enabled on the source site?

  10. +++ b/src/Plugin/migrate/source/PathautoPattern.php
    @@ -55,10 +76,71 @@ class PathautoPattern extends DrupalSqlBase {
    +        // This loop tries to find the destination entity type. If the ID is
    +        // "taxonomy_term_tags", then for first, it tries to find a content
    +        // entity definition with ID "taxonomy", then "taxonomy_term", and
    +        // finally "taxonomy_term_tags".
    

    👍 Nice heuristic!

  11. +++ b/src/Plugin/migrate/source/PathautoPattern.php
    @@ -55,10 +76,71 @@ class PathautoPattern extends DrupalSqlBase {
    +      // "Default" patterns (which do not have entity bundle restriction) should
    +      // get higher weight to act as a fallback.
    +      $rows[] = $row + [
    +        'weight' => !empty($row['bundle']) ? 0 : 1,
    +      ];
    

    👍

    🤔 I presume that the D7 pathauto module already functioned this way, and in D8 it's just more explicit?

huzooka’s picture

Re #10:

#10 is the review of #8, and not #9.

  1. Yes, because weight is not the expected one. The default pattern's weight must be higher than the bundle-specific pattern's weight.
  2. Well, these processes are replacing a part of the logic of the original ::prepareRow method.

    • Partially, this is (only about) my personal preference: I think it is way more safe to use core-provided process plugins where possible.
    • It is easier to track what happens on migration just by looking at the migration definition.
    • Since I also want to derive pattern migrations per entity_type and bundle, decoupling entity_type and bundle params from the original ::prepareRow method is crucial.
  3. Yes, this was missing. I noticed it while writing the test.
  4. Obsolete. See #9.
  5. 👍
  6. 👍
  7. Fixed.
  8. Obsolete. See #9.
  9. Yes. https://git.drupalcode.org/project/pathauto/-/blob/7.x-1.x/pathauto.inst...
  10. 👍
  11. Yes.
huzooka’s picture

Assigned: Unassigned » huzooka

I just noticed that when the current taxonomy vocabulary is the one used by forum navigation, then the "original" taxonomy vocabulary pattern is skipped: see https://git.drupalcode.org/project/pathauto/-/blob/7.x-1.x/pathauto.modu...

huzooka’s picture

Assigned: huzooka » Unassigned
Status: Needs work » Needs review
StatusFileSize
new39.21 KB
new2.26 KB

Addressing #12.

huzooka’s picture

This patch makes PathautoPattern::count() return the actual number of rows to migrate.

wim leers’s picture

  1. +++ b/src/Plugin/migrate/process/PathautoPatternSelectionCriteria.php
    @@ -31,7 +31,7 @@ class PathautoPatternSelectionCriteria extends ProcessPluginBase {
    -      throw new MigrateSkipProcessException('The entity_type, the bundle or both sources are missing');
    +      throw new MigrateSkipProcessException('The entity_type, the bundle or both source are missing');
    

    🤓This did not address #10.7 — I asked "sources" to be removed.

  2. 🙏 #11.9: can you add that as a comment then?
  3. 🙈 #11.4 & #11.8: OOPS! And … much better! 👍
  4. 👍#12 & #13: nice 🤓👍
  5. 🤔
    #14: I don't understand this — PathautoPattern::count() inherited \Drupal\migrate\Plugin\migrate\source\SourcePluginBase::count(), which calls \Drupal\migrate\Plugin\migrate\source\SourcePluginBase::doCount(), which does
      protected function doCount() {
        $iterator = $this->getIterator();
        return $iterator instanceof \Countable ? $iterator->count() : iterator_count($this->initializeIterator());
      }
    
wim leers’s picture

Status: Needs review » Reviewed & tested by the community
  1. 🤔
    #14: I don't understand this — PathautoPattern::count() inherited \Drupal\migrate\Plugin\migrate\source\SourcePluginBase::count(), which calls \Drupal\migrate\Plugin\migrate\source\SourcePluginBase::doCount(), which does
      protected function doCount() {
        $iterator = $this->getIterator();
        return $iterator instanceof \Countable ? $iterator->count() : iterator_count($this->initializeIterator());
      }
    

Oops! This is wrong! @huzooka pointed out that PathautoPattern::count() will result in a call to \Drupal\migrate\Plugin\migrate\source\SqlBase::doCount(), which does do what Zoltan's comment in #14 described.

So … that means the only remark I have left is that silly nitpick in #15.1. Obviously that's non-essential.

So … 🚢🥳

berdir’s picture

Thanks for all the work on pathauto migrate stuff and the extensive reviews.

In theory, there still is forum specific integration for forum aliases but it's broken, also because core has been broken since forever, so I'm not completely sure about this. If we do this and decide that forum specific integration is no longer necessary/useful, shouldn't we also remove that? There are quite a few issues and it's causing confusion.

huzooka’s picture

@Berdir, this is about the pattern migration.

If core has issues with the forum alias migrations, I think that also that bug should be fixed (https://www.w3.org/Provider/Style/URI)

berdir’s picture

I know it is a about the pattern migration. My point is that \Drupal\pathauto\Plugin\pathauto\AliasType\ForumAliasType *does* exist, but it doesn't work because core's forum prefix is broken. It's *supposed* to be forum/ID, not taxonomy/term/ID but has never worked in D8. See #2010132: Canonical taxonomy term link for forum vocabulary is broken. And as a result, our plugin is also broken (likely not just because of that core issue).

As a result, it is challenging to review/test/accept changes in this very broken context and I'm not quite sure I understand what this issue is doing exactly and what the overall intent is.

huzooka’s picture

Re #19:

\Drupal\pathauto\Plugin\pathauto\AliasType\ForumAliasType *does* exist, but it doesn't work because core's forum prefix is broken. It's *supposed* to be forum/ID, not taxonomy/term/ID but has never worked in D8. See #2010132: Canonical taxonomy term link for forum vocabulary is broken. And as a result, our plugin is also broken (likely not just because of that core issue).

Although that plugin is broken, the (forum taxonomy) pattern we migrate into here works well. Long story short: the pattern which is used for the forum taxonomy vocabulary should be the destination pattern of the D7 forum vocabulary, and that's what I solve here.

wim leers’s picture

#20++

narendrar’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new38.53 KB
new2.84 KB

Patch rerolled for failing test on 9.3.0

huzooka’s picture

#22 ignores checking dependencies metadata 👍. These kind of metadata isn't migrated – these are calculated by the config entity class. (This is necessary because the latest pathauto release does not depend on ctools.)

damienmckenna’s picture

StatusFileSize
new38.37 KB

Rerolled.

damienmckenna’s picture

StatusFileSize
new38.41 KB

Rerolled to adjust for some fuzz.

damienmckenna’s picture

Might one of the maintainers be willing to review this and provide feedback, especially around requirements for getting this committed? Thank you.

dan612’s picture

StatusFileSize
new38.7 KB
new6.21 KB

Patch is failing to apply for me on Drupal 10.2.3 + 8.x-1.12 -- attempt at rerolling ... but something not quite right. This patch was made against 8.x-1.12, which explains why it is failing on 8.x-1.x. Things have changed.

wim leers’s picture

Status: Needs review » Needs work

#27: Right — we only need MigratePathautoTest to pass on 1.12 for this to be incorporated into #3424401: D10: Update recommendation for Pathauto (drupal/pathauto).

(There seems to be little point in making this work against 8.x-1.x because it's been green multiple times over the past few years and the maintainer hasn't committed it.)

We can't ask DrupalCI or GitLab CI to test against a specific tag very easily, so just sharing the output of running the test suite locally will suffice 👍

berdir’s picture

> (There seems to be little point in making this work against 8.x-1.x because it's been green multiple times over the past few years and the maintainer hasn't committed it.)

The issue wasn't RTBC for 2 years.

I'm still confused about the focus on this, soon enough forum won't even be in core anymore. It's literally a 1000 lines of code (that I'll have to maintain and keep working forever) to migrate what's essentially a single pattern for the few sites that are using forum module that will usually take a few minutes to set up again. A lot of that is tests but still. I've spent quite some time on fixing Migrate tests in various modules already for D9/D10 compatibility and it's one thing if there's data involved that would actually be a lot of work, but for something like pathauto, I'm struggling to see the benefit.

I've personally never did a ull 1:1 migration of a D7 project. If people see a benefit in maintaining migrations for this, then it might be better suited in a separate project?

+++ b/src/Plugin/migrate/process/PathautoPatternSelectionCriteria.php
@@ -0,0 +1,51 @@
+    return [
+      [
+        'id' => ($entity_type == 'node') ? 'node_type' : 'entity_bundle:' . $entity_type,
+        'bundles' => [$bundle => $bundle],

this is outdated and doesn't work anymore on D10. node_type no longer exists.

wim leers’s picture

Oh yes, sorry — it was not meant in a negative way at all. I think it's fine that it's up to us to keep maintaining this 👍😊

(This is meant for those people for whom writing the code/YAML files to use the Drupal core migration system is unrealistic.)

I'd like for this to remain an open issue here for now to increase the odds of such non-expert users discovering it.

P.S.: the value of this issue alone seems limited for sure, but it's a blocker for #3179865: [PP-1] Derive pathauto pattern migrations to solve inaccurate pattern migration dependencies, and that is what brings the real value!

dan612’s picture

StatusFileSize
new38.73 KB

Attaching reroll with updates to tests to avoid the following errors:

PHP Fatal error:  Declaration of Drupal\Tests\pathauto\Kernel\Migrate\d7\MigratePathautoTest::setUp() must be compatible with Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase::setUp(): void in /app/docroot/modules/contrib/pathauto/tests/src/Kernel/Migrate/d7/MigratePathautoTest.php on line 91

Drupal\Tests\pathauto\Kernel\Migrate\d7\MigratePathautoTest::testPathautoMigrations with data set "Disabled forum on source site" (false)
Error: Call to undefined function Drupal\Tests\pathauto\Kernel\Migrate\d7\drupal_get_path()
jienckebd’s picture

StatusFileSize
new38.74 KB

Hey Dan!! I know you.

The node_type condition plugin was deprecated since Drupal 9.3 in favor of a generalized entity_bundle:* condition plugin.

This pathauto issue applies this change to 1.x branch.

The patch in this issue still references the removed node_type condition plugin and results in test failures.

The attached patch replaces references to the node_type condition plugin with references to the generalized entity_bundle:node condition plugin.

jienckebd’s picture

It seems that this issue combines 4 pathauto 1.x issues including this one. So I applied the same change to that issue to make the combined patch pass tests.

marcelovani made their first commit to this issue’s fork.