Commit 510c23fd authored by quietone's avatar quietone

Issue #2982007 by quietone, bisonbleu: Move...

Issue #2982007 by quietone, bisonbleu: Move ProductDisplayType::resolveTargetVariationType to a process plugin
parent 860a33c4
......@@ -10,7 +10,10 @@ source:
process:
product_id: nid
title: title
type: type
type:
plugin: migration_lookup
migration: commerce1_product_type
source: type
uid: uid
body: body
status: status
......
......@@ -7,8 +7,8 @@ migration_tags:
source:
plugin: commerce1_product_display_type
variations:
matching: true
default: default
matching: true
default: default
process:
id: type
exists:
......@@ -25,7 +25,16 @@ process:
label: name
description: description
help: help
variationType: variation_type
variationType:
-
plugin: commerce1_resolve_product_variation_type
source: type
variations:
matching: true
default: default
-
plugin: skip_on_empty
method: row
injectVariationFields:
plugin: default_value
default_value: 1
......
<?php
namespace Drupal\commerce_migrate_commerce\Plugin\migrate\process\commerce1;
use Drupal\migrate\MigrateException;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
/**
* Resolve the product variation type.
*
* This plugin determines the product variation type referenced by a product
* type. This is necessary because in 2.x, products can only be mapped to a
* single product variation type, whereas in 1.x one product display node can
* be mapped to multiple product types.
*
* The product variation type will be set to the same name as the product type,
* if that name exists in the Commerce 1 product reference field. If it does
* not exist then the name is set to 'default'. This solution may not work for
* all sites. In that case, this plugin can be overwritten by custom migration
* classes to provide the different logic for determining the target variation
* type. Another option is to modify the migration yml file to use the
* static_map process plugin instead.
*
* Available configuration keys:
* - matching: (optional) Only used if there are more than one referenced
* product types. If set, returns the referenced type that matches the input
* type.
* - default: (optional) Only used if there are more than one referenced
* product types. A default type to use when a matching type is not found.
*
* Example:
*
* @code
* process:
* type:
* plugin: commerce1_resolve_product_variation_type
* source: type
* variations:
* matching: true
* default: trees
* @endcode
*
* If the source value is 'boats' and there is a referenced type of 'boats' then
* the return vale is 'boats'. If that source value is not 'boats' then 'trees'
* is returned.
*
* @MigrateProcessPlugin(
* id = "commerce1_resolve_product_variation_type"
* )
*/
class ResolveProductVariationType extends ProcessPluginBase {
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
if (!is_string($value)) {
throw new MigrateException(sprintf('%s is not a string', var_export($value, TRUE)));
}
$new_value = $value;
// Get all the product types for this commerce display type.
$product_variation_types = array_filter($row->getSourceProperty('data/settings/referenceable_types'));
$count = count($product_variation_types);
if ($count > 1) {
// Assume the default type if it is set in the configuration.
if (!empty($this->configuration['variations']['default'])) {
$new_value = $this->configuration['variations']['default'];
}
// Try to find a variation type that matches the product type.
if (isset($this->configuration['variations']['matching'])) {
$key = array_search($value, $product_variation_types);
if ($key !== FALSE) {
$new_value = $product_variation_types[$key];
}
}
}
if ($count === 1) {
$new_value = reset($product_variation_types);
}
return $new_value;
}
}
......@@ -45,7 +45,11 @@ class ProductDisplayType extends DrupalSqlBase {
* {@inheritdoc}
*/
public function prepareRow(Row $row) {
$instance_config = unserialize($row->getSourceProperty('data'));
$row->setSourceProperty('data', unserialize($row->getSourceProperty('data')));
// @TODO: Remove this block of code when resolveTargetVariationType is
// removed.
$instance_config = $row->getSourceProperty('data');
$product_variation_type = array_filter($instance_config['settings']['referenceable_types']);
if (count($product_variation_type) > 1) {
......@@ -96,8 +100,14 @@ class ProductDisplayType extends DrupalSqlBase {
* The product variation type matching the product, of FALSE if not found.
*
* @throws \Drupal\migrate\MigrateException
*
* @deprecated in Commerce Migrate 8.x-2.x-beta11 and will be removed before
* Commerce Migrate 8.x-3.x. Instead, you should use the
* ResolveProductVariationType process plugin
* See https://www.drupal.org/node/2982007
*/
public function resolveTargetVariationType(Row $row, array $product_variation_types) {
@trigger_error('ProductDisplayType::resolveTargetVariationType() is deprecated in Commerce Migrate 8.x-2.x-beta11 and will be removed before Commerce Migrate 8.x-3.x. Instead, you should use the ResolveProductVariationType process plugin. See https://www.drupal.org/node/2982007', E_USER_DEPRECATED);
$product_variation_type = FALSE;
if (isset($this->configuration['variations']['matching'])) {
......
......@@ -2,7 +2,10 @@
namespace Drupal\Tests\commerce_migrate_commerce\Kernel\Migrate\commerce1;
use Drupal\Core\Database\Database;
use Drupal\KernelTests\KernelTestBase;
use Drupal\Tests\commerce_migrate\Kernel\CommerceMigrateTestTrait;
use Drupal\Tests\migrate\Kernel\MigrateDumpAlterInterface;
/**
* Tests product migration.
......@@ -10,7 +13,7 @@ use Drupal\Tests\commerce_migrate\Kernel\CommerceMigrateTestTrait;
* @group commerce_migrate
* @group commerce_migrate_commerce1
*/
class ProductTest extends Commerce1TestBase {
class ProductTest extends Commerce1TestBase implements MigrateDumpAlterInterface {
use CommerceMigrateTestTrait;
......@@ -32,6 +35,72 @@ class ProductTest extends Commerce1TestBase {
$this->migrateProducts();
}
/**
* {@inheritdoc}
*/
public static function migrateDumpAlter(KernelTestBase $test) {
$db = Database::getConnection('default', 'migrate');
// Remove all product types that can be referenced by the hat content type.
$results = $db->select('field_config_instance', 'fci')
->condition('field_name', 'field_product')
->condition('entity_type', 'node')
->condition('bundle', 'hats')
->fields('fci', ['data'])
->execute()
->fetchCol();
if ($results) {
$data = unserialize(reset($results));
}
$data['settings']['referenceable_types'] = [
'bags_cases' => 0,
'drinks' => 0,
'hats' => 0,
'shoes' => 0,
'storage_devices' => 0,
'tops' => 0,
];
$data = serialize($data);
$db->update('field_config_instance')
->condition('field_name', 'field_product')
->condition('entity_type', 'node')
->condition('bundle', 'hats')
->fields(['data' => $data])
->execute();
// Change the product types that can be referenced by the shoe content
// type to 'hats' and 'shoes'.
$results = $db->select('field_config_instance', 'fci')
->condition('field_name', 'field_product')
->condition('entity_type', 'node')
->condition('bundle', 'shoes')
->fields('fci', ['data'])
->execute()
->fetchCol();
if ($results) {
$data = unserialize(reset($results));
}
$data['settings']['referenceable_types'] = [
'bags_cases' => 0,
'drinks' => 0,
'hats' => 'shoes',
'shoes' => 'shoes',
'storage_devices' => 0,
'tops' => 0,
];
$data = serialize($data);
$db->update('field_config_instance')
->condition('field_name', 'field_product')
->condition('entity_type', 'node')
->condition('bundle', 'shoes')
->fields(['data' => $data])
->execute();
}
/**
* Test product migration from Drupal 7 to 8.
*/
......@@ -45,7 +114,24 @@ class ProductTest extends Commerce1TestBase {
['1'],
['1']
);
$this->assertProductEntity(
22,
'hats',
'1',
'Commerce Guys Baseball Cap',
TRUE,
['1'],
['1']
);
$this->assertProductEntity(
23,
'hats',
'1',
'Drupal Commerce Ski Cap',
TRUE,
['1'],
['1']
);
// Tests a product with multiple variations.
$this->assertProductEntity(
26,
......
......@@ -2,7 +2,10 @@
namespace Drupal\Tests\commerce_migrate_commerce\Kernel\Migrate\commerce1;
use Drupal\Core\Database\Database;
use Drupal\KernelTests\KernelTestBase;
use Drupal\Tests\commerce_migrate\Kernel\CommerceMigrateTestTrait;
use Drupal\Tests\migrate\Kernel\MigrateDumpAlterInterface;
/**
* Tests product type migration.
......@@ -10,7 +13,7 @@ use Drupal\Tests\commerce_migrate\Kernel\CommerceMigrateTestTrait;
* @group commerce_migrate
* @group commerce_migrate_commerce1
*/
class ProductTypeTest extends Commerce1TestBase {
class ProductTypeTest extends Commerce1TestBase implements MigrateDumpAlterInterface {
use CommerceMigrateTestTrait;
......@@ -41,6 +44,72 @@ class ProductTypeTest extends Commerce1TestBase {
$this->executeMigration($migration);
}
/**
* {@inheritdoc}
*/
public static function migrateDumpAlter(KernelTestBase $test) {
$db = Database::getConnection('default', 'migrate');
// Remove all product types that can be referenced by the hat content type.
$results = $db->select('field_config_instance', 'fci')
->condition('field_name', 'field_product')
->condition('entity_type', 'node')
->condition('bundle', 'hats')
->fields('fci', ['data'])
->execute()
->fetchCol();
if ($results) {
$data = unserialize(reset($results));
}
$data['settings']['referenceable_types'] = [
'bags_cases' => 0,
'drinks' => 0,
'hats' => 0,
'shoes' => 0,
'storage_devices' => 0,
'tops' => 0,
];
$data = serialize($data);
$db->update('field_config_instance')
->condition('field_name', 'field_product')
->condition('entity_type', 'node')
->condition('bundle', 'hats')
->fields(['data' => $data])
->execute();
// Change the product types that can be referenced by the shoe content
// type to 'hats' and 'shoes'.
$results = $db->select('field_config_instance', 'fci')
->condition('field_name', 'field_product')
->condition('entity_type', 'node')
->condition('bundle', 'shoes')
->fields('fci', ['data'])
->execute()
->fetchCol();
if ($results) {
$data = unserialize(reset($results));
}
$data['settings']['referenceable_types'] = [
'bags_cases' => 0,
'drinks' => 0,
'hats' => 'hats',
'shoes' => 'shoes',
'storage_devices' => 0,
'tops' => 0,
];
$data = serialize($data);
$db->update('field_config_instance')
->condition('field_name', 'field_product')
->condition('entity_type', 'node')
->condition('bundle', 'shoes')
->fields(['data' => $data])
->execute();
}
/**
* Test product type migration from Drupal 7 to 8.
*/
......@@ -52,6 +121,34 @@ class ProductTypeTest extends Commerce1TestBase {
'variation_type' => 'bags_cases',
];
$this->assertProductTypeEntity($type['id'], $type['label'], $type['description'], $type['variation_type']);
$type = [
'id' => 'drinks',
'label' => 'Drinks',
'description' => 'A <em>Drinks</em> is a content type which contain product variations.',
'variation_type' => 'drinks',
];
$this->assertProductTypeEntity($type['id'], $type['label'], $type['description'], $type['variation_type']);
$type = [
'id' => 'hats',
'label' => 'Hats',
'description' => 'A <em>Hats</em> is a content type which contain product variations.',
'variation_type' => 'hats',
];
$this->assertProductTypeEntity($type['id'], $type['label'], $type['description'], $type['variation_type']);
$type = [
'id' => 'shoes',
'label' => 'Shoes',
'description' => 'A <em>Shoes</em> is a content type which contain product variations.',
'variation_type' => 'shoes',
];
$this->assertProductTypeEntity($type['id'], $type['label'], $type['description'], $type['variation_type']);
$type = [
'id' => 'storage_devices',
'label' => 'Storage Devices',
'description' => 'A <em>Storage Devices</em> is a content type which contain product variations.',
'variation_type' => 'storage_devices',
];
$this->assertProductTypeEntity($type['id'], $type['label'], $type['description'], $type['variation_type']);
$type = [
'id' => 'tops',
'label' => 'Tops',
......
......@@ -123,8 +123,7 @@ class ProductDisplayTypeTest extends MigrateSqlSourceTestBase {
'field_name' => 'field_product',
'description' => 'Shirts',
'help' => '',
'variation_type' => 'tops',
'data' => 'a:7:{s:11:"description";s:0:"";s:7:"display";a:5:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:6:"module";s:13:"commerce_cart";s:8:"settings";a:6:{s:17:"attributes_single";b:0;s:7:"combine";i:1;s:16:"default_quantity";i:1;s:14:"line_item_type";s:7:"product";s:13:"show_quantity";i:0;s:30:"show_single_product_attributes";b:0;}s:4:"type";s:30:"commerce_cart_add_to_cart_form";s:6:"weight";i:3;}s:4:"full";a:5:{s:5:"label";s:6:"hidden";s:6:"module";s:13:"commerce_cart";s:8:"settings";a:5:{s:7:"combine";i:1;s:16:"default_quantity";i:1;s:14:"line_item_type";s:7:"product";s:13:"show_quantity";i:1;s:30:"show_single_product_attributes";b:0;}s:4:"type";s:30:"commerce_cart_add_to_cart_form";s:6:"weight";i:5;}s:15:"product_in_cart";a:4:{s:5:"label";s:5:"above";s:8:"settings";a:0:{}s:4:"type";s:6:"hidden";s:6:"weight";i:0;}s:12:"product_list";a:5:{s:5:"label";s:6:"hidden";s:6:"module";s:15:"field_extractor";s:8:"settings";a:3:{s:10:"field_name";s:11:"field_color";s:9:"formatter";s:27:"entityreference_entity_view";s:8:"settings";a:2:{s:5:"links";i:1;s:9:"view_mode";s:16:"add_to_cart_form";}}s:4:"type";s:15:"field_extractor";s:6:"weight";i:11;}s:6:"teaser";a:4:{s:5:"label";s:5:"above";s:8:"settings";a:0:{}s:4:"type";s:6:"hidden";s:6:"weight";i:0;}}s:14:"fences_wrapper";s:3:"div";s:5:"label";s:18:"Product variations";s:8:"required";i:1;s:8:"settings";a:3:{s:15:"field_injection";i:1;s:19:"referenceable_types";a:6:{s:10:"bags_cases";i:0;s:6:"drinks";i:0;s:4:"hats";i:0;s:5:"shoes";i:0;s:15:"storage_devices";i:0;s:4:"tops";s:4:"tops";}s:18:"user_register_form";b:0;}s:6:"widget";a:5:{s:6:"active";i:1;s:6:"module";s:18:"inline_entity_form";s:8:"settings";a:2:{s:6:"fields";a:0:{}s:13:"type_settings";a:5:{s:14:"allow_existing";i:0;s:18:"autogenerate_title";i:1;s:17:"delete_references";i:1;s:14:"match_operator";s:8:"CONTAINS";s:22:"use_variation_language";i:1;}}s:4:"type";s:18:"inline_entity_form";s:6:"weight";i:2;}}',
'data' => unserialize('a:7:{s:11:"description";s:0:"";s:7:"display";a:5:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:6:"module";s:13:"commerce_cart";s:8:"settings";a:6:{s:17:"attributes_single";b:0;s:7:"combine";i:1;s:16:"default_quantity";i:1;s:14:"line_item_type";s:7:"product";s:13:"show_quantity";i:0;s:30:"show_single_product_attributes";b:0;}s:4:"type";s:30:"commerce_cart_add_to_cart_form";s:6:"weight";i:3;}s:4:"full";a:5:{s:5:"label";s:6:"hidden";s:6:"module";s:13:"commerce_cart";s:8:"settings";a:5:{s:7:"combine";i:1;s:16:"default_quantity";i:1;s:14:"line_item_type";s:7:"product";s:13:"show_quantity";i:1;s:30:"show_single_product_attributes";b:0;}s:4:"type";s:30:"commerce_cart_add_to_cart_form";s:6:"weight";i:5;}s:15:"product_in_cart";a:4:{s:5:"label";s:5:"above";s:8:"settings";a:0:{}s:4:"type";s:6:"hidden";s:6:"weight";i:0;}s:12:"product_list";a:5:{s:5:"label";s:6:"hidden";s:6:"module";s:15:"field_extractor";s:8:"settings";a:3:{s:10:"field_name";s:11:"field_color";s:9:"formatter";s:27:"entityreference_entity_view";s:8:"settings";a:2:{s:5:"links";i:1;s:9:"view_mode";s:16:"add_to_cart_form";}}s:4:"type";s:15:"field_extractor";s:6:"weight";i:11;}s:6:"teaser";a:4:{s:5:"label";s:5:"above";s:8:"settings";a:0:{}s:4:"type";s:6:"hidden";s:6:"weight";i:0;}}s:14:"fences_wrapper";s:3:"div";s:5:"label";s:18:"Product variations";s:8:"required";i:1;s:8:"settings";a:3:{s:15:"field_injection";i:1;s:19:"referenceable_types";a:6:{s:10:"bags_cases";i:0;s:6:"drinks";i:0;s:4:"hats";i:0;s:5:"shoes";i:0;s:15:"storage_devices";i:0;s:4:"tops";s:4:"tops";}s:18:"user_register_form";b:0;}s:6:"widget";a:5:{s:6:"active";i:1;s:6:"module";s:18:"inline_entity_form";s:8:"settings";a:2:{s:6:"fields";a:0:{}s:13:"type_settings";a:5:{s:14:"allow_existing";i:0;s:18:"autogenerate_title";i:1;s:17:"delete_references";i:1;s:14:"match_operator";s:8:"CONTAINS";s:22:"use_variation_language";i:1;}}s:4:"type";s:18:"inline_entity_form";s:6:"weight";i:2;}}'),
],
];
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment