Update to Drupal 8.1.8. For more information, see https://www.drupal.org/project/drupal/releases/8.1.8
This commit is contained in:
parent
e9f047ccf8
commit
f9f23cdf38
312 changed files with 6751 additions and 1546 deletions
|
@ -94,8 +94,10 @@ abstract class DestinationBase extends PluginBase implements MigrateDestinationI
|
|||
*
|
||||
* @param array $id_map
|
||||
* The map row data for the item.
|
||||
* @param int $update_action
|
||||
* The rollback action to take if we are updating an existing item.
|
||||
*/
|
||||
protected function setRollbackAction(array $id_map) {
|
||||
protected function setRollbackAction(array $id_map, $update_action = MigrateIdMapInterface::ROLLBACK_PRESERVE) {
|
||||
// If the entity we're updating was previously migrated by us, preserve the
|
||||
// existing rollback action.
|
||||
if (isset($id_map['sourceid1'])) {
|
||||
|
@ -104,7 +106,7 @@ abstract class DestinationBase extends PluginBase implements MigrateDestinationI
|
|||
// Otherwise, we're updating an entity which already existed on the
|
||||
// destination and want to make sure we do not delete it on rollback.
|
||||
else {
|
||||
$this->rollbackAction = MigrateIdMapInterface::ROLLBACK_PRESERVE;
|
||||
$this->rollbackAction = $update_action;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,8 @@ abstract class Entity extends DestinationBase implements ContainerFactoryPluginI
|
|||
protected function getEntity(Row $row, array $old_destination_id_values) {
|
||||
$entity_id = reset($old_destination_id_values) ?: $this->getEntityId($row);
|
||||
if (!empty($entity_id) && ($entity = $this->storage->load($entity_id))) {
|
||||
$this->updateEntity($entity, $row);
|
||||
// Allow updateEntity() to change the entity.
|
||||
$entity = $this->updateEntity($entity, $row) ?: $entity;
|
||||
}
|
||||
else {
|
||||
// Attempt to ensure we always have a bundle.
|
||||
|
|
|
@ -7,6 +7,7 @@ use Drupal\Core\Entity\EntityInterface;
|
|||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Field\FieldTypePluginManagerInterface;
|
||||
use Drupal\Core\TypedData\TranslatableInterface;
|
||||
use Drupal\Core\TypedData\TypedDataInterface;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\MigrateException;
|
||||
|
@ -85,7 +86,12 @@ class EntityContentBase extends Entity {
|
|||
if (!$entity) {
|
||||
throw new MigrateException('Unable to get entity');
|
||||
}
|
||||
return $this->save($entity, $old_destination_id_values);
|
||||
|
||||
$ids = $this->save($entity, $old_destination_id_values);
|
||||
if (!empty($this->configuration['translations'])) {
|
||||
$ids[] = $entity->language()->getId();
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,12 +110,32 @@ class EntityContentBase extends Entity {
|
|||
return array($entity->id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether this destination is for translations.
|
||||
*
|
||||
* @return bool
|
||||
* Whether this destination is for translations.
|
||||
*/
|
||||
protected function isTranslationDestination() {
|
||||
return !empty($this->configuration['translations']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$id_key = $this->getKey('id');
|
||||
$ids[$id_key]['type'] = 'integer';
|
||||
|
||||
if ($this->isTranslationDestination()) {
|
||||
if ($key = $this->getKey('langcode')) {
|
||||
$ids[$key]['type'] = 'string';
|
||||
}
|
||||
else {
|
||||
throw new MigrateException('This entity type does not support translation.');
|
||||
}
|
||||
}
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
|
@ -120,8 +146,29 @@ class EntityContentBase extends Entity {
|
|||
* The entity to update.
|
||||
* @param \Drupal\migrate\Row $row
|
||||
* The row object to update from.
|
||||
*
|
||||
* @return NULL|\Drupal\Core\Entity\EntityInterface
|
||||
* An updated entity, or NULL if it's the same as the one passed in.
|
||||
*/
|
||||
protected function updateEntity(EntityInterface $entity, Row $row) {
|
||||
// By default, an update will be preserved.
|
||||
$rollback_action = MigrateIdMapInterface::ROLLBACK_PRESERVE;
|
||||
|
||||
// Make sure we have the right translation.
|
||||
if ($this->isTranslationDestination()) {
|
||||
$property = $this->storage->getEntityType()->getKey('langcode');
|
||||
if ($row->hasDestinationProperty($property)) {
|
||||
$language = $row->getDestinationProperty($property);
|
||||
if (!$entity->hasTranslation($language)) {
|
||||
$entity->addTranslation($language);
|
||||
|
||||
// We're adding a translation, so delete it on rollback.
|
||||
$rollback_action = MigrateIdMapInterface::ROLLBACK_DELETE;
|
||||
}
|
||||
$entity = $entity->getTranslation($language);
|
||||
}
|
||||
}
|
||||
|
||||
// If the migration has specified a list of properties to be overwritten,
|
||||
// clone the row with an empty set of destination values, and re-add only
|
||||
// the specified properties.
|
||||
|
@ -140,7 +187,10 @@ class EntityContentBase extends Entity {
|
|||
}
|
||||
}
|
||||
|
||||
$this->setRollbackAction($row->getIdMap());
|
||||
$this->setRollbackAction($row->getIdMap(), $rollback_action);
|
||||
|
||||
// We might have a different (translated) entity, so return it.
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,4 +235,32 @@ class EntityContentBase extends Entity {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rollback(array $destination_identifier) {
|
||||
if ($this->isTranslationDestination()) {
|
||||
// Attempt to remove the translation.
|
||||
$entity = $this->storage->load(reset($destination_identifier));
|
||||
if ($entity && $entity instanceof TranslatableInterface) {
|
||||
if ($key = $this->getKey('langcode')) {
|
||||
if (isset($destination_identifier[$key])) {
|
||||
$langcode = $destination_identifier[$key];
|
||||
if ($entity->hasTranslation($langcode)) {
|
||||
// Make sure we don't remove the default translation.
|
||||
$translation = $entity->getTranslation($langcode);
|
||||
if (!$translation->isDefaultTranslation()) {
|
||||
$entity->removeTranslation($langcode);
|
||||
$entity->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
parent::rollback($destination_identifier);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@ class Migration extends ProcessPluginBase implements ContainerFactoryPluginInter
|
|||
$source_id_values[$migration_id] = $value;
|
||||
}
|
||||
// Break out of the loop as soon as a destination ID is found.
|
||||
if ($destination_ids = $migration->getIdMap()->lookupDestinationID($source_id_values[$migration_id])) {
|
||||
if ($destination_ids = $migration->getIdMap()->lookupDestinationId($source_id_values[$migration_id])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ class Migration extends ProcessPluginBase implements ContainerFactoryPluginInter
|
|||
*
|
||||
* @throws \Drupal\migrate\MigrateSkipProcessException
|
||||
*/
|
||||
protected function skipOnEmpty($value) {
|
||||
protected function skipOnEmpty(array $value) {
|
||||
if (!array_filter($value)) {
|
||||
throw new MigrateSkipProcessException();
|
||||
}
|
||||
|
|
41
core/modules/migrate/src/Plugin/migrate/process/Substr.php
Normal file
41
core/modules/migrate/src/Plugin/migrate/process/Substr.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\migrate\Plugin\migrate\process;
|
||||
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate\MigrateException;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
|
||||
/**
|
||||
* This plugin returns a substring of the current value.
|
||||
*
|
||||
* @MigrateProcessPlugin(
|
||||
* id = "substr"
|
||||
* )
|
||||
*/
|
||||
class Substr extends ProcessPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
$start = isset($this->configuration['start']) ? $this->configuration['start'] : 0;
|
||||
if (!is_int($start)) {
|
||||
throw new MigrateException('The start position configuration value should be an integer. Omit this key to capture from the beginning of the string.');
|
||||
}
|
||||
$length = isset($this->configuration['length']) ? $this->configuration['length'] : NULL;
|
||||
if (!is_null($length) && !is_int($length)) {
|
||||
throw new MigrateException('The character length configuration value should be an integer. Omit this key to capture from the start position to the end of the string.');
|
||||
}
|
||||
if (!is_string($value)) {
|
||||
throw new MigrateException('The input value must be a string.');
|
||||
}
|
||||
|
||||
// Use optional start or length to return a portion of $value.
|
||||
$new_value = Unicode::substr($value, $start, $length);
|
||||
return $new_value;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
name: 'Migration external translated test'
|
||||
type: module
|
||||
package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
dependencies:
|
||||
- node
|
||||
- migrate
|
|
@ -0,0 +1,19 @@
|
|||
id: external_translated_test_node
|
||||
label: External translated content
|
||||
source:
|
||||
plugin: migrate_external_translated_test
|
||||
default_lang: true
|
||||
constants:
|
||||
type: external_test
|
||||
process:
|
||||
type: constants/type
|
||||
title: title
|
||||
langcode:
|
||||
plugin: static_map
|
||||
source: lang
|
||||
map:
|
||||
English: en
|
||||
French: fr
|
||||
Spanish: es
|
||||
destination:
|
||||
plugin: entity:node
|
|
@ -0,0 +1,27 @@
|
|||
id: external_translated_test_node_translation
|
||||
label: External translated content translations
|
||||
source:
|
||||
plugin: migrate_external_translated_test
|
||||
default_lang: false
|
||||
constants:
|
||||
type: external_test
|
||||
process:
|
||||
nid:
|
||||
plugin: migration
|
||||
source: name
|
||||
migration: external_translated_test_node
|
||||
type: constants/type
|
||||
title: title
|
||||
langcode:
|
||||
plugin: static_map
|
||||
source: lang
|
||||
map:
|
||||
English: en
|
||||
French: fr
|
||||
Spanish: es
|
||||
destination:
|
||||
plugin: entity:node
|
||||
translations: true
|
||||
migration_dependencies:
|
||||
required:
|
||||
- external_translated_test_node
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\migrate_external_translated_test\Plugin\migrate\source;
|
||||
|
||||
use Drupal\migrate\Plugin\migrate\source\SourcePluginBase;
|
||||
|
||||
/**
|
||||
* A simple migrate source for our tests.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "migrate_external_translated_test"
|
||||
* )
|
||||
*/
|
||||
class MigrateExternalTranslatedTestSource extends SourcePluginBase {
|
||||
|
||||
/**
|
||||
* The data to import.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $import = [
|
||||
['name' => 'cat', 'title' => 'Cat', 'lang' => 'English'],
|
||||
['name' => 'cat', 'title' => 'Chat', 'lang' => 'French'],
|
||||
['name' => 'cat', 'title' => 'Gato', 'lang' => 'Spanish'],
|
||||
['name' => 'dog', 'title' => 'Dog', 'lang' => 'English'],
|
||||
['name' => 'dog', 'title' => 'Chien', 'lang' => 'French'],
|
||||
['name' => 'monkey', 'title' => 'Monkey', 'lang' => 'English'],
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return [
|
||||
'name' => $this->t('Unique name'),
|
||||
'title' => $this->t('Title'),
|
||||
'lang' => $this->t('Language'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['name']['type'] = 'string';
|
||||
if (!$this->configuration['default_lang']) {
|
||||
$ids['lang']['type'] = 'string';
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initializeIterator() {
|
||||
$data = [];
|
||||
|
||||
// Keep the rows with the right languages.
|
||||
$want_default = $this->configuration['default_lang'];
|
||||
foreach ($this->import as $row) {
|
||||
$is_english = $row['lang'] == 'English';
|
||||
if ($want_default == $is_english) {
|
||||
$data[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
return new \ArrayIterator($data);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Kernel;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
|
||||
use Drupal\migrate\Plugin\MigrateIdMapInterface;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* Tests the EntityContentBase destination.
|
||||
*
|
||||
* @group migrate
|
||||
*/
|
||||
class MigrateEntityContentBaseTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['migrate', 'user', 'language', 'entity_test'];
|
||||
|
||||
/**
|
||||
* The storage for entity_test_mul.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\ContentEntityStorageInterface
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* A content migrate destination.
|
||||
*
|
||||
* @var \Drupal\migrate\Plugin\MigrateDestinationInterface
|
||||
*/
|
||||
protected $destination;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installEntitySchema('entity_test_mul');
|
||||
|
||||
ConfigurableLanguage::createFromLangcode('en')->save();
|
||||
ConfigurableLanguage::createFromLangcode('fr')->save();
|
||||
|
||||
$this->storage = $this->container->get('entity.manager')->getStorage('entity_test_mul');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the existing translations of an entity.
|
||||
*
|
||||
* @param int $id
|
||||
* The entity ID.
|
||||
* @param string $default
|
||||
* The expected default translation language code.
|
||||
* @param string[] $others
|
||||
* The expected other translation language codes.
|
||||
*/
|
||||
protected function assertTranslations($id, $default, $others = []) {
|
||||
$entity = $this->storage->load($id);
|
||||
$this->assertTrue($entity, "Entity exists");
|
||||
$this->assertEquals($default, $entity->language()->getId(), "Entity default translation");
|
||||
$translations = array_keys($entity->getTranslationLanguages(FALSE));
|
||||
sort($others);
|
||||
sort($translations);
|
||||
$this->assertEquals($others, $translations, "Entity translations");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the destination plugin to test.
|
||||
*
|
||||
* @param array $configuration
|
||||
* The plugin configuration.
|
||||
*/
|
||||
protected function createDestination(array $configuration) {
|
||||
$this->destination = new EntityContentBase(
|
||||
$configuration,
|
||||
'fake_plugin_id',
|
||||
[],
|
||||
$this->getMock(MigrationInterface::class),
|
||||
$this->storage,
|
||||
[],
|
||||
$this->container->get('entity.manager'),
|
||||
$this->container->get('plugin.manager.field.field_type')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test importing and rolling back translated entities.
|
||||
*/
|
||||
public function testTranslated() {
|
||||
// Create a destination.
|
||||
$this->createDestination(['translations' => TRUE]);
|
||||
|
||||
// Create some pre-existing entities.
|
||||
$this->storage->create(['id' => 1, 'langcode' => 'en'])->save();
|
||||
$this->storage->create(['id' => 2, 'langcode' => 'fr'])->save();
|
||||
$translated = $this->storage->create(['id' => 3, 'langcode' => 'en']);
|
||||
$translated->save();
|
||||
$translated->addTranslation('fr')->save();
|
||||
|
||||
// Pre-assert that things are as expected.
|
||||
$this->assertTranslations(1, 'en');
|
||||
$this->assertTranslations(2, 'fr');
|
||||
$this->assertTranslations(3, 'en', ['fr']);
|
||||
$this->assertFalse($this->storage->load(4));
|
||||
|
||||
$destination_rows = [
|
||||
// Existing default translation.
|
||||
['id' => 1, 'langcode' => 'en', 'action' => MigrateIdMapInterface::ROLLBACK_PRESERVE],
|
||||
// New translation.
|
||||
['id' => 2, 'langcode' => 'en', 'action' => MigrateIdMapInterface::ROLLBACK_DELETE],
|
||||
// Existing non-default translation.
|
||||
['id' => 3, 'langcode' => 'fr', 'action' => MigrateIdMapInterface::ROLLBACK_PRESERVE],
|
||||
// Brand new row.
|
||||
['id' => 4, 'langcode' => 'fr', 'action' => MigrateIdMapInterface::ROLLBACK_DELETE],
|
||||
];
|
||||
$rollback_actions = [];
|
||||
|
||||
// Import some rows.
|
||||
foreach ($destination_rows as $idx => $destination_row) {
|
||||
$row = new Row([], []);
|
||||
foreach ($destination_row as $key => $value) {
|
||||
$row->setDestinationProperty($key, $value);
|
||||
}
|
||||
$this->destination->import($row);
|
||||
|
||||
// Check that the rollback action is correct, and save it.
|
||||
$this->assertEquals($destination_row['action'], $this->destination->rollbackAction());
|
||||
$rollback_actions[$idx] = $this->destination->rollbackAction();
|
||||
}
|
||||
|
||||
$this->assertTranslations(1, 'en');
|
||||
$this->assertTranslations(2, 'fr', ['en']);
|
||||
$this->assertTranslations(3, 'en', ['fr']);
|
||||
$this->assertTranslations(4, 'fr');
|
||||
|
||||
// Rollback the rows.
|
||||
foreach ($destination_rows as $idx => $destination_row) {
|
||||
if ($rollback_actions[$idx] == MigrateIdMapInterface::ROLLBACK_DELETE) {
|
||||
$this->destination->rollback($destination_row);
|
||||
}
|
||||
}
|
||||
|
||||
// No change, update of existing translation.
|
||||
$this->assertTranslations(1, 'en');
|
||||
// Remove added translation.
|
||||
$this->assertTranslations(2, 'fr');
|
||||
// No change, update of existing translation.
|
||||
$this->assertTranslations(3, 'en', ['fr']);
|
||||
// No change, can't remove default translation.
|
||||
$this->assertTranslations(4, 'fr');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Kernel;
|
||||
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\migrate\MigrateExecutable;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
|
||||
/**
|
||||
* Tests migrating non-Drupal translated content.
|
||||
*
|
||||
* Ensure it's possible to migrate in translations, even if there's no nid or
|
||||
* tnid property on the source.
|
||||
*
|
||||
* @group migrate
|
||||
*/
|
||||
class MigrateExternalTranslatedTest extends MigrateTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @todo: Remove migrate_drupal when https://www.drupal.org/node/2560795 is
|
||||
* fixed.
|
||||
*/
|
||||
public static $modules = ['system', 'user', 'language', 'node', 'field', 'migrate_drupal', 'migrate_external_translated_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->installSchema('system', ['sequences']);
|
||||
$this->installSchema('node', array('node_access'));
|
||||
$this->installEntitySchema('user');
|
||||
$this->installEntitySchema('node');
|
||||
|
||||
// Create some languages.
|
||||
ConfigurableLanguage::createFromLangcode('en')->save();
|
||||
ConfigurableLanguage::createFromLangcode('fr')->save();
|
||||
ConfigurableLanguage::createFromLangcode('es')->save();
|
||||
|
||||
// Create a content type.
|
||||
NodeType::create([
|
||||
'type' => 'external_test',
|
||||
'name' => 'Test node type',
|
||||
])->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test importing and rolling back our data.
|
||||
*/
|
||||
public function testMigrations() {
|
||||
/** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */
|
||||
$storage = $this->container->get('entity.manager')->getStorage('node');
|
||||
$this->assertEquals(0, count($storage->loadMultiple()));
|
||||
|
||||
// Run the migrations.
|
||||
$migration_ids = ['external_translated_test_node', 'external_translated_test_node_translation'];
|
||||
$this->executeMigrations($migration_ids);
|
||||
$this->assertEquals(3, count($storage->loadMultiple()));
|
||||
|
||||
$node = $storage->load(1);
|
||||
$this->assertEquals('en', $node->language()->getId());
|
||||
$this->assertEquals('Cat', $node->title->value);
|
||||
$this->assertEquals('Chat', $node->getTranslation('fr')->title->value);
|
||||
$this->assertEquals('Gato', $node->getTranslation('es')->title->value);
|
||||
|
||||
$node = $storage->load(2);
|
||||
$this->assertEquals('en', $node->language()->getId());
|
||||
$this->assertEquals('Dog', $node->title->value);
|
||||
$this->assertEquals('Chien', $node->getTranslation('fr')->title->value);
|
||||
$this->assertFalse($node->hasTranslation('es'), "No spanish translation for node 2");
|
||||
|
||||
$node = $storage->load(3);
|
||||
$this->assertEquals('en', $node->language()->getId());
|
||||
$this->assertEquals('Monkey', $node->title->value);
|
||||
$this->assertFalse($node->hasTranslation('fr'), "No french translation for node 3");
|
||||
$this->assertFalse($node->hasTranslation('es'), "No spanish translation for node 3");
|
||||
|
||||
$this->assertNull($storage->load(4), "No node 4 migrated");
|
||||
|
||||
// Roll back the migrations.
|
||||
foreach ($migration_ids as $migration_id) {
|
||||
$migration = $this->getMigration($migration_id);
|
||||
$executable = new MigrateExecutable($migration, $this);
|
||||
$executable->rollback();
|
||||
}
|
||||
|
||||
$this->assertEquals(0, count($storage->loadMultiple()));
|
||||
}
|
||||
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\Tests\migrate\Unit\Plugin\migrate\destination;
|
||||
|
||||
use Drupal\Core\Entity\ContentEntityInterface;
|
||||
use Drupal\Core\Entity\ContentEntityType;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Field\FieldTypePluginManagerInterface;
|
||||
|
@ -97,6 +98,33 @@ class EntityContentBaseTest extends UnitTestCase {
|
|||
$destination->import(new Row([], []));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that translation destination fails for untranslatable entities.
|
||||
*
|
||||
* @expectedException \Drupal\migrate\MigrateException
|
||||
* @expectedExceptionMessage This entity type does not support translation
|
||||
*/
|
||||
public function testUntranslatable() {
|
||||
// An entity type without a language.
|
||||
$entity_type = $this->prophesize(ContentEntityType::class);
|
||||
$entity_type->getKey('langcode')->willReturn('');
|
||||
$entity_type->getKey('id')->willReturn('id');
|
||||
|
||||
$this->storage->getEntityType()->willReturn($entity_type->reveal());
|
||||
|
||||
$destination = new EntityTestDestination(
|
||||
[ 'translations' => TRUE ],
|
||||
'',
|
||||
[],
|
||||
$this->migration->reveal(),
|
||||
$this->storage->reveal(),
|
||||
[],
|
||||
$this->entityManager->reveal(),
|
||||
$this->prophesize(FieldTypePluginManagerInterface::class)->reveal()
|
||||
);
|
||||
$destination->getIds();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\Tests\migrate\Unit\process;
|
||||
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Plugin\migrate\process\Migration;
|
||||
use Drupal\migrate\Plugin\MigrateDestinationInterface;
|
||||
|
@ -86,4 +87,51 @@ class MigrationTest extends MigrateProcessTestCase {
|
|||
$this->assertEquals(2, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that processing is skipped when the input value is empty.
|
||||
*
|
||||
* @expectedException \Drupal\migrate\MigrateSkipProcessException
|
||||
*/
|
||||
public function testSkipOnEmpty() {
|
||||
$migration_plugin = $this->prophesize(MigrationInterface::class);
|
||||
$migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class);
|
||||
$process_plugin_manager = $this->prophesize(MigratePluginManager::class);
|
||||
|
||||
$configuration = [
|
||||
'migration' => 'foobaz',
|
||||
];
|
||||
$migration_plugin->id()->willReturn(uniqid());
|
||||
$migration = new Migration($configuration, 'migration', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal());
|
||||
$migration->transform(0, $this->migrateExecutable, $this->row, 'foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a successful lookup.
|
||||
*/
|
||||
public function testSuccessfulLookup() {
|
||||
$migration_plugin = $this->prophesize(MigrationInterface::class);
|
||||
$migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class);
|
||||
$process_plugin_manager = $this->prophesize(MigratePluginManager::class);
|
||||
|
||||
$configuration = [
|
||||
'migration' => 'foobaz',
|
||||
];
|
||||
$migration_plugin->id()->willReturn(uniqid());
|
||||
|
||||
$id_map = $this->prophesize(MigrateIdMapInterface::class);
|
||||
$id_map->lookupDestinationId([1])->willReturn([3]);
|
||||
$migration_plugin->getIdMap()->willReturn($id_map->reveal());
|
||||
|
||||
$migration_plugin_manager->createInstances(['foobaz'])
|
||||
->willReturn(['foobaz' => $migration_plugin->reveal()]);
|
||||
|
||||
$migrationStorage = $this->prophesize(EntityStorageInterface::class);
|
||||
$migrationStorage
|
||||
->loadMultiple(['foobaz'])
|
||||
->willReturn([$migration_plugin->reveal()]);
|
||||
|
||||
$migration = new Migration($configuration, 'migration', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal());
|
||||
$this->assertSame(3, $migration->transform(1, $this->migrateExecutable, $this->row, 'foo'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
92
core/modules/migrate/tests/src/Unit/process/SubstrTest.php
Normal file
92
core/modules/migrate/tests/src/Unit/process/SubstrTest.php
Normal file
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Unit\process;
|
||||
|
||||
use Drupal\migrate\Plugin\migrate\process\Substr;
|
||||
|
||||
/**
|
||||
* Tests the substr plugin.
|
||||
*
|
||||
* @coversDefaultClass \Drupal\migrate\Plugin\migrate\process\Substr
|
||||
*
|
||||
* @group migrate
|
||||
*/
|
||||
class SubstrTest extends MigrateProcessTestCase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Substr plugin based on providerTestSubstr() values.
|
||||
*
|
||||
* @dataProvider providerTestSubstr
|
||||
*/
|
||||
public function testSubstr($start = NULL, $length = NULL, $expected = NULL) {
|
||||
$configuration['start'] = $start;
|
||||
$configuration['length'] = $length;
|
||||
$this->plugin = new Substr($configuration, 'map', []);
|
||||
$value = $this->plugin->transform('Captain Janeway', $this->migrateExecutable, $this->row, 'destinationproperty');
|
||||
$this->assertSame($expected, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testSubstr().
|
||||
*/
|
||||
public function providerTestSubstr() {
|
||||
return [
|
||||
// Tests with valid start and length values.
|
||||
[0, 7, 'Captain'],
|
||||
// Tests with valid start > 0 and valid length.
|
||||
[6, 3, 'n J'],
|
||||
// Tests with valid start < 0 and valid length.
|
||||
[-7, 4, 'Jane'],
|
||||
// Tests without start value and valid length value.
|
||||
[NULL, 7, 'Captain'],
|
||||
// Tests with valid start value and no length value.
|
||||
[1, NULL, 'aptain Janeway'],
|
||||
// Tests without both start and length values.
|
||||
[NULL, NULL, 'Captain Janeway'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests invalid input type.
|
||||
*
|
||||
* @expectedException \Drupal\migrate\MigrateException
|
||||
* @expectedExceptionMessage The input value must be a string.
|
||||
*/
|
||||
public function testSubstrFail() {
|
||||
$configuration = [];
|
||||
$this->plugin = new Substr($configuration, 'map', []);
|
||||
$this->plugin->transform(['Captain Janeway'], $this->migrateExecutable, $this->row, 'destinationproperty');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the start parameter is an integer.
|
||||
*
|
||||
* @expectedException \Drupal\migrate\MigrateException
|
||||
* @expectedExceptionMessage The start position configuration value should be an integer. Omit this key to capture from the beginning of the string.
|
||||
*/
|
||||
public function testStartIsString() {
|
||||
$configuration['start'] = '2';
|
||||
$this->plugin = new Substr($configuration, 'map', []);
|
||||
$this->plugin->transform(['foo'], $this->migrateExecutable, $this->row, 'destinationproperty');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the length parameter is an integer.
|
||||
*
|
||||
* @expectedException \Drupal\migrate\MigrateException
|
||||
* @expectedExceptionMessage The character length configuration value should be an integer. Omit this key to capture from the start position to the end of the string.
|
||||
*/
|
||||
public function testLengthIsString() {
|
||||
$configuration['length'] = '1';
|
||||
$this->plugin = new Substr($configuration, 'map', []);
|
||||
$this->plugin->transform(['foo'], $this->migrateExecutable, $this->row, 'destinationproperty');
|
||||
}
|
||||
|
||||
}
|
Reference in a new issue