upgrades core to 8.4.2
This commit is contained in:
@@ -5,8 +5,8 @@ package: Core (Experimental)
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -43,4 +43,15 @@ class MigrateDestination extends Plugin {
|
||||
*/
|
||||
public $requirements_met = TRUE;
|
||||
|
||||
/**
|
||||
* Identifies the system handling the data the destination plugin will write.
|
||||
*
|
||||
* The destination plugin itself determines how the value is used. For
|
||||
* example, Migrate Drupal's destination plugins expect destination_module to
|
||||
* be the name of a module that must be installed on the destination.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $destination_module;
|
||||
|
||||
}
|
||||
|
||||
@@ -43,16 +43,15 @@ class MigrateSource extends Plugin implements MultipleProviderAnnotationInterfac
|
||||
/**
|
||||
* Identifies the system providing the data the source plugin will read.
|
||||
*
|
||||
* This can be any type, and the source plugin itself determines how the value
|
||||
* is used. For example, Migrate Drupal's source plugins expect
|
||||
* source_provider to be the name of a module that must be installed and
|
||||
* enabled in the source database.
|
||||
* The source plugin itself determines how the value is used. For example,
|
||||
* Migrate Drupal's source plugins expect source_module to be the name of a
|
||||
* module that must be installed and enabled in the source database.
|
||||
*
|
||||
* @see \Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase::checkRequirements
|
||||
*
|
||||
* @var mixed
|
||||
* @var string
|
||||
*/
|
||||
public $source_provider;
|
||||
public $source_module;
|
||||
|
||||
/**
|
||||
* Specifies the minimum version of the source provider.
|
||||
@@ -60,7 +59,7 @@ class MigrateSource extends Plugin implements MultipleProviderAnnotationInterfac
|
||||
* This can be any type, and the source plugin itself determines how it is
|
||||
* used. For example, Migrate Drupal's source plugins expect this to be an
|
||||
* integer representing the minimum installed database schema version of the
|
||||
* module specified by source_provider.
|
||||
* module specified by source_module.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\migrate;
|
||||
|
||||
|
||||
interface MigrateBuildDependencyInterface {
|
||||
|
||||
/**
|
||||
|
||||
@@ -96,7 +96,7 @@ class MigrateExecutable implements MigrateExecutableInterface {
|
||||
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
|
||||
* The migration to run.
|
||||
* @param \Drupal\migrate\MigrateMessageInterface $message
|
||||
* The message to record.
|
||||
* The migrate message service.
|
||||
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
|
||||
* The event dispatcher.
|
||||
*
|
||||
@@ -386,9 +386,14 @@ class MigrateExecutable implements MigrateExecutableInterface {
|
||||
$multiple = $plugin->multiple();
|
||||
}
|
||||
}
|
||||
// No plugins or no value means do not set.
|
||||
if ($plugins && !is_null($value)) {
|
||||
$row->setDestinationProperty($destination, $value);
|
||||
// Ensure all values, including nulls, are migrated.
|
||||
if ($plugins) {
|
||||
if (isset($value)) {
|
||||
$row->setDestinationProperty($destination, $value);
|
||||
}
|
||||
else {
|
||||
$row->setEmptyDestinationProperty($destination);
|
||||
}
|
||||
}
|
||||
// Reset the value.
|
||||
$value = NULL;
|
||||
@@ -534,6 +539,9 @@ class MigrateExecutable implements MigrateExecutableInterface {
|
||||
|
||||
// @TODO: explore resetting the container.
|
||||
|
||||
// Run garbage collector to further reduce memory.
|
||||
gc_collect_cycles();
|
||||
|
||||
return memory_get_usage();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\migrate;
|
||||
|
||||
|
||||
interface MigrateMessageInterface {
|
||||
|
||||
/**
|
||||
|
||||
@@ -133,4 +133,12 @@ interface MigrateDestinationInterface extends PluginInspectionInterface {
|
||||
*/
|
||||
public function rollbackAction();
|
||||
|
||||
/**
|
||||
* Gets the destination module handling the destination data.
|
||||
*
|
||||
* @return string|null
|
||||
* The destination module or NULL if not found.
|
||||
*/
|
||||
public function getDestinationModule();
|
||||
|
||||
}
|
||||
|
||||
@@ -213,6 +213,8 @@ interface MigrateIdMapInterface extends \Iterator, PluginInspectionInterface {
|
||||
*
|
||||
* @deprecated in Drupal 8.1.x, will be removed before Drupal 9.0.x. Use
|
||||
* lookupDestinationIds() instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2725809
|
||||
*/
|
||||
public function lookupDestinationId(array $source_id_values);
|
||||
|
||||
@@ -227,7 +229,7 @@ interface MigrateIdMapInterface extends \Iterator, PluginInspectionInterface {
|
||||
* If unkeyed, the first count($source_id_values) keys will be assumed.
|
||||
*
|
||||
* @return array
|
||||
* An array of arrays of destination identifier values.
|
||||
* An array of arrays of destination identifier values.
|
||||
*
|
||||
* @throws \Drupal\migrate\MigrateException
|
||||
* Thrown when $source_id_values contains unknown keys, or is the wrong
|
||||
@@ -266,10 +268,10 @@ interface MigrateIdMapInterface extends \Iterator, PluginInspectionInterface {
|
||||
public function getQualifiedMapTableName();
|
||||
|
||||
/**
|
||||
* Sets the migrate message.
|
||||
* Sets the migrate message service.
|
||||
*
|
||||
* @param \Drupal\migrate\MigrateMessageInterface $message
|
||||
* The message to display.
|
||||
* The migrate message service.
|
||||
*/
|
||||
public function setMessage(MigrateMessageInterface $message);
|
||||
|
||||
|
||||
@@ -100,4 +100,12 @@ interface MigrateSourceInterface extends \Countable, \Iterator, PluginInspection
|
||||
*/
|
||||
public function getIds();
|
||||
|
||||
/**
|
||||
* Gets the source module providing the source data.
|
||||
*
|
||||
* @return string|null
|
||||
* The source module or NULL if not found.
|
||||
*/
|
||||
public function getSourceModule();
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ use Drupal\migrate\Plugin\Discovery\ProviderFilterDecorator;
|
||||
* Plugin manager for migrate source plugins.
|
||||
*
|
||||
* @see \Drupal\migrate\Plugin\MigrateSourceInterface
|
||||
* @see \Drupal\migrate\Plugin\source\SourcePluginBase
|
||||
* @see \Drupal\migrate\Plugin\migrate\source\SourcePluginBase
|
||||
* @see \Drupal\migrate\Annotation\MigrateSource
|
||||
* @see plugin_api
|
||||
*
|
||||
|
||||
@@ -312,6 +312,8 @@ class Migration extends PluginBase implements MigrationInterface, RequirementsIn
|
||||
*
|
||||
* @deprecated in Drupal 8.1.x, will be removed before Drupal 9.0.x. Use
|
||||
* more specific getters instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2873795
|
||||
*/
|
||||
public function get($property) {
|
||||
return isset($this->$property) ? $this->$property : NULL;
|
||||
@@ -570,7 +572,7 @@ class Migration extends PluginBase implements MigrationInterface, RequirementsIn
|
||||
*/
|
||||
public function mergeProcessOfProperty($property, array $process_of_property) {
|
||||
// If we already have a process value then merge the incoming process array
|
||||
//otherwise simply set it.
|
||||
// otherwise simply set it.
|
||||
$current_process = $this->getProcess();
|
||||
if (isset($current_process[$property])) {
|
||||
$this->process = NestedArray::mergeDeepArray([$current_process, $this->getProcessNormalized([$property => $process_of_property])], TRUE);
|
||||
|
||||
@@ -153,7 +153,7 @@ interface MigrationInterface extends PluginInspectionInterface, DerivativeInspec
|
||||
/**
|
||||
* Set the current migration status.
|
||||
*
|
||||
* @param int $result
|
||||
* @param int $status
|
||||
* One of the STATUS_* constants.
|
||||
*/
|
||||
public function setStatus($status);
|
||||
|
||||
@@ -64,7 +64,7 @@ class MigrationPluginManager extends DefaultPluginManager implements MigrationPl
|
||||
*/
|
||||
protected function getDiscovery() {
|
||||
if (!isset($this->discovery)) {
|
||||
$directories = array_map(function($directory) {
|
||||
$directories = array_map(function ($directory) {
|
||||
return [$directory . '/migration_templates', $directory . '/migrations'];
|
||||
}, $this->moduleHandler->getModuleDirectories());
|
||||
|
||||
@@ -125,7 +125,7 @@ class MigrationPluginManager extends DefaultPluginManager implements MigrationPl
|
||||
* An array of migration objects with the given tag.
|
||||
*/
|
||||
public function createInstancesByTag($tag) {
|
||||
$migrations = array_filter($this->getDefinitions(), function($migration) use ($tag) {
|
||||
$migrations = array_filter($this->getDefinitions(), function ($migration) use ($tag) {
|
||||
return !empty($migration['migration_tags']) && in_array($tag, $migration['migration_tags']);
|
||||
});
|
||||
return $this->createInstances(array_keys($migrations));
|
||||
|
||||
@@ -64,6 +64,6 @@ abstract class ComponentEntityDisplayBase extends DestinationBase {
|
||||
* @return \Drupal\Core\Entity\Display\EntityDisplayInterface
|
||||
* The entity display object.
|
||||
*/
|
||||
protected abstract function getEntity($entity_type, $bundle, $mode);
|
||||
abstract protected function getEntity($entity_type, $bundle, $mode);
|
||||
|
||||
}
|
||||
|
||||
@@ -195,4 +195,26 @@ class Config extends DestinationBase implements ContainerFactoryPluginInterface,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDestinationModule() {
|
||||
if (!empty($this->configuration['destination_module'])) {
|
||||
return $this->configuration['destination_module'];
|
||||
}
|
||||
if (!empty($this->pluginDefinition['destination_module'])) {
|
||||
return $this->pluginDefinition['destination_module'];
|
||||
}
|
||||
// Config translations require the config_translation module so set the
|
||||
// migration provider to 'config_translation'. The corresponding non
|
||||
// translated configuration is expected to be handled in a separate
|
||||
// migration.
|
||||
if (isset($this->configuration['translations'])) {
|
||||
return 'config_translation';
|
||||
}
|
||||
// Get the module handling this configuration object from the config_name,
|
||||
// which is of the form <module_name>.<configuration object name>
|
||||
return !empty($this->configuration['config_name']) ? explode('.', $this->configuration['config_name'], 2)[0] : NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -110,4 +110,22 @@ abstract class DestinationBase extends PluginBase implements MigrateDestinationI
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDestinationModule() {
|
||||
if (!empty($this->configuration['destination_module'])) {
|
||||
return $this->configuration['destination_module'];
|
||||
}
|
||||
if (!empty($this->pluginDefinition['destination_module'])) {
|
||||
return $this->pluginDefinition['destination_module'];
|
||||
}
|
||||
if (is_string($this->migration->provider)) {
|
||||
return $this->migration->provider;
|
||||
}
|
||||
else {
|
||||
return reset($this->migration->provider);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -149,6 +149,7 @@ class EntityContentBase extends Entity {
|
||||
* An updated entity, or NULL if it's the same as the one passed in.
|
||||
*/
|
||||
protected function updateEntity(EntityInterface $entity, Row $row) {
|
||||
$empty_destinations = $row->getEmptyDestinationProperties();
|
||||
// By default, an update will be preserved.
|
||||
$rollback_action = MigrateIdMapInterface::ROLLBACK_PRESERVE;
|
||||
|
||||
@@ -171,6 +172,7 @@ class EntityContentBase extends Entity {
|
||||
// clone the row with an empty set of destination values, and re-add only
|
||||
// the specified properties.
|
||||
if (isset($this->configuration['overwrite_properties'])) {
|
||||
$empty_destinations = array_intersect($empty_destinations, $this->configuration['overwrite_properties']);
|
||||
$clone = $row->cloneWithoutDestination();
|
||||
foreach ($this->configuration['overwrite_properties'] as $property) {
|
||||
$clone->setDestinationProperty($property, $row->getDestinationProperty($property));
|
||||
@@ -184,6 +186,9 @@ class EntityContentBase extends Entity {
|
||||
$field->setValue($values);
|
||||
}
|
||||
}
|
||||
foreach ($empty_destinations as $field_name) {
|
||||
$entity->$field_name = NULL;
|
||||
}
|
||||
|
||||
$this->setRollbackAction($row->getIdMap(), $rollback_action);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Plugin\PluginBase;
|
||||
use Drupal\migrate\MigrateMessage;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Event\MigrateIdMapMessageEvent;
|
||||
use Drupal\migrate\MigrateException;
|
||||
@@ -55,7 +56,7 @@ class Sql extends PluginBase implements MigrateIdMapInterface, ContainerFactoryP
|
||||
protected $messageTableName;
|
||||
|
||||
/**
|
||||
* The migrate message.
|
||||
* The migrate message service.
|
||||
*
|
||||
* @var \Drupal\migrate\MigrateMessageInterface
|
||||
*/
|
||||
@@ -156,6 +157,7 @@ class Sql extends PluginBase implements MigrateIdMapInterface, ContainerFactoryP
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->migration = $migration;
|
||||
$this->eventDispatcher = $event_dispatcher;
|
||||
$this->message = new MigrateMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,8 @@ Drupal 8.4.x and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPA
|
||||
*
|
||||
* @deprecated in Drupal 8.4.x and will be removed in Drupal 9.0.x. Use
|
||||
* \Drupal\migrate\Plugin\migrate\process\MakeUniqueBase instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2873762
|
||||
*/
|
||||
abstract class DedupeBase extends MakeUniqueBase {
|
||||
}
|
||||
|
||||
@@ -19,5 +19,7 @@ Drupal 8.4.x and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPA
|
||||
*
|
||||
* @deprecated in Drupal 8.4.x and will be removed in Drupal 9.0.x. Use
|
||||
* \Drupal\migrate\Plugin\migrate\process\MakeUniqueEntityField instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2873762
|
||||
*/
|
||||
class DedupeEntity extends MakeUniqueEntityField { }
|
||||
class DedupeEntity extends MakeUniqueEntityField {}
|
||||
|
||||
@@ -19,11 +19,9 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
* The file can be moved, reused, or set to be automatically renamed if a
|
||||
* duplicate exists.
|
||||
*
|
||||
* The source value is an array of two values:
|
||||
* - source: The source path or URI, e.g. '/path/to/foo.txt' or
|
||||
* 'public://bar.txt'.
|
||||
* - destination: The destination path or URI, e.g. '/path/to/bar.txt' or
|
||||
* 'public://foo.txt'.
|
||||
* The source value is an indexed array of two values:
|
||||
* - The source path or URI, e.g. '/path/to/foo.txt' or 'public://bar.txt'.
|
||||
* - The destination URI, e.g. 'public://foo.txt'.
|
||||
*
|
||||
* Available configuration keys:
|
||||
* - move: (optional) Boolean, if TRUE, move the file, otherwise copy the file.
|
||||
@@ -39,8 +37,9 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
* process:
|
||||
* path_to_file:
|
||||
* plugin: file_copy
|
||||
* source: /path/to/file.png
|
||||
* destination: /new/path/to/file.png
|
||||
* source:
|
||||
* - /path/to/file.png
|
||||
* - public://new/path/to/file.png
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\migrate\Plugin\MigrateProcessInterface
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\migrate\Plugin\migrate\process;
|
||||
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
@@ -2,65 +2,20 @@
|
||||
|
||||
namespace Drupal\migrate\Plugin\migrate\process;
|
||||
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\Row;
|
||||
@trigger_error('The ' . __NAMESPACE__ . '\Iterator is deprecated in
|
||||
Drupal 8.4.x and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\SubProcess', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* This plugin iterates and processes an array.
|
||||
* Iterates and processes an associative array.
|
||||
*
|
||||
* @link https://www.drupal.org/node/2135345 Online handbook documentation for iterator process plugin @endlink
|
||||
* @deprecated in Drupal 8.4.x and will be removed in Drupal 9.0.x. Use
|
||||
* \Drupal\migrate\Plugin\migrate\process\SubProcess instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2880427
|
||||
*
|
||||
* @MigrateProcessPlugin(
|
||||
* id = "iterator",
|
||||
* handle_multiples = TRUE
|
||||
* )
|
||||
*/
|
||||
class Iterator extends ProcessPluginBase {
|
||||
|
||||
/**
|
||||
* Runs a process pipeline on each destination property per list item.
|
||||
*/
|
||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
$return = [];
|
||||
if (!is_null($value)) {
|
||||
foreach ($value as $key => $new_value) {
|
||||
$new_row = new Row($new_value, []);
|
||||
$migrate_executable->processRow($new_row, $this->configuration['process']);
|
||||
$destination = $new_row->getDestination();
|
||||
if (array_key_exists('key', $this->configuration)) {
|
||||
$key = $this->transformKey($key, $migrate_executable, $new_row);
|
||||
}
|
||||
$return[$key] = $destination;
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the process pipeline for the current key.
|
||||
*
|
||||
* @param string|int $key
|
||||
* The current key.
|
||||
* @param \Drupal\migrate\MigrateExecutableInterface $migrate_executable
|
||||
* The migrate executable helper class.
|
||||
* @param \Drupal\migrate\Row $row
|
||||
* The current row after processing.
|
||||
*
|
||||
* @return mixed
|
||||
* The transformed key.
|
||||
*/
|
||||
protected function transformKey($key, MigrateExecutableInterface $migrate_executable, Row $row) {
|
||||
$process = ['key' => $this->configuration['key']];
|
||||
$migrate_executable->processRow($row, $process, $key);
|
||||
return $row->getDestinationProperty('key');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function multiple() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
class Iterator extends SubProcess {}
|
||||
|
||||
@@ -6,7 +6,6 @@ use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
|
||||
/**
|
||||
* Logs values without changing them.
|
||||
*
|
||||
|
||||
@@ -17,4 +17,4 @@ Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPA
|
||||
* @deprecated in Drupal 8.3.x and will be removed in Drupal 9.0.x.
|
||||
* Use \Drupal\migrate\Plugin\migrate\process\MigrationLookup instead.
|
||||
*/
|
||||
class Migration extends MigrationLookup { }
|
||||
class Migration extends MigrationLookup {}
|
||||
|
||||
@@ -222,15 +222,16 @@ class MigrationLookup extends ProcessPluginBase implements ContainerFactoryPlugi
|
||||
// Do a normal migration with the stub row.
|
||||
$migrate_executable->processRow($stub_row, $process);
|
||||
$destination_ids = [];
|
||||
$id_map = $migration->getIdMap();
|
||||
try {
|
||||
$destination_ids = $destination_plugin->import($stub_row);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
$migration->getIdMap()->saveMessage($stub_row->getSourceIdValues(), $e->getMessage());
|
||||
$id_map->saveMessage($stub_row->getSourceIdValues(), $e->getMessage());
|
||||
}
|
||||
|
||||
if ($destination_ids) {
|
||||
$migration->getIdMap()->saveIdMapping($stub_row, $destination_ids, MigrateIdMapInterface::STATUS_NEEDS_UPDATE);
|
||||
$id_map->saveIdMapping($stub_row, $destination_ids, MigrateIdMapInterface::STATUS_NEEDS_UPDATE);
|
||||
}
|
||||
}
|
||||
if ($destination_ids) {
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\migrate\Plugin\migrate\process;
|
||||
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* Runs an array of arrays through its own process pipeline.
|
||||
*
|
||||
* The sub_process plugin accepts an array of associative arrays and runs each
|
||||
* one through its own process pipeline, producing a newly keyed associative
|
||||
* array of transformed values.
|
||||
*
|
||||
* Available configuration keys:
|
||||
* - process: the plugin(s) that will process each element of the source.
|
||||
* - key: runs the process pipeline for the key to determine a new dynamic
|
||||
* name.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* @code
|
||||
* source: Array
|
||||
* (
|
||||
* [upload] => Array
|
||||
* (
|
||||
* [0] => Array
|
||||
* (
|
||||
* [fid] => 1
|
||||
* [list] => 0
|
||||
* [description] => "File number 1"
|
||||
* )
|
||||
* [1] => Array
|
||||
* (
|
||||
* [fid] => 2
|
||||
* [list] => 1
|
||||
* [description] => "File number 2"
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* ...
|
||||
* @endcode
|
||||
*
|
||||
* The sub_process process plugin will take these arrays one at a time and run
|
||||
* its own process over each one:
|
||||
*
|
||||
* @code
|
||||
* process:
|
||||
* upload:
|
||||
* plugin: sub_process
|
||||
* source: upload
|
||||
* process:
|
||||
* target_id:
|
||||
* plugin: migration_lookup
|
||||
* migration: d6_file
|
||||
* source: fid
|
||||
* display: list
|
||||
* description: description
|
||||
* @endcode
|
||||
*
|
||||
* In this case, each item in the upload array will be processed by the
|
||||
* sub_process process plugin. The target_id will be found by looking up the
|
||||
* destination value from a previous migration. The display and description
|
||||
* fields will simply be mapped.
|
||||
*
|
||||
* In the next example, normally the array returned from sub_process will have
|
||||
* its original keys. If you need to change the key, it is possible for the
|
||||
* returned array to be keyed by one of the transformed values in the sub-array.
|
||||
*
|
||||
* @code
|
||||
* source: Array
|
||||
* (
|
||||
* [format] => 1
|
||||
* [name] => Filtered HTML
|
||||
* ...
|
||||
* [filters] => Array
|
||||
* (
|
||||
* [0] => Array
|
||||
* (
|
||||
* [module] => filter
|
||||
* [delta] => 2
|
||||
* [weight] => 0
|
||||
* )
|
||||
* [1] => Array
|
||||
* (
|
||||
* [module] => filter
|
||||
* [delta] => 0
|
||||
* [weight] => 1
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* ...
|
||||
*
|
||||
* process:
|
||||
* filters:
|
||||
* plugin: iterator
|
||||
* source: filters
|
||||
* key: "@id"
|
||||
* process:
|
||||
* id:
|
||||
* plugin: concat
|
||||
* source:
|
||||
* - module
|
||||
* - delta
|
||||
* delimiter: _
|
||||
* @endcode
|
||||
*
|
||||
* In the above example, the keys of the returned array would be filter_2 and
|
||||
* filter_0
|
||||
*
|
||||
* @see \Drupal\migrate\Plugin\MigrateProcessInterface
|
||||
*
|
||||
* @MigrateProcessPlugin(
|
||||
* id = "sub_process",
|
||||
* handle_multiples = TRUE
|
||||
* )
|
||||
*/
|
||||
class SubProcess extends ProcessPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
$return = [];
|
||||
if (is_array($value) || $value instanceof \Traversable) {
|
||||
foreach ($value as $key => $new_value) {
|
||||
$new_row = new Row($new_value, []);
|
||||
$migrate_executable->processRow($new_row, $this->configuration['process']);
|
||||
$destination = $new_row->getDestination();
|
||||
if (array_key_exists('key', $this->configuration)) {
|
||||
$key = $this->transformKey($key, $migrate_executable, $new_row);
|
||||
}
|
||||
$return[$key] = $destination;
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the process pipeline for the key to determine its dynamic name.
|
||||
*
|
||||
* @param string|int $key
|
||||
* The current key.
|
||||
* @param \Drupal\migrate\MigrateExecutableInterface $migrate_executable
|
||||
* The migrate executable helper class.
|
||||
* @param \Drupal\migrate\Row $row
|
||||
* The current row after processing.
|
||||
*
|
||||
* @return mixed
|
||||
* The transformed key.
|
||||
*/
|
||||
protected function transformKey($key, MigrateExecutableInterface $migrate_executable, Row $row) {
|
||||
$process = ['key' => $this->configuration['key']];
|
||||
$migrate_executable->processRow($row, $process, $key);
|
||||
return $row->getDestinationProperty('key');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function multiple() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,8 +28,8 @@ use Drupal\migrate\Plugin\MigrationInterface;
|
||||
* -
|
||||
* channel_machine_name: movies
|
||||
* channel_description: Movies
|
||||
* ids:
|
||||
* channel_machine_name:
|
||||
* ids:
|
||||
* channel_machine_name:
|
||||
* type: string
|
||||
* @endcode
|
||||
*
|
||||
|
||||
@@ -13,7 +13,49 @@ use Drupal\migrate\Plugin\MigrateSourceInterface;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* The base class for all source plugins.
|
||||
* The base class for source plugins.
|
||||
*
|
||||
* Available configuration keys:
|
||||
* - cache_counts: (optional) If set, cache the source count.
|
||||
* - skip_count: (optional) If set, do not attempt to count the source.
|
||||
* - track_changes: (optional) If set, track changes to incoming data.
|
||||
* - high_water_property: (optional) It is an array of name & alias values
|
||||
* (optional table alias). This high_water_property is typically a timestamp
|
||||
* or serial id showing what was the last imported record. Only content with a
|
||||
* higher value will be imported.
|
||||
*
|
||||
* The high_water_property and track_changes are mutually exclusive.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* @code
|
||||
* source:
|
||||
* plugin: some_source_plugin_name
|
||||
* cache_counts: true
|
||||
* track_changes: true
|
||||
* @endcode
|
||||
*
|
||||
* This example uses the plugin "some_source_plugin_name" and caches the count
|
||||
* of available source records to save calculating it every time count() is
|
||||
* called. Changes to incoming data are watched (because track_changes is true),
|
||||
* which can affect the result of prepareRow().
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* @code
|
||||
* source:
|
||||
* plugin: some_source_plugin_name
|
||||
* skip_count: true
|
||||
* high_water_property:
|
||||
* name: changed
|
||||
* alias: n
|
||||
* @endcode
|
||||
*
|
||||
* In this example, skip_count is true which means count() will not attempt to
|
||||
* count the available source records, but just always return -1 instead. The
|
||||
* high_water_property defines which field marks the last imported row of the
|
||||
* migration. This will get converted into a SQL condition that looks like
|
||||
* 'n.changed' or 'changed' if no alias.
|
||||
*
|
||||
* @see \Drupal\migrate\Plugin\MigratePluginManager
|
||||
* @see \Drupal\migrate\Annotation\MigrateSource
|
||||
@@ -177,7 +219,7 @@ abstract class SourcePluginBase extends PluginBase implements MigrateSourceInter
|
||||
* @return array
|
||||
* An array of the data for this source.
|
||||
*/
|
||||
protected abstract function initializeIterator();
|
||||
abstract protected function initializeIterator();
|
||||
|
||||
/**
|
||||
* Gets the module handler.
|
||||
@@ -541,4 +583,17 @@ abstract class SourcePluginBase extends PluginBase implements MigrateSourceInter
|
||||
$this->saveHighWater(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSourceModule() {
|
||||
if (!empty($this->configuration['source_module'])) {
|
||||
return $this->configuration['source_module'];
|
||||
}
|
||||
elseif (!empty($this->pluginDefinition['source_module'])) {
|
||||
return $this->pluginDefinition['source_module'];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,13 +15,37 @@ use Drupal\migrate\Plugin\RequirementsInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Sources whose data may be fetched via DBTNG.
|
||||
* Sources whose data may be fetched via a database connection.
|
||||
*
|
||||
* By default, an existing database connection with key 'migrate' and target
|
||||
* 'default' is used. These may be overridden with explicit 'key' and/or
|
||||
* 'target' configuration keys. In addition, if the configuration key 'database'
|
||||
* is present, it is used as a database connection information array to define
|
||||
* the connection.
|
||||
* Database configuration, which may appear either within the source plugin
|
||||
* configuration or in state, is structured as follows:
|
||||
*
|
||||
* 'key' - The database key name (defaults to 'migrate').
|
||||
* 'target' - The database target name (defaults to 'default').
|
||||
* 'database' - Database connection information as accepted by
|
||||
* Database::addConnectionInfo(). If not present, the key/target is assumed
|
||||
* to already be defined (e.g., in settings.php).
|
||||
*
|
||||
* This configuration info is obtained in the following order:
|
||||
*
|
||||
* 1. If the source plugin configuration contains a key 'database_state_key',
|
||||
* its value is taken as the name of a state key which contains an array
|
||||
* with the above database configuration.
|
||||
* 2. Otherwise, if the source plugin configuration contains 'key', the above
|
||||
* database configuration is obtained directly from the plugin configuration.
|
||||
* 3. Otherwise, if the state 'migrate.fallback_state_key' exists, its value is
|
||||
* taken as the name of a state key which contains an array with the above
|
||||
* database configuration.
|
||||
* 4. Otherwise, if a connection named 'migrate' exists, that is used as the
|
||||
* database connection.
|
||||
* 5. Otherwise, RequirementsException is thrown.
|
||||
*
|
||||
* It is strongly recommended that database connections be explicitly defined
|
||||
* via 'database_state_key' or in the source plugin configuration. Defining
|
||||
* migrate.fallback_state_key or a 'migrate' connection affects not only any
|
||||
* migrations intended to use that particular connection, but all
|
||||
* SqlBase-derived source plugins which do not have explicit database
|
||||
* configuration.
|
||||
*/
|
||||
abstract class SqlBase extends SourcePluginBase implements ContainerFactoryPluginInterface, RequirementsInterface {
|
||||
|
||||
@@ -101,16 +125,21 @@ abstract class SqlBase extends SourcePluginBase implements ContainerFactoryPlugi
|
||||
*/
|
||||
public function getDatabase() {
|
||||
if (!isset($this->database)) {
|
||||
// See if the database info is in state - if not, fallback to
|
||||
// configuration.
|
||||
// Look first for an explicit state key containing the configuration.
|
||||
if (isset($this->configuration['database_state_key'])) {
|
||||
$this->database = $this->setUpDatabase($this->state->get($this->configuration['database_state_key']));
|
||||
}
|
||||
// Next, use explicit configuration in the source plugin.
|
||||
elseif (isset($this->configuration['key'])) {
|
||||
$this->database = $this->setUpDatabase($this->configuration);
|
||||
}
|
||||
// Next, try falling back to the global state key.
|
||||
elseif (($fallback_state_key = $this->state->get('migrate.fallback_state_key'))) {
|
||||
$this->database = $this->setUpDatabase($this->state->get($fallback_state_key));
|
||||
}
|
||||
// If all else fails, let setUpDatabase() fallback to the 'migrate' key.
|
||||
else {
|
||||
$this->database = $this->setUpDatabase($this->configuration);
|
||||
$this->database = $this->setUpDatabase([]);
|
||||
}
|
||||
}
|
||||
return $this->database;
|
||||
@@ -274,11 +303,17 @@ abstract class SqlBase extends SourcePluginBase implements ContainerFactoryPlugi
|
||||
}
|
||||
// 2. If we are using high water marks, also include rows above the mark.
|
||||
// But, include all rows if the high water mark is not set.
|
||||
if ($this->getHighWaterProperty() && ($high_water = $this->getHighWater())) {
|
||||
if ($this->getHighWaterProperty()) {
|
||||
$high_water_field = $this->getHighWaterField();
|
||||
$conditions->condition($high_water_field, $high_water, '>');
|
||||
$high_water = $this->getHighWater();
|
||||
if ($high_water) {
|
||||
$conditions->condition($high_water_field, $high_water, '>');
|
||||
$condition_added = TRUE;
|
||||
}
|
||||
// Always sort by the high water field, to ensure that the first run
|
||||
// (before we have a high water value) also has the results in a
|
||||
// consistent order.
|
||||
$this->query->orderBy($high_water_field);
|
||||
$condition_added = TRUE;
|
||||
}
|
||||
if ($condition_added) {
|
||||
$this->query->condition($conditions);
|
||||
|
||||
@@ -77,6 +77,13 @@ class Row {
|
||||
*/
|
||||
protected $isStub = FALSE;
|
||||
|
||||
/**
|
||||
* The empty destination properties.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $emptyDestinationProperties = [];
|
||||
|
||||
/**
|
||||
* Constructs a \Drupal\Migrate\Row object.
|
||||
*
|
||||
@@ -229,6 +236,26 @@ class Row {
|
||||
NestedArray::unsetValue($this->destination, explode(static::PROPERTY_SEPARATOR, $property));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a destination to be empty.
|
||||
*
|
||||
* @param string $property
|
||||
* The destination property.
|
||||
*/
|
||||
public function setEmptyDestinationProperty($property) {
|
||||
$this->emptyDestinationProperties[] = $property;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the empty destination properties.
|
||||
*
|
||||
* @return array
|
||||
* An array of destination properties.
|
||||
*/
|
||||
public function getEmptyDestinationProperties() {
|
||||
return $this->emptyDestinationProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the whole destination array.
|
||||
*
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -4,8 +4,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
+3
-3
@@ -7,8 +7,8 @@ dependencies:
|
||||
- node
|
||||
- migrate
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
+2
-1
@@ -8,7 +8,8 @@ use Drupal\migrate\Plugin\migrate\source\SourcePluginBase;
|
||||
* A simple migrate source for our tests.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "migrate_external_translated_test"
|
||||
* id = "migrate_external_translated_test",
|
||||
* source_module = "migrate_external_translated_test"
|
||||
* )
|
||||
*/
|
||||
class MigrateExternalTranslatedTestSource extends SourcePluginBase {
|
||||
|
||||
+3
-3
@@ -6,8 +6,8 @@ package: Testing
|
||||
dependencies:
|
||||
- migrate
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
+3
-3
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
+3
-3
@@ -6,8 +6,8 @@ package: Testing
|
||||
dependencies:
|
||||
- migrate
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -18,13 +18,14 @@ class MigrateBundleTest extends MigrateTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['taxonomy', 'text'];
|
||||
public static $modules = ['taxonomy', 'text', 'user'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installEntitySchema('user');
|
||||
$this->installEntitySchema('taxonomy_vocabulary');
|
||||
$this->installEntitySchema('taxonomy_term');
|
||||
$this->installConfig(['taxonomy']);
|
||||
|
||||
@@ -10,6 +10,7 @@ use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
|
||||
use Drupal\migrate\Plugin\MigrateIdMapInterface;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_entity_test\Entity\StringIdEntityTest;
|
||||
|
||||
/**
|
||||
* Tests the EntityContentBase destination.
|
||||
@@ -204,4 +205,65 @@ class MigrateEntityContentBaseTest extends KernelTestBase {
|
||||
$this->assertEquals(123456789012, $map_row['destid1']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests empty destinations.
|
||||
*/
|
||||
public function testEmptyDestinations() {
|
||||
$this->enableModules(['migrate_entity_test']);
|
||||
$this->installEntitySchema('migrate_string_id_entity_test');
|
||||
|
||||
$definition = [
|
||||
'source' => [
|
||||
'plugin' => 'embedded_data',
|
||||
'data_rows' => [
|
||||
['id' => 123, 'version' => 'foo'],
|
||||
// This integer needs an 'int' schema with 'big' size. If 'destid1'
|
||||
// is not correctly taking the definition from the destination entity
|
||||
// type, the import will fail with an SQL exception.
|
||||
['id' => 123456789012, 'version' => 'bar'],
|
||||
],
|
||||
'ids' => [
|
||||
'id' => ['type' => 'integer', 'size' => 'big'],
|
||||
'version' => ['type' => 'string'],
|
||||
],
|
||||
'constants' => ['null' => NULL],
|
||||
],
|
||||
'process' => [
|
||||
'id' => 'id',
|
||||
'version' => 'version',
|
||||
],
|
||||
'destination' => [
|
||||
'plugin' => 'entity:migrate_string_id_entity_test',
|
||||
],
|
||||
];
|
||||
|
||||
$migration = \Drupal::service('plugin.manager.migration')
|
||||
->createStubMigration($definition);
|
||||
$executable = new MigrateExecutable($migration, new MigrateMessage());
|
||||
$executable->import();
|
||||
|
||||
/** @var \Drupal\migrate_entity_test\Entity\StringIdEntityTest $entity */
|
||||
$entity = StringIdEntityTest::load('123');
|
||||
$this->assertSame('foo', $entity->version->value);
|
||||
$entity = StringIdEntityTest::load('123456789012');
|
||||
$this->assertSame('bar', $entity->version->value);
|
||||
|
||||
// Rerun the migration forcing the version to NULL.
|
||||
$definition['process'] = [
|
||||
'id' => 'id',
|
||||
'version' => 'constants/null',
|
||||
];
|
||||
|
||||
$migration = \Drupal::service('plugin.manager.migration')
|
||||
->createStubMigration($definition);
|
||||
$executable = new MigrateExecutable($migration, new MigrateMessage());
|
||||
$executable->import();
|
||||
|
||||
/** @var \Drupal\migrate_entity_test\Entity\StringIdEntityTest $entity */
|
||||
$entity = StringIdEntityTest::load('123');
|
||||
$this->assertNull($entity->version->value);
|
||||
$entity = StringIdEntityTest::load('123456789012');
|
||||
$this->assertNull($entity->version->value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,13 +17,14 @@ class MigrateRollbackEntityConfigTest extends MigrateTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['field', 'taxonomy', 'text', 'language', 'config_translation'];
|
||||
public static $modules = ['field', 'taxonomy', 'text', 'language', 'config_translation', 'user'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installEntitySchema('user');
|
||||
$this->installEntitySchema('taxonomy_vocabulary');
|
||||
$this->installEntitySchema('taxonomy_term');
|
||||
$this->installConfig(['taxonomy']);
|
||||
|
||||
@@ -20,13 +20,14 @@ class MigrateRollbackTest extends MigrateTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['field', 'taxonomy', 'text'];
|
||||
public static $modules = ['field', 'taxonomy', 'text', 'user'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installEntitySchema('user');
|
||||
$this->installEntitySchema('taxonomy_vocabulary');
|
||||
$this->installEntitySchema('taxonomy_term');
|
||||
$this->installConfig(['taxonomy']);
|
||||
|
||||
@@ -39,7 +39,9 @@ abstract class MigrateSqlSourceTestBase extends MigrateSourceTestBase {
|
||||
->createTable($table, [
|
||||
// SQLite uses loose affinity typing, so it's OK for every field to
|
||||
// be a text field.
|
||||
'fields' => array_map(function() { return ['type' => 'text']; }, $pilot),
|
||||
'fields' => array_map(function () {
|
||||
return ['type' => 'text'];
|
||||
}, $pilot),
|
||||
]);
|
||||
|
||||
$fields = array_keys($pilot);
|
||||
|
||||
@@ -230,7 +230,9 @@ abstract class MigrateTestBase extends KernelTestBase implements MigrateMessageI
|
||||
$migration = $this->getMigration($migration);
|
||||
}
|
||||
/** @var \Drupal\migrate\Plugin\MigrationInterface $migration */
|
||||
$destination = array_map(function() { return NULL; }, $migration->getDestinationPlugin()->getIds());
|
||||
$destination = array_map(function () {
|
||||
return NULL;
|
||||
}, $migration->getDestinationPlugin()->getIds());
|
||||
$row = new Row($row, $migration->getSourcePlugin()->getIds());
|
||||
$migration->getIdMap()->saveIdMapping($row, $destination, $status);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Kernel;
|
||||
|
||||
use Drupal\comment\Entity\CommentType;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
|
||||
/**
|
||||
* Provides methods for testing node and comment combinations.
|
||||
*/
|
||||
trait NodeCommentCombinationTrait {
|
||||
|
||||
/**
|
||||
* Creates a node type with a corresponding comment type.
|
||||
*
|
||||
* @param string $node_type
|
||||
* The node type ID.
|
||||
* @param string $comment_type
|
||||
* (optional) The comment type ID, if not provided defaults to
|
||||
* comment_node_{type}.
|
||||
*/
|
||||
protected function createNodeCommentCombination($node_type, $comment_type = NULL) {
|
||||
if (!$comment_type) {
|
||||
$comment_type = "comment_node_$node_type";
|
||||
}
|
||||
NodeType::create([
|
||||
'type' => $node_type,
|
||||
'label' => $this->randomString(),
|
||||
])->save();
|
||||
|
||||
CommentType::create([
|
||||
'id' => $comment_type,
|
||||
'label' => $this->randomString(),
|
||||
'target_entity_type_id' => 'node',
|
||||
])->save();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -89,7 +89,9 @@ class MigrationPluginListTest extends KernelTestBase {
|
||||
// Any database-based source plugins should fail a requirements test in the
|
||||
// absence of a source database connection (e.g., a connection with the
|
||||
// 'migrate' key).
|
||||
$source_plugins = array_map(function ($migration_plugin) { return $migration_plugin->getSourcePlugin(); }, $migration_plugins);
|
||||
$source_plugins = array_map(function ($migration_plugin) {
|
||||
return $migration_plugin->getSourcePlugin();
|
||||
}, $migration_plugins);
|
||||
foreach ($source_plugins as $id => $source_plugin) {
|
||||
if ($source_plugin instanceof RequirementsInterface) {
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Kernel\Plugin;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\KernelTests\FileSystemModuleDiscoveryDataProviderTrait;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
|
||||
|
||||
/**
|
||||
* Tests that modules exist for all source and destination plugins.
|
||||
*
|
||||
* @group migrate_drupal_ui
|
||||
*/
|
||||
class MigrationProvidersExistTest extends MigrateDrupalTestBase {
|
||||
|
||||
use FileSystemModuleDiscoveryDataProviderTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['migration_provider_test'];
|
||||
|
||||
/**
|
||||
* Tests that modules exist for all source and destination plugins.
|
||||
*/
|
||||
public function testProvidersExist() {
|
||||
// Install all available modules.
|
||||
$module_handler = $this->container->get('module_handler');
|
||||
$modules = $this->coreModuleListDataProvider();
|
||||
$modules_enabled = $module_handler->getModuleList();
|
||||
$modules_to_enable = array_keys(array_diff_key($modules, $modules_enabled));
|
||||
$this->enableModules($modules_to_enable);
|
||||
|
||||
/** @var \Drupal\migrate\Plugin\MigrationPluginManager $plugin_manager */
|
||||
$plugin_manager = $this->container->get('plugin.manager.migration');
|
||||
// Get all the migrations
|
||||
$migrations = $plugin_manager->createInstances(array_keys($plugin_manager->getDefinitions()));
|
||||
// Ensure the test module was enabled.
|
||||
$this->assertTrue(array_key_exists('migration_provider_test', $migrations));
|
||||
$this->assertTrue(array_key_exists('migration_provider_no_annotation', $migrations));
|
||||
/** @var \Drupal\migrate\Plugin\Migration $migration */
|
||||
foreach ($migrations as $migration) {
|
||||
$source_module = $migration->getSourcePlugin()->getSourceModule();
|
||||
$destination_module = $migration->getDestinationPlugin()->getDestinationModule();
|
||||
$migration_id = $migration->getPluginId();
|
||||
if ($migration_id == 'migration_provider_test') {
|
||||
$this->assertFalse($source_module, new FormattableMarkup('Source module not found for @migration_id.', ['@migration_id' => $migration_id]));
|
||||
$this->assertFalse($destination_module, new FormattableMarkup('Destination module not found for @migration_id.', ['@migration_id' => $migration_id]));
|
||||
}
|
||||
elseif ($migration_id == 'migration_provider_no_annotation') {
|
||||
$this->assertFalse($source_module, new FormattableMarkup('Source module not found for @migration_id.', ['@migration_id' => $migration_id]));
|
||||
$this->assertTrue($destination_module, new FormattableMarkup('Destination module found for @migration_id.', ['@migration_id' => $migration_id]));
|
||||
}
|
||||
else {
|
||||
$this->assertTrue($source_module, new FormattableMarkup('Source module found for @migration_id.', ['@migration_id' => $migration_id]));
|
||||
$this->assertTrue($destination_module, new FormattableMarkup('Destination module found for @migration_id.', ['@migration_id' => $migration_id]));
|
||||
}
|
||||
// Destination module can't be migrate or migrate_drupal or migrate_drupal_ui
|
||||
$invalid_destinations = ['migrate', 'migrate_drupal', 'migrate_drupal_ui'];
|
||||
$this->assertNotContains($destination_module, $invalid_destinations, new FormattableMarkup('Invalid destination for @migration_id.', ['@migration_id' => $migration_id]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,8 +7,12 @@
|
||||
|
||||
namespace Drupal\Tests\migrate\Kernel;
|
||||
|
||||
use Drupal\migrate\Plugin\migrate\source\TestSqlBase;
|
||||
use Drupal\Core\Database\Query\ConditionInterface;
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\migrate\Exception\RequirementsException;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\migrate\Plugin\migrate\source\SqlBase;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
|
||||
/**
|
||||
* Tests the functionality of SqlBase.
|
||||
@@ -17,17 +21,47 @@ use Drupal\Core\Database\Database;
|
||||
*/
|
||||
class SqlBaseTest extends MigrateTestBase {
|
||||
|
||||
/**
|
||||
* The (probably mocked) migration under test.
|
||||
*
|
||||
* @var \Drupal\migrate\Plugin\MigrationInterface
|
||||
*/
|
||||
protected $migration;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->migration = $this->getMock(MigrationInterface::class);
|
||||
$this->migration->method('id')->willReturn('fubar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests different connection types.
|
||||
*/
|
||||
public function testConnectionTypes() {
|
||||
$sql_base = new TestSqlBase();
|
||||
$sql_base = new TestSqlBase([], $this->migration);
|
||||
|
||||
// Check the default values.
|
||||
$sql_base->setConfiguration([]);
|
||||
$this->assertIdentical($sql_base->getDatabase()->getTarget(), 'default');
|
||||
$this->assertIdentical($sql_base->getDatabase()->getKey(), 'migrate');
|
||||
// Verify that falling back to the default 'migrate' connection (defined in
|
||||
// the base class) works.
|
||||
$this->assertSame($sql_base->getDatabase()->getTarget(), 'default');
|
||||
$this->assertSame($sql_base->getDatabase()->getKey(), 'migrate');
|
||||
|
||||
// Verify the fallback state key overrides the 'migrate' connection.
|
||||
$target = 'test_fallback_target';
|
||||
$key = 'test_fallback_key';
|
||||
$config = ['target' => $target, 'key' => $key];
|
||||
$database_state_key = 'test_fallback_state';
|
||||
\Drupal::state()->set($database_state_key, $config);
|
||||
\Drupal::state()->set('migrate.fallback_state_key', $database_state_key);
|
||||
// Create a test connection using the default database configuration.
|
||||
Database::addConnectionInfo($key, $target, Database::getConnectionInfo('default')['default']);
|
||||
$this->assertSame($sql_base->getDatabase()->getTarget(), $target);
|
||||
$this->assertSame($sql_base->getDatabase()->getKey(), $key);
|
||||
|
||||
// Verify that setting explicit connection information overrides fallbacks.
|
||||
$target = 'test_db_target';
|
||||
$key = 'test_migrate_connection';
|
||||
$config = ['target' => $target, 'key' => $key];
|
||||
@@ -35,11 +69,11 @@ class SqlBaseTest extends MigrateTestBase {
|
||||
Database::addConnectionInfo($key, $target, Database::getConnectionInfo('default')['default']);
|
||||
|
||||
// Validate we have injected our custom key and target.
|
||||
$this->assertIdentical($sql_base->getDatabase()->getTarget(), $target);
|
||||
$this->assertIdentical($sql_base->getDatabase()->getKey(), $key);
|
||||
$this->assertSame($sql_base->getDatabase()->getTarget(), $target);
|
||||
$this->assertSame($sql_base->getDatabase()->getKey(), $key);
|
||||
|
||||
// Now test we can have SqlBase create the connection from an info array.
|
||||
$sql_base = new TestSqlBase();
|
||||
$sql_base = new TestSqlBase([], $this->migration);
|
||||
|
||||
$target = 'test_db_target2';
|
||||
$key = 'test_migrate_connection2';
|
||||
@@ -51,7 +85,7 @@ class SqlBaseTest extends MigrateTestBase {
|
||||
$sql_base->getDatabase();
|
||||
|
||||
// Validate the connection has been created with the right values.
|
||||
$this->assertIdentical(Database::getConnectionInfo($key)[$target], $database);
|
||||
$this->assertSame(Database::getConnectionInfo($key)[$target], $database);
|
||||
|
||||
// Now, test this all works when using state to store db info.
|
||||
$target = 'test_state_db_target';
|
||||
@@ -63,11 +97,11 @@ class SqlBaseTest extends MigrateTestBase {
|
||||
Database::addConnectionInfo($key, $target, Database::getConnectionInfo('default')['default']);
|
||||
|
||||
// Validate we have injected our custom key and target.
|
||||
$this->assertIdentical($sql_base->getDatabase()->getTarget(), $target);
|
||||
$this->assertIdentical($sql_base->getDatabase()->getKey(), $key);
|
||||
$this->assertSame($sql_base->getDatabase()->getTarget(), $target);
|
||||
$this->assertSame($sql_base->getDatabase()->getKey(), $key);
|
||||
|
||||
// Now test we can have SqlBase create the connection from an info array.
|
||||
$sql_base = new TestSqlBase();
|
||||
$sql_base = new TestSqlBase([], $this->migration);
|
||||
|
||||
$target = 'test_state_db_target2';
|
||||
$key = 'test_state_migrate_connection2';
|
||||
@@ -81,13 +115,68 @@ class SqlBaseTest extends MigrateTestBase {
|
||||
$sql_base->getDatabase();
|
||||
|
||||
// Validate the connection has been created with the right values.
|
||||
$this->assertIdentical(Database::getConnectionInfo($key)[$target], $database);
|
||||
$this->assertSame(Database::getConnectionInfo($key)[$target], $database);
|
||||
|
||||
// Verify that falling back to 'migrate' when the connection is not defined
|
||||
// throws a RequirementsException.
|
||||
\Drupal::state()->delete('migrate.fallback_state_key');
|
||||
$sql_base->setConfiguration([]);
|
||||
Database::renameConnection('migrate', 'fallback_connection');
|
||||
$this->setExpectedException(RequirementsException::class,
|
||||
'No database connection configured for source plugin');
|
||||
$sql_base->getDatabase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that SqlBase respects high-water values.
|
||||
*
|
||||
* @param mixed $high_water
|
||||
* (optional) The high-water value to set.
|
||||
* @param array $query_result
|
||||
* (optional) The expected query results.
|
||||
*
|
||||
* @dataProvider highWaterDataProvider
|
||||
*/
|
||||
public function testHighWater($high_water = NULL, array $query_result = []) {
|
||||
$configuration = [
|
||||
'high_water_property' => [
|
||||
'name' => 'order',
|
||||
],
|
||||
];
|
||||
$source = new TestSqlBase($configuration, $this->migration);
|
||||
|
||||
if ($high_water) {
|
||||
$source->getHighWaterStorage()->set($this->migration->id(), $high_water);
|
||||
}
|
||||
|
||||
$query_result = new \ArrayIterator($query_result);
|
||||
|
||||
$query = $this->getMock(SelectInterface::class);
|
||||
$query->method('execute')->willReturn($query_result);
|
||||
$query->expects($this->atLeastOnce())->method('orderBy')->with('order', 'ASC');
|
||||
|
||||
$condition_group = $this->getMock(ConditionInterface::class);
|
||||
$query->method('orConditionGroup')->willReturn($condition_group);
|
||||
|
||||
$source->setQuery($query);
|
||||
$source->rewind();
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for ::testHighWater().
|
||||
*
|
||||
* @return array
|
||||
* The scenarios to test.
|
||||
*/
|
||||
public function highWaterDataProvider() {
|
||||
return [
|
||||
'no high-water value set' => [],
|
||||
'high-water value set' => [33],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Drupal\migrate\Plugin\migrate\source;
|
||||
|
||||
/**
|
||||
* A dummy source to help with testing SqlBase.
|
||||
*
|
||||
@@ -96,10 +185,22 @@ namespace Drupal\migrate\Plugin\migrate\source;
|
||||
class TestSqlBase extends SqlBase {
|
||||
|
||||
/**
|
||||
* Overrides the constructor so we can create one easily.
|
||||
* The query to execute.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Query\SelectInterface
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->state = \Drupal::state();
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* Overrides the constructor so we can create one easily.
|
||||
*
|
||||
* @param array $configuration
|
||||
* The plugin instance configuration.
|
||||
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
|
||||
* (optional) The migration being run.
|
||||
*/
|
||||
public function __construct(array $configuration = [], MigrationInterface $migration = NULL) {
|
||||
parent::__construct($configuration, 'sql_base', [], $migration, \Drupal::state());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,6 +234,25 @@ class TestSqlBase extends SqlBase {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {}
|
||||
public function query() {
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the query to execute.
|
||||
*
|
||||
* @param \Drupal\Core\Database\Query\SelectInterface $query
|
||||
* The query to execute.
|
||||
*/
|
||||
public function setQuery(SelectInterface $query) {
|
||||
$this->query = $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHighWaterStorage() {
|
||||
return parent::getHighWaterStorage();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
namespace Drupal\Tests\migrate\Unit\Event;
|
||||
|
||||
use Drupal\migrate\Event\EventBase;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\migrate\Event\EventBase
|
||||
* @group migrate
|
||||
*/
|
||||
class EventBaseTest extends \PHPUnit_Framework_TestCase {
|
||||
class EventBaseTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* Test getMigration method.
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
namespace Drupal\Tests\migrate\Unit\Event;
|
||||
|
||||
use Drupal\migrate\Event\MigrateImportEvent;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\migrate\Event\MigrateImportEvent
|
||||
* @group migrate
|
||||
*/
|
||||
class MigrateImportEventTest extends \PHPUnit_Framework_TestCase {
|
||||
class MigrateImportEventTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* Test getMigration method.
|
||||
|
||||
@@ -439,6 +439,33 @@ class MigrateExecutableTest extends MigrateTestCase {
|
||||
$this->executable->processRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the processRow method.
|
||||
*/
|
||||
public function testProcessRowEmptyDestination() {
|
||||
$expected = [
|
||||
'test' => 'test destination',
|
||||
'test1' => 'test1 destination',
|
||||
'test2' => NULL,
|
||||
];
|
||||
$row = new Row();
|
||||
$plugins = [];
|
||||
foreach ($expected as $key => $value) {
|
||||
$plugin = $this->prophesize(MigrateProcessInterface::class);
|
||||
$plugin->getPluginDefinition()->willReturn([]);
|
||||
$plugin->transform(NULL, $this->executable, $row, $key)->willReturn($value);
|
||||
$plugin->multiple()->willReturn(TRUE);
|
||||
$plugins[$key][0] = $plugin->reveal();
|
||||
}
|
||||
$this->migration->method('getProcessPlugins')->willReturn($plugins);
|
||||
$this->executable->processRow($row);
|
||||
foreach ($expected as $key => $value) {
|
||||
$this->assertSame($value, $row->getDestinationProperty($key));
|
||||
}
|
||||
$this->assertCount(2, $row->getDestination());
|
||||
$this->assertSame(['test2'], $row->getEmptyDestinationProperties());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a mock migration source instance.
|
||||
*
|
||||
|
||||
@@ -61,12 +61,12 @@ abstract class MigrateTestCase extends UnitTestCase {
|
||||
// on the test class and use a return callback.
|
||||
$migration->expects($this->any())
|
||||
->method('getStatus')
|
||||
->willReturnCallback(function() {
|
||||
->willReturnCallback(function () {
|
||||
return $this->migrationStatus;
|
||||
});
|
||||
$migration->expects($this->any())
|
||||
->method('setStatus')
|
||||
->willReturnCallback(function($status) {
|
||||
->willReturnCallback(function ($status) {
|
||||
$this->migrationStatus = $status;
|
||||
});
|
||||
|
||||
@@ -147,7 +147,9 @@ abstract class MigrateTestCase extends UnitTestCase {
|
||||
protected function createSchemaFromRow(array $row) {
|
||||
// SQLite uses loose ("affinity") typing, so it is OK for every column to be
|
||||
// a text field.
|
||||
$fields = array_map(function() { return ['type' => 'text']; }, $row);
|
||||
$fields = array_map(function () {
|
||||
return ['type' => 'text'];
|
||||
}, $row);
|
||||
return ['fields' => $fields];
|
||||
}
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ class TestMigrationMock extends Migration {
|
||||
/**
|
||||
* The values passed into set().
|
||||
*
|
||||
* @var array $set
|
||||
* @var array
|
||||
*/
|
||||
public $set = [];
|
||||
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ class EntityContentBaseTest extends UnitTestCase {
|
||||
$this->storage->getEntityType()->willReturn($entity_type->reveal());
|
||||
|
||||
$destination = new EntityTestDestination(
|
||||
[ 'translations' => TRUE ],
|
||||
['translations' => TRUE],
|
||||
'',
|
||||
[],
|
||||
$this->migration->reveal(),
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
|
||||
namespace Drupal\Tests\migrate\Unit\process;
|
||||
|
||||
@trigger_error('The ' . __NAMESPACE__ . '\DedupeEntityTest is deprecated in
|
||||
Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\MakeUniqueEntityFieldTest', E_USER_DEPRECATED);
|
||||
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Entity\Query\QueryInterface;
|
||||
@@ -14,14 +11,14 @@ use Drupal\Component\Utility\Unicode;
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\migrate\Plugin\migrate\process\DedupeEntity
|
||||
* @group migrate
|
||||
* @group legacy
|
||||
*/
|
||||
class DedupeEntityTest extends MigrateProcessTestCase {
|
||||
|
||||
/**
|
||||
* The mock entity query.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\Query\QueryInterface
|
||||
* @var \Drupal\Core\Entity\Query\QueryFactory
|
||||
* @var \Drupal\Core\Entity\Query\QueryInterface|\Drupal\Core\Entity\Query\QueryFactory
|
||||
*/
|
||||
protected $entityQuery;
|
||||
|
||||
@@ -168,7 +165,9 @@ class DedupeEntityTest extends MigrateProcessTestCase {
|
||||
->will($this->returnValue($this->entityQuery));
|
||||
$this->entityQuery->expects($this->exactly($count + 1))
|
||||
->method('execute')
|
||||
->will($this->returnCallback(function () use (&$count) { return $count--;}));
|
||||
->will($this->returnCallback(function () use (&$count) {
|
||||
return $count--;
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Unit\process;
|
||||
use Drupal\migrate\Plugin\migrate\process\Flatten;
|
||||
|
||||
use Drupal\migrate\Plugin\migrate\process\Flatten;
|
||||
|
||||
/**
|
||||
* Tests the flatten plugin.
|
||||
|
||||
@@ -48,7 +48,9 @@ class GetTest extends MigrateProcessTestCase {
|
||||
$this->plugin->setSource(['test1', 'test2']);
|
||||
$this->row->expects($this->exactly(2))
|
||||
->method('getSourceProperty')
|
||||
->will($this->returnCallback(function ($argument) use ($map) { return $map[$argument]; } ));
|
||||
->will($this->returnCallback(function ($argument) use ($map) {
|
||||
return $map[$argument];
|
||||
}));
|
||||
$value = $this->plugin->transform(NULL, $this->migrateExecutable, $this->row, 'destinationproperty');
|
||||
$this->assertSame($value, ['source_value1', 'source_value2']);
|
||||
}
|
||||
@@ -79,7 +81,9 @@ class GetTest extends MigrateProcessTestCase {
|
||||
$this->plugin->setSource(['test1', '@@test2', '@@test3', 'test4']);
|
||||
$this->row->expects($this->exactly(4))
|
||||
->method('getSourceProperty')
|
||||
->will($this->returnCallback(function ($argument) use ($map) { return $map[$argument]; } ));
|
||||
->will($this->returnCallback(function ($argument) use ($map) {
|
||||
return $map[$argument];
|
||||
}));
|
||||
$value = $this->plugin->transform(NULL, $this->migrateExecutable, $this->row, 'destinationproperty');
|
||||
$this->assertSame($value, ['source_value1', 'source_value2', 'source_value3', 'source_value4']);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ class IteratorTest extends MigrateTestCase {
|
||||
|
||||
/**
|
||||
* Tests the iterator process plugin.
|
||||
*
|
||||
* @group legacy
|
||||
*/
|
||||
public function testIterator() {
|
||||
$migration = $this->getMigration();
|
||||
|
||||
@@ -17,8 +17,7 @@ class MakeUniqueEntityFieldTest extends MigrateProcessTestCase {
|
||||
/**
|
||||
* The mock entity query.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\Query\QueryInterface
|
||||
* @var \Drupal\Core\Entity\Query\QueryFactory
|
||||
* @var \Drupal\Core\Entity\Query\QueryInterface|\Drupal\Core\Entity\Query\QueryFactory
|
||||
*/
|
||||
protected $entityQuery;
|
||||
|
||||
@@ -165,7 +164,9 @@ class MakeUniqueEntityFieldTest extends MigrateProcessTestCase {
|
||||
->will($this->returnValue($this->entityQuery));
|
||||
$this->entityQuery->expects($this->exactly($count + 1))
|
||||
->method('execute')
|
||||
->will($this->returnCallback(function () use (&$count) { return $count--;}));
|
||||
->will($this->returnCallback(function () use (&$count) {
|
||||
return $count--;
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -199,4 +199,43 @@ class MigrationLookupTest extends MigrateProcessTestCase {
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that a message is successfully created if import fails.
|
||||
*/
|
||||
public function testImportException() {
|
||||
$migration_plugin = $this->prophesize(MigrationInterface::class);
|
||||
$migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class);
|
||||
$process_plugin_manager = $this->prophesize(MigratePluginManager::class);
|
||||
|
||||
$destination_id_map = $this->prophesize(MigrateIdMapInterface::class);
|
||||
$destination_migration = $this->prophesize('Drupal\migrate\Plugin\Migration');
|
||||
$destination_migration->getIdMap()->willReturn($destination_id_map->reveal());
|
||||
$migration_plugin_manager->createInstances(['destination_migration'])
|
||||
->willReturn(['destination_migration' => $destination_migration->reveal()]);
|
||||
$destination_id_map->lookupDestinationId([1])->willReturn(NULL);
|
||||
$destination_id_map->saveMessage(Argument::any(), Argument::any())->willReturn(NULL);
|
||||
$destination_id_map->saveIdMapping(Argument::any(), Argument::any(), Argument::any())->shouldNotBeCalled();
|
||||
|
||||
$configuration = [
|
||||
'no_stub' => FALSE,
|
||||
'migration' => 'destination_migration',
|
||||
];
|
||||
|
||||
$destination_migration->id()->willReturn('destination_migration');
|
||||
$destination_migration->getDestinationPlugin(TRUE)->shouldBeCalled();
|
||||
$destination_migration->getProcess()->willReturn([]);
|
||||
$destination_migration->getSourceConfiguration()->willReturn([]);
|
||||
|
||||
$source_plugin = $this->prophesize(MigrateSourceInterface::class);
|
||||
$source_plugin->getIds()->willReturn(['nid']);
|
||||
$destination_migration->getSourcePlugin()->willReturn($source_plugin->reveal());
|
||||
$destination_plugin = $this->prophesize(MigrateDestinationInterface::class);
|
||||
$e = new \Exception();
|
||||
$destination_plugin->import(Argument::any())->willThrow($e);
|
||||
$destination_migration->getDestinationPlugin(TRUE)->willReturn($destination_plugin->reveal());
|
||||
|
||||
$migration = new MigrationLookup($configuration, '', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal());
|
||||
$migration->transform(1, $this->migrateExecutable, $this->row, '');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
|
||||
namespace Drupal\Tests\migrate\Unit\process;
|
||||
|
||||
@trigger_error('The ' . __NAMESPACE__ . '\MigrationTest is deprecated in
|
||||
Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\MigrationLookupTest', E_USER_DEPRECATED);
|
||||
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\migrate\MigrateSkipProcessException;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
@@ -17,11 +14,9 @@ use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
|
||||
use Prophecy\Argument;
|
||||
|
||||
/**
|
||||
* @deprecated in Drupal 8.4.x, to be removed before Drupal 9.0.x. Use
|
||||
* \Drupal\Tests\migrate\Unit\process\MigrationLookupTest instead.
|
||||
*
|
||||
* @coversDefaultClass \Drupal\migrate\Plugin\migrate\process\Migration
|
||||
* @group migrate
|
||||
* @group legacy
|
||||
*/
|
||||
class MigrationTest extends MigrateProcessTestCase {
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Unit\process;
|
||||
|
||||
use Drupal\migrate\MigrateExecutable;
|
||||
use Drupal\migrate\Plugin\migrate\process\Get;
|
||||
use Drupal\migrate\Plugin\migrate\process\SubProcess;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\Tests\migrate\Unit\MigrateTestCase;
|
||||
|
||||
/**
|
||||
* Tests the sub_process process plugin.
|
||||
*
|
||||
* @group migrate
|
||||
*/
|
||||
class SubProcessTest extends MigrateTestCase {
|
||||
|
||||
/**
|
||||
* The sub_process plugin being tested.
|
||||
*
|
||||
* @var \Drupal\migrate\Plugin\migrate\process\SubProcess
|
||||
*/
|
||||
protected $plugin;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $migrationConfiguration = [
|
||||
'id' => 'test',
|
||||
];
|
||||
|
||||
/**
|
||||
* Tests the sub_process process plugin.
|
||||
*/
|
||||
public function testSubProcess() {
|
||||
$migration = $this->getMigration();
|
||||
// Set up the properties for the sub_process.
|
||||
$configuration = [
|
||||
'process' => [
|
||||
'foo' => 'source_foo',
|
||||
'id' => 'source_id',
|
||||
],
|
||||
'key' => '@id',
|
||||
];
|
||||
$plugin = new SubProcess($configuration, 'sub_process', []);
|
||||
// Manually create the plugins. Migration::getProcessPlugins does this
|
||||
// normally but the plugin system is not available.
|
||||
foreach ($configuration['process'] as $destination => $source) {
|
||||
$sub_process_plugins[$destination][] = new Get(['source' => $source], 'get', []);
|
||||
}
|
||||
$migration->expects($this->at(1))
|
||||
->method('getProcessPlugins')
|
||||
->willReturn($sub_process_plugins);
|
||||
// Set up the key plugins.
|
||||
$key_plugin['key'][] = new Get(['source' => '@id'], 'get', []);
|
||||
$migration->expects($this->at(2))
|
||||
->method('getProcessPlugins')
|
||||
->will($this->returnValue($key_plugin));
|
||||
$event_dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||
$migrate_executable = new MigrateExecutable($migration, $this->getMock('Drupal\migrate\MigrateMessageInterface'), $event_dispatcher);
|
||||
|
||||
// The current value of the pipeline.
|
||||
$current_value = [
|
||||
[
|
||||
'source_foo' => 'test',
|
||||
'source_id' => 42,
|
||||
],
|
||||
];
|
||||
// This is not used but the interface requires it, so create an empty row.
|
||||
$row = new Row();
|
||||
|
||||
// After transformation, check to make sure that source_foo and source_id's
|
||||
// values ended up in the proper destinations, and that the value of the
|
||||
// key (@id) is the same as the destination ID (42).
|
||||
$new_value = $plugin->transform($current_value, $migrate_executable, $row, 'test');
|
||||
$this->assertSame(count($new_value), 1);
|
||||
$this->assertSame(count($new_value[42]), 2);
|
||||
$this->assertSame($new_value[42]['foo'], 'test');
|
||||
$this->assertSame($new_value[42]['id'], 42);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user