Problem/Motivation

A migration for custom block translated strings is needed. The translations for the title and body of custom blocks is in the i18n string module.

Use D6 custom block translation migration as example. And in D7 the i18n string table is named 'i18n_string' and not '18n_strings' as in D6.

Proposed resolution

Write a patch
review
commit

Comments

quietone created an issue. See original summary.

quietone’s picture

Version: 8.6.x-dev » 8.7.x-dev
Status: Active » Needs review
StatusFileSize
new18.07 KB

Making a start.
This has a new source plugin and test and a migration test.

Found out that the d7 i18n string table has a different name than in D6. So there needs to be a new version of i18nQueryTrait and instead of making a D7 version I added a common one. Though that work is not complete as the D6 source plugins need to add a property.
Also, the d6 version include testing of translations of the body of the block but I didn't see how to translate the body, so that still needs to be looked into.

Status: Needs review » Needs work

The last submitted patch, 2: 3001749-2.patch, failed testing. View results

quietone’s picture

Status: Needs work » Fixed
StatusFileSize
new18.07 KB
new685 bytes

Wrong table name in the test

quietone’s picture

Status: Fixed » Needs review

Oops, that was to be NR not fixed

quietone’s picture

Status: Needs review » Needs work

Still needs work to translation the body of the block and to remove d6/i18nQuery.

quietone’s picture

Status: Needs work » Needs review
StatusFileSize
new28.54 KB
new12.38 KB

Add a translation of the body field and test that.

quietone’s picture

StatusFileSize
new32.97 KB
new11.96 KB

The d6 and d7 box/custom block source plugins are identical expect for using different tables names. This makes a common source plugin that they both use.

And changes the use of REQUEST_TIME to \Drupal::time()->getRequestTime().

Status: Needs review » Needs work

The last submitted patch, 8: 3001749-8.patch, failed testing. View results

jofitz’s picture

Status: Needs work » Needs review
StatusFileSize
new33.24 KB
new1.95 KB

I suggest that d6_box_translation should not be deprecated (at least not while d7_block_custom_translation is created in exactly the same manner)

masipila’s picture

Status: Needs review » Needs work

I read the patch and found a couple of nits.

1.

+++ b/core/modules/block_content/src/Plugin/migrate/source/BlockCustomTranslation.php
@@ -1,32 +1,50 @@
 /**
- * Gets Drupal 6 i18n custom block translations from database.
+ * Drupal custom block source from database.
  */

Class descriptions should start with a third person verb.

2.

   public function query() {
-    // Build a query based on i18n_strings table where each row has the
+    // Get the name of the i18n string table.
+    if ($this->getModuleSchemaVersion('system') >= 7000) {
+      $this->i18nStringTable = 'i18n_string';
+      $this->blockCustomTable = 'block_custom';
+    }
+    else {
+      $this->i18nStringTable = 'i18n_strings';
+      $this->blockCustomTable = 'boxes';
+    }

Can we improve the inline comments a bit, for example like this: "Drupal 6 and 7 used stored the data in different tables. Determine which table names to use."

3.

+    // Build a query based on i18n_string table where each row has the
     // translation for only one property, either title or description. The
     // method prepareRow() is then used to obtain the translation for the
     // other property.
-    $query = $this->select('boxes', 'b')
+    $query = $this->select($this->blockCustomTable, 'b')

Build a query based on blockCustomTable, not i18n_string table.

4.

     // Use 'title' for the info field to match the property name in the
-    // i18n_strings table.
+    // i18n_string table.
     $query->addField('b', 'info', 'title');

... to match the property name in i18nStringTable.

5.

+++ b/core/modules/block_content/src/Plugin/migrate/source/d7/BlockCustomTranslation.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Drupal 7 custom block source from database.

Class descriptions should start with a third person verb.

6.

+++ b/core/modules/content_translation/src/Plugin/migrate/source/I18nQueryTrait.php
@@ -0,0 +1,87 @@
+  /**
+   * Get the translation for the property not already in the row.
+   *
[...]
+   * Since these values are stored in separate rows of the i18n_string
+   * table we get them individually, one in the source plugin query() and the
[...]
+   * @param \Drupal\migrate\Row $row
+   *   The current migration row which must include both a 'language' property
+   *   and an 'objectid' property. The 'objectid' is the value for the
+   *   'objectid' field in the i18n_string table.
[...]
+   * @param string $object_id_name
+   *   The value of the objectid in the i18n table.
+   */
+  protected function getPropertyNotInRowTranslation(Row $row, $property_not_in_row, $object_id_name, MigrateIdMapInterface $id_map) {

Method descriptions should start with a third person verb as well. And were are referring to i18n_string table here like in the previous comments.

7. @quietone, could you please comment on the deprecation comment by Jo Fitzgerald in #10?

Cheers,
Markus

quietone’s picture

Status: Needs work » Needs review
StatusFileSize
new32.84 KB
new3.63 KB

1-6 Fixed.
7. Yes, Jo Fitzgerald is right to remove the deprecation. And the plugins have different source_modules too so probably better to not do a deprecation at all. At least that is what I am thinking at this late hour.

Status: Needs review » Needs work

The last submitted patch, 12: interdiff-10-12.patch, failed testing. View results

quietone’s picture

Status: Needs work » Needs review

The patch passed tests, it is just that sued the extension 'patch' on the interdiff. So this is really NR.

masipila’s picture

Queued for PostgreSQL and SQLite

heddn’s picture

Status: Needs review » Needs work

NW for a duplicate I18nQueryTrait and sqlite failures.

quietone’s picture

Status: Needs work » Needs review
StatusFileSize
new35.64 KB
new5.78 KB

Remove the duplicate I18nQueryTrait resulting in a deprecated d6 version and the new one.

+++ b/core/modules/block_content/tests/src/Kernel/Migrate/d7/MigrateCustomBlockContentTranslationTest.php
@@ -0,0 +1,69 @@
+    $this->assertGreaterThanOrEqual(\Drupal::time()->getRequestTime(), $block->getChangedTime());

Looking at the times, although this is copied from the D6 version of this test, this looks wrong. The block changed time should not be >= the request time. Instead the request time should be >= the block changed time. Or am I wrong?

Status: Needs review » Needs work

The last submitted patch, 17: 3001749-17.patch, failed testing. View results

quietone’s picture

Status: Needs work » Needs review
StatusFileSize
new33.36 KB
new2.47 KB

The menu link test needs to set the name of the i18n string table. Plus remove the deprecation as it is only used for tests.

quietone’s picture

Added tests for PostgreSQL and SQLite

quietone’s picture

Right, this is ready for review.

That suggests that the assertion mentioned in #17 does need to change, which means the D6 test should change.

Will someone confirm that, and if confirmed, should we do that here or in a separate issue?

edit: fix link to comment

heddn’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/block_content/src/Plugin/migrate/source/BlockCustomTranslation.php
    @@ -1,45 +1,65 @@
    +    // Drupal 6 and Drupal 7 use different tables for custom blocks and i18n
    +    // strings. Determine which table names to use.
    +    // Get the name of the i18n string table.
    +    if ($this->getModuleSchemaVersion('system') >= 7000) {
    +      $this->i18nStringTable = 'i18n_string';
    +      $this->blockCustomTable = 'block_custom';
    +    }
    +    else {
    +      $this->i18nStringTable = 'i18n_strings';
    +      $this->blockCustomTable = 'boxes';
    +    }
    +    // Build a query based on blockCustomTable table where each row has the
    

    Instead of having a single base class, can we use one each for d6 and d7 and use a static constant that has the table names?

    maybe move the bulk of the code into the d7 plugin and have the d6 plugin extend that with a new static member. then d6 can just be pulled into contrib later (if we want to).

  2. +++ b/core/modules/menu_link_content/src/Plugin/migrate/source/d6/MenuLinkTranslation.php
    @@ -33,9 +33,18 @@ public function query() {
    +    $query->leftJoin($this->i18nStringTable, 'i18n', 'CAST(ml.mlid as CHAR(255)) = i18n.objectid');
    

    I'm mildly interested why casting to CHAR(255), we picked 255. Does that mean we don't let more than 255 characters? Do we have any values stored in our test cases that are longer than 255?

quietone’s picture

Status: Needs work » Needs review
StatusFileSize
new32.82 KB
new4.71 KB

1. Fixed.
2. The source property objectid is defined with a length of 255, so no there is nothing longer than that in the source.

    'objectid' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
        'description' => 'Object ID.',
      ),
heddn’s picture

Status: Needs review » Reviewed & tested by the community

Perfect. Onward and upward.

quietone’s picture

Issue tags: +blocker

#3008028: Migrate D7 i18n menu links needs the changes to i18nQuery that are made here, so tagging as a blocker.

gábor hojtsy’s picture

Status: Reviewed & tested by the community » Needs work

Yay great! Looks good except this one:

+++ b/core/modules/menu_link_content/src/Plugin/migrate/source/d6/MenuLinkTranslation.php
@@ -33,9 +33,18 @@ public function query() {
+    // Drupal 6 and Drupal 7 use different tables for i18n strings. Determine
+    //  which table names to use.  Get the name of the i18n string table.
+    if ($this->getModuleSchemaVersion('system') >= 7000) {
+      $this->i18nStringTable = 'i18n_string';
+    }
+    else {
+      $this->i18nStringTable = 'i18n_strings';
+    }

Why does D6 menu translation class has this code for D7? That looks confusing.

IMHO same CONST solution could apply as for the block translation class suggested above by @heddn.

quietone’s picture

Status: Needs work » Needs review
StatusFileSize
new33.1 KB
new1.99 KB

Yes, missed that one. Hopefully this will fix it.

mikelutz’s picture

Status: Needs review » Reviewed & tested by the community

Feedback addressed, tests green. Back to rtbc.

gábor hojtsy’s picture

Status: Reviewed & tested by the community » Needs work

Attempted to commit but phpsniff found these:

FILE: ..._content/src/Plugin/migrate/source/d7/BlockCustomTranslation.php
----------------------------------------------------------------------
FOUND 4 ERRORS AFFECTING 4 LINES
----------------------------------------------------------------------
  3 | ERROR | [x] There must be one blank line after the namespace
    |       |     declaration
  8 | ERROR | [x] There must be one blank line after the last USE
    |       |     statement; 0 found;
 97 | ERROR | [x] Expected 1 blank line after function; 0 found
 98 | ERROR | [x] The closing brace for the class must have an empty
    |       |     line before it
quietone’s picture

Status: Needs work » Needs review
StatusFileSize
new33 KB
new935 bytes

Sorry about that. Fixed and improved the class summary line while I was there.

mikelutz’s picture

Status: Needs review » Reviewed & tested by the community

Per interdiff, style issues have been addressed, RTBC for me again, pending passing tests.

  • Gábor Hojtsy committed 9d7f684 on 8.7.x
    Issue #3001749 by quietone, Jo Fitzgerald, heddn, masipila, Gábor Hojtsy...
gábor hojtsy’s picture

Status: Reviewed & tested by the community » Fixed

Superb, thanks!

  • Gábor Hojtsy committed 786a4e2 on 8.6.x
    Issue #3001749 by quietone, Jo Fitzgerald, heddn, masipila, Gábor Hojtsy...

Status: Fixed » Closed (fixed)

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