Skip to content
Snippets Groups Projects
Commit ba9b75f6 authored by catch's avatar catch
Browse files

Issue #3258581 by godotislate, nikolay shapovalov, boromino, quietone,...

Issue #3258581 by godotislate, nikolay shapovalov, boromino, quietone, merlin06, benjifisher: Move I18nQueryTrait from content_translation to migrate_drupal
parent 380195b0
No related branches found
No related tags found
2 merge requests!11197Issue #3506427 by eduardo morales alberti: Remove responsive_image.ajax from hook,!10223132456: Fix issue where views instances are emptied before an ajax request is complete
Pipeline #413475 passed with warnings
Pipeline: drupal

#413488

    Pipeline: drupal

    #413479

      Pipeline: drupal

      #413477

        ...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
        use Drupal\migrate\Row; use Drupal\migrate\Row;
        use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase; use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
        use Drupal\content_translation\Plugin\migrate\source\I18nQueryTrait; use Drupal\migrate_drupal\Plugin\migrate\source\I18nQueryTrait;
        /** /**
        * Drupal 7 i18n content block translations source from database. * Drupal 7 i18n content block translations source from database.
        ......
        ...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
        namespace Drupal\content_translation\Plugin\migrate\source; namespace Drupal\content_translation\Plugin\migrate\source;
        @trigger_error('The ' . __NAMESPACE__ . '\I18nQueryTrait is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use \Drupal\migrate_drupal\Plugin\migrate\source\I18nQueryTrait instead. See https://www.drupal.org/node/3439256', E_USER_DEPRECATED);
        use Drupal\migrate\Plugin\MigrateIdMapInterface; use Drupal\migrate\Plugin\MigrateIdMapInterface;
        use Drupal\migrate\MigrateException; use Drupal\migrate\MigrateException;
        use Drupal\migrate\Row; use Drupal\migrate\Row;
        ...@@ -10,6 +12,11 @@ ...@@ -10,6 +12,11 @@
        /** /**
        * Gets an i18n translation from the source database. * Gets an i18n translation from the source database.
        *
        * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use
        * \Drupal\migrate_drupal\Plugin\migrate\source\I18nQueryTrait instead.
        *
        * @see https://www.drupal.org/node/3439256
        */ */
        trait I18nQueryTrait { trait I18nQueryTrait {
        ......
        ...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
        namespace Drupal\menu_link_content\Plugin\migrate\source\d6; namespace Drupal\menu_link_content\Plugin\migrate\source\d6;
        use Drupal\content_translation\Plugin\migrate\source\I18nQueryTrait;
        use Drupal\migrate\Row;
        use Drupal\menu_link_content\Plugin\migrate\source\MenuLink; use Drupal\menu_link_content\Plugin\migrate\source\MenuLink;
        use Drupal\migrate\Row;
        use Drupal\migrate_drupal\Plugin\migrate\source\I18nQueryTrait;
        // cspell:ignore mlid // cspell:ignore mlid
        ......
        ...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
        namespace Drupal\menu_link_content\Plugin\migrate\source\d7; namespace Drupal\menu_link_content\Plugin\migrate\source\d7;
        use Drupal\content_translation\Plugin\migrate\source\I18nQueryTrait;
        use Drupal\migrate\Row;
        use Drupal\menu_link_content\Plugin\migrate\source\MenuLink; use Drupal\menu_link_content\Plugin\migrate\source\MenuLink;
        use Drupal\migrate\Row;
        use Drupal\migrate_drupal\Plugin\migrate\source\I18nQueryTrait;
        // cspell:ignore mlid objectid textgroup // cspell:ignore mlid objectid textgroup
        ......
        <?php
        declare(strict_types=1);
        namespace Drupal\migrate_drupal\Plugin\migrate\source;
        use Drupal\migrate\Plugin\MigrateIdMapInterface;
        use Drupal\migrate\MigrateException;
        use Drupal\migrate\Row;
        // cspell:ignore objectid
        /**
        * Gets an i18n translation from the source database.
        */
        trait I18nQueryTrait {
        /**
        * The i18n string table name.
        *
        * @var string
        */
        protected string $i18nStringTable;
        /**
        * Gets the translation for the property not already in the row.
        *
        * For some i18n migrations there are two translation values, such as a
        * translated title and a translated description, that need to be retrieved.
        * Since these values are stored in separate rows of the i18nStringTable
        * table we get them individually, one in the source plugin query() and the
        * other in prepareRow(). The names of the properties varies, for example,
        * in BoxTranslation they are 'body' and 'title' whereas in
        * MenuLinkTranslation they are 'title' and 'description'. This will save both
        * translations to the row.
        *
        * @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 $property_not_in_row
        * The name of the property to get the translation for.
        * @param string $object_id_name
        * The value of the objectid in the i18n table.
        * @param \Drupal\migrate\Plugin\MigrateIdMapInterface $id_map
        * The ID map.
        *
        * @return bool
        * FALSE if the property has already been migrated.
        *
        * @throws \Drupal\migrate\MigrateException
        */
        protected function getPropertyNotInRowTranslation(Row $row, string $property_not_in_row, string $object_id_name, MigrateIdMapInterface $id_map): bool {
        $language = $row->getSourceProperty('language');
        if (!$language) {
        throw new MigrateException('No language found.');
        }
        $object_id = $row->getSourceProperty($object_id_name);
        if (!$object_id) {
        throw new MigrateException('No objectid found.');
        }
        // If this row has been migrated it is a duplicate so skip it.
        if ($id_map->lookupDestinationIds([$object_id_name => $object_id, 'language' => $language])) {
        return FALSE;
        }
        // Save the translation for the property already in the row.
        $property_in_row = $row->getSourceProperty('property');
        $row->setSourceProperty($property_in_row . '_translated', $row->getSourceProperty('translation'));
        // Get the translation, if one exists, for the property not already in the
        // row.
        $query = $this->select($this->i18nStringTable, 'i18n')
        ->fields('i18n', ['lid'])
        ->condition('i18n.property', $property_not_in_row)
        ->condition('i18n.objectid', $object_id);
        $query->leftJoin('locales_target', 'lt', '[i18n].[lid] = [lt].[lid]');
        $query->condition('lt.language', $language);
        $query->addField('lt', 'translation');
        $results = $query->execute()->fetchAssoc();
        $row->setSourceProperty($property_not_in_row . '_translated', $results['translation'] ?? NULL);
        return TRUE;
        }
        }
        <?php
        declare(strict_types=1);
        namespace Drupal\Tests\migrate_drupal\Kernel;
        use Drupal\KernelTests\KernelTestBase;
        use Drupal\migrate\Plugin\migrate\source\SourcePluginBase;
        use Drupal\migrate\Plugin\MigrationInterface;
        /**
        * Tests instantiating migrate source plugins using I18nQueryTrait.
        *
        * @group migrate_drupal
        */
        class I18nQueryTraitTest extends KernelTestBase {
        /**
        * {@inheritdoc}
        */
        protected static $modules = [
        'block_content',
        'menu_link_content',
        'migrate',
        'migrate_drupal',
        'taxonomy',
        ];
        /**
        * Tests instantiating migrate source plugins using I18nQueryTrait.
        *
        * I18nQueryTrait was originally in the content_translation module, which
        * could lead to fatal errors instantiating the source plugins that use it
        * when the content_translation module was not installed.
        *
        * @param string $plugin_id
        * The ID of a Migrate source plugin that uses I18nQueryTrait.
        *
        * @dataProvider providerI18nQueryTraitPlugins
        */
        public function testMigrateSourcePluginUsingI18nQueryTraitDiscovery(string $plugin_id): void {
        // Namespace for uninstalled module content_translation needs to be removed
        // for this test.
        $this->disablePsr4ForUninstalledModules(['content_translation']);
        $migration = $this->createMock(MigrationInterface::class);
        $this->assertInstanceOf(SourcePluginBase::class, \Drupal::service('plugin.manager.migrate.source')->createInstance($plugin_id, [], $migration));
        }
        /**
        * Removes PSR-4 namespaces from class loader for uninstalled modules.
        *
        * TestRunnerKernel registers namespaces for all modules, including
        * uninstalled modules. This method removes the PSR-4 namespace for the list
        * of modules passed in after confirming they are all uninstalled.
        *
        * @param string[] $remove_psr4_modules
        * List of machine names of modules that are uninstalled and whose PSR-4
        * namespaces should be removed from the class loader.
        */
        protected function disablePsr4ForUninstalledModules(array $remove_psr4_modules): void {
        /** @var \Drupal\Core\Extension\ModuleExtensionList $module_list */
        $module_list = \Drupal::service('extension.list.module');
        $available_modules = $module_list->getAllAvailableInfo();
        $installed_modules = $module_list->getAllInstalledInfo();
        $prefixes = $this->classLoader->getPrefixesPsr4();
        foreach ($remove_psr4_modules as $module) {
        $this->assertArrayHasKey($module, $available_modules);
        $this->assertArrayNotHasKey($module, $installed_modules);
        if (isset($prefixes["Drupal\\$module\\"])) {
        // Cannot actually remove the PSR4 prefix from the class loader, so set
        // the path to a wrong location.
        $this->classLoader->setPsr4("Drupal\\$module\\", '');
        }
        }
        }
        /**
        * Provides data for testMigrateSourcePluginUsingI18nQueryTraitDiscovery().
        */
        public static function providerI18nQueryTraitPlugins(): array {
        return [
        ['d6_box_translation'],
        ['d7_block_custom_translation'],
        ['d6_menu_link_translation'],
        ['d7_menu_link_translation'],
        ['d7_term_localized_translation'],
        ];
        }
        }
        ...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
        namespace Drupal\taxonomy\Plugin\migrate\source\d7; namespace Drupal\taxonomy\Plugin\migrate\source\d7;
        use Drupal\content_translation\Plugin\migrate\source\I18nQueryTrait;
        use Drupal\migrate\Row; use Drupal\migrate\Row;
        use Drupal\migrate_drupal\Plugin\migrate\source\I18nQueryTrait;
        // cspell:ignore ltlanguage objectid // cspell:ignore ltlanguage objectid
        ......
        0% Loading or .
        You are about to add 0 people to the discussion. Proceed with caution.
        Finish editing this message first!
        Please register or to comment