From a30616fb875f8fde62a72d854960e491ff62511a Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Sun, 3 Mar 2024 16:12:27 +0000 Subject: [PATCH] Issue #3422603 by b2f, godotislate: Fixing source IDs with spaces in Sql.php (cherry picked from commit 56f8d7594cf742ab4ff1ce83a9874d7198f4f8f8) --- .../migrate/src/Plugin/migrate/id_map/Sql.php | 15 +++++-- .../tests/src/Unit/MigrateSqlIdMapTest.php | 40 ++++++++++++++++++- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php index 52b89c9999da..54d55cfb0332 100644 --- a/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php +++ b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php @@ -590,14 +590,23 @@ public function getRowsNeedingUpdate($count) { public function lookupSourceId(array $destination_id_values) { $source_id_fields = $this->sourceIdFields(); $query = $this->getDatabase()->select($this->mapTableName(), 'map'); + // To allow source field names to be defined with spaces and special + // characters, create an alias map of column alias to source field name, + // since SQL column aliases do not support spaces or special characters. + $alias_map = []; foreach ($source_id_fields as $source_field_name => $id_map_field_name) { - $query->addField('map', $id_map_field_name, $source_field_name); + $alias = $query->addField('map', $id_map_field_name); + $alias_map[$alias] = $source_field_name; } foreach ($this->destinationIdFields() as $field_name => $destination_id) { $query->condition("map.$destination_id", $destination_id_values[$field_name], '='); } - $result = $query->execute(); - return $result->fetchAssoc() ?: []; + $result = $query->execute()->fetchAssoc() ?: []; + $source_ids = []; + foreach ($result as $alias => $id) { + $source_ids[$alias_map[$alias]] = $id; + } + return $source_ids; } /** diff --git a/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php b/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php index 0ba79e1aab5d..afcb0cde8dce 100644 --- a/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php +++ b/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php @@ -625,6 +625,42 @@ public function lookupSourceIdMappingDataProvider() { * @dataProvider lookupSourceIdMappingDataProvider */ public function testLookupSourceIdMapping($num_source_fields, $num_destination_fields) { + $source_id_property_prefix = 'source_id_property_'; + $this->doTestLookupSourceIdMapping($num_source_fields, $num_destination_fields, $source_id_property_prefix); + } + + /** + * Performs the source ID test on source and destination fields. + * + * This performs same test as ::testLookupSourceIdMapping, except with source + * property names including spaces and special characters not allowed in SQL + * column aliases. + * + * @param int $num_source_fields + * Number of source fields to test. + * @param int $num_destination_fields + * Number of destination fields to test. + * + * @dataProvider lookupSourceIdMappingDataProvider + */ + public function testLookupSourceIdMappingNonSqlCharacters($num_source_fields, $num_destination_fields) { + $source_id_property_prefix = '$ource id property * '; + $this->doTestLookupSourceIdMapping($num_source_fields, $num_destination_fields, $source_id_property_prefix); + } + + /** + * Performs the source ID test on source and destination fields. + * + * @param int $num_source_fields + * Number of source fields to test. + * @param int $num_destination_fields + * Number of destination fields to test. + * @param string $source_id_property_prefix + * Prefix for the source ID properties. + * + * @dataProvider lookupSourceIdMappingDataProvider + */ + public function doTestLookupSourceIdMapping(int $num_source_fields, int $num_destination_fields, string $source_id_property_prefix): void { // Adjust the migration configuration according to the number of source and // destination fields. $this->sourceIds = []; @@ -635,8 +671,8 @@ public function testLookupSourceIdMapping($num_source_fields, $num_destination_f for ($i = 1; $i <= $num_source_fields; $i++) { $row["sourceid$i"] = "source_id_value_$i"; $source_ids_values = [$row["sourceid$i"]]; - $expected_result["source_id_property_$i"] = "source_id_value_$i"; - $this->sourceIds["source_id_property_$i"] = []; + $expected_result[$source_id_property_prefix . $i] = "source_id_value_$i"; + $this->sourceIds[$source_id_property_prefix . $i] = []; } $destination_id_values = []; $nonexistent_id_values = []; -- GitLab