Update to drupal-org-drupal 8.0.0-rc2. For more information, see https://www.drupal.org/node/2598668
This commit is contained in:
parent
f32e58e4b1
commit
8e18df8c36
3062 changed files with 15044 additions and 172506 deletions
|
@ -10,6 +10,13 @@ migrate_plugin:
|
|||
migrate_destination:
|
||||
type: migrate_plugin
|
||||
label: 'Destination'
|
||||
mapping:
|
||||
overwrite_properties:
|
||||
type: sequence
|
||||
label: 'Properties to overwrite'
|
||||
sequence:
|
||||
type: string
|
||||
label: 'Property'
|
||||
|
||||
migrate_source:
|
||||
type: migrate_plugin
|
||||
|
|
|
@ -45,4 +45,30 @@ class MigrateSource extends Plugin {
|
|||
*/
|
||||
public $requirements_met = TRUE;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @see \Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase::checkRequirements
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $source_provider;
|
||||
|
||||
/**
|
||||
* Specifies the minimum version of the source provider.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $minimum_version;
|
||||
|
||||
}
|
||||
|
|
|
@ -585,8 +585,11 @@ class Migration extends ConfigEntityBase implements MigrationInterface, Requirem
|
|||
parent::calculateDependencies();
|
||||
$this->calculatePluginDependencies($this->getSourcePlugin());
|
||||
$this->calculatePluginDependencies($this->getDestinationPlugin());
|
||||
// Add dependencies on required migration dependencies.
|
||||
foreach ($this->getMigrationDependencies()['required'] as $dependency) {
|
||||
|
||||
// Add hard dependencies on required migrations.
|
||||
$dependencies = $this->getEntityManager()->getStorage($this->entityTypeId)
|
||||
->getVariantIds($this->getMigrationDependencies()['required']);
|
||||
foreach ($dependencies as $dependency) {
|
||||
$this->addDependency('config', $this->getEntityType()->getConfigPrefix() . '.' . $dependency);
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ class MigrationStorage extends ConfigEntityStorage implements MigrateBuildDepend
|
|||
* @return string[]
|
||||
* The expanded list of IDs.
|
||||
*/
|
||||
protected function getVariantIds(array $ids) {
|
||||
public function getVariantIds(array $ids) {
|
||||
// Re-index the array numerically, since we need to limit the loop by size.
|
||||
$ids = array_values($ids);
|
||||
|
||||
|
|
|
@ -109,6 +109,17 @@ class EntityContentBase extends Entity {
|
|||
* The row object to update from.
|
||||
*/
|
||||
protected function updateEntity(EntityInterface $entity, Row $row) {
|
||||
// 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.
|
||||
if (isset($this->configuration['overwrite_properties'])) {
|
||||
$clone = $row->cloneWithoutDestination();
|
||||
foreach ($this->configuration['overwrite_properties'] as $property) {
|
||||
$clone->setDestinationProperty($property, $row->getDestinationProperty($property));
|
||||
}
|
||||
$row = $clone;
|
||||
}
|
||||
|
||||
foreach ($row->getDestination() as $field_name => $values) {
|
||||
$field = $entity->$field_name;
|
||||
if ($field instanceof TypedDataInterface) {
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
|
||||
namespace Drupal\migrate\Plugin\migrate\destination;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* @MigrateDestination(
|
||||
* id = "entity:field_config"
|
||||
|
|
|
@ -32,18 +32,29 @@ class EntityRevision extends EntityContentBase {
|
|||
*
|
||||
* @param \Drupal\migrate\Row $row
|
||||
* The row object.
|
||||
* @param array $old_destination_id_values
|
||||
* The old destination ids.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityInterface|false
|
||||
* The entity or false if it can not be created.
|
||||
*/
|
||||
protected function getEntity(Row $row, array $old_destination_id_values) {
|
||||
$revision_id = $old_destination_id_values ? reset($old_destination_id_values) : $row->getDestinationProperty($this->getKey('revision'));
|
||||
$revision_id = $old_destination_id_values ?
|
||||
reset($old_destination_id_values) :
|
||||
$row->getDestinationProperty($this->getKey('revision'));
|
||||
if (!empty($revision_id) && ($entity = $this->storage->loadRevision($revision_id))) {
|
||||
$entity->setNewRevision(FALSE);
|
||||
}
|
||||
else {
|
||||
$entity_id = $row->getDestinationProperty($this->getKey('id'));
|
||||
$entity = $this->storage->load($entity_id);
|
||||
|
||||
// If we fail to load the original entity something is wrong and we need
|
||||
// to return immediately.
|
||||
if (!$entity) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$entity->enforceIsNew(FALSE);
|
||||
$entity->setNewRevision(TRUE);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ namespace Drupal\migrate\Plugin\migrate\source;
|
|||
use Drupal\Core\Plugin\PluginBase;
|
||||
use Drupal\migrate\Entity\MigrationInterface;
|
||||
use Drupal\migrate\MigrateException;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\MigrateSkipRowException;
|
||||
use Drupal\migrate\Plugin\MigrateIdMapInterface;
|
||||
use Drupal\migrate\Plugin\MigrateSourceInterface;
|
||||
|
|
|
@ -187,6 +187,15 @@ class Row {
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones the row with an empty set of destination values.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function cloneWithoutDestination() {
|
||||
return (new static($this->getSource(), $this->sourceIds, $this->isStub()))->freezeSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if destination property exists.
|
||||
*
|
||||
|
|
|
@ -9,9 +9,9 @@ namespace Drupal\migrate\Tests;
|
|||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\migrate\Entity\Migration;
|
||||
use Drupal\migrate\Entity\MigrationInterface;
|
||||
use Drupal\migrate\MigrateExecutable;
|
||||
use Drupal\migrate\MigrateMessageInterface;
|
||||
use Drupal\migrate\Plugin\MigrateIdMapInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\simpletest\KernelTestBase;
|
||||
|
||||
|
@ -199,4 +199,26 @@ abstract class MigrateTestBase extends KernelTestBase implements MigrateMessageI
|
|||
$this->collectMessages = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records a failure in the map table of a specific migration in order to
|
||||
* test scenarios which require a failed row.
|
||||
*
|
||||
* @param string|\Drupal\migrate\Entity\MigrationInterface $migration
|
||||
* The migration entity, or its ID.
|
||||
* @param array $row
|
||||
* The raw source row which "failed".
|
||||
* @param int $status
|
||||
* (optional) The failure status. Should be one of the
|
||||
* MigrateIdMapInterface::STATUS_* constants.
|
||||
*/
|
||||
protected function mockFailure($migration, array $row, $status = MigrateIdMapInterface::STATUS_FAILED) {
|
||||
if (is_string($migration)) {
|
||||
$migration = Migration::load($migration);
|
||||
}
|
||||
/** @var \Drupal\migrate\Entity\MigrationInterface $migration */
|
||||
$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,76 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\migrate\Kernel\Entity\MigrationTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\migrate\Kernel\Entity;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\migrate\Entity\Migration;
|
||||
|
||||
/**
|
||||
* Tests the Migration entity.
|
||||
*
|
||||
* @coversDefaultClass \Drupal\migrate\Entity\Migration
|
||||
* @group migrate
|
||||
*/
|
||||
class MigrationTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['migrate'];
|
||||
|
||||
/**
|
||||
* @covers ::calculateDependencies
|
||||
*/
|
||||
public function testCalculateDependencies() {
|
||||
$fixture_migrations = [
|
||||
'd6_node__article' => 'd6_node',
|
||||
'd6_node__page' => 'd6_node',
|
||||
'd6_variables' => 'd6_variables',
|
||||
];
|
||||
|
||||
foreach ($fixture_migrations as $id => $template) {
|
||||
$values = [
|
||||
'id' => $id,
|
||||
'template' => $template,
|
||||
'source' => [
|
||||
'plugin' => 'empty',
|
||||
],
|
||||
'destination' => [
|
||||
'plugin' => 'null',
|
||||
],
|
||||
'migration_tags' => []
|
||||
];
|
||||
Migration::create($values)->save();
|
||||
}
|
||||
|
||||
$values = [
|
||||
'migration_dependencies' => [
|
||||
'required' => [
|
||||
'd6_node:*',
|
||||
'd6_variables'
|
||||
]
|
||||
],
|
||||
'source' => [
|
||||
'plugin' => 'empty',
|
||||
],
|
||||
'destination' => [
|
||||
'plugin' => 'null',
|
||||
],
|
||||
];
|
||||
|
||||
$migration = new Migration($values, 'migration');
|
||||
$expected = [
|
||||
'migrate.migration.d6_node__article',
|
||||
'migrate.migration.d6_node__page',
|
||||
'migrate.migration.d6_variables'
|
||||
];
|
||||
$migration->calculateDependencies();
|
||||
$this->assertEquals($expected, $migration->getDependencies()['config']);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,219 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\migrate\Unit\destination\EntityRevisionTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\migrate\Unit\destination;
|
||||
|
||||
use Drupal\Core\Entity\ContentEntityInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\migrate\Plugin\migrate\destination\EntityRevision as RealEntityRevision;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* Tests entity revision destination.
|
||||
*
|
||||
* @group migrate
|
||||
* @coversDefaultClass \Drupal\migrate\Plugin\migrate\destination\EntityRevision
|
||||
*/
|
||||
class EntityRevisionTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @var \Drupal\migrate\Entity\MigrationInterface
|
||||
*/
|
||||
protected $migration;
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Entity\EntityStorageInterface
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Setup mocks to be used when creating a revision destination.
|
||||
$this->migration = $this->prophesize('\Drupal\migrate\Entity\MigrationInterface');
|
||||
$this->storage = $this->prophesize('\Drupal\Core\Entity\EntityStorageInterface');
|
||||
$this->entityManager = $this->prophesize('\Drupal\Core\Entity\EntityManagerInterface');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that passed old destination values are used by default.
|
||||
*
|
||||
* @covers ::getEntity
|
||||
*/
|
||||
public function testGetEntityDestinationValues() {
|
||||
$destination = $this->getEntityRevisionDestination([]);
|
||||
// Return a dummy because we don't care what gets called.
|
||||
$entity = $this->prophesize('\Drupal\Core\Entity\EntityInterface')
|
||||
->willImplement('\Drupal\Core\Entity\RevisionableInterface');
|
||||
// Assert that the first ID from the destination values is used to load the
|
||||
// entity.
|
||||
$this->storage->loadRevision(12)
|
||||
->shouldBeCalled()
|
||||
->willReturn($entity->reveal());
|
||||
$row = new Row([], []);
|
||||
$this->assertEquals($entity->reveal(), $destination->getEntity($row, [12, 13]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that revision updates update.
|
||||
*
|
||||
* @covers ::getEntity
|
||||
*/
|
||||
public function testGetEntityUpdateRevision() {
|
||||
$destination = $this->getEntityRevisionDestination([]);
|
||||
$entity = $this->prophesize('\Drupal\Core\Entity\EntityInterface')
|
||||
->willImplement('\Drupal\Core\Entity\RevisionableInterface');
|
||||
|
||||
$entity_type = $this->prophesize('\Drupal\Core\Entity\EntityTypeInterface');
|
||||
$entity_type->getKey('id')->willReturn('nid');
|
||||
$entity_type->getKey('revision')->willReturn('vid');
|
||||
$this->storage->getEntityType()->willReturn($entity_type->reveal());
|
||||
|
||||
// Assert we load the correct revision.
|
||||
$this->storage->loadRevision(2)
|
||||
->shouldBeCalled()
|
||||
->willReturn($entity->reveal());
|
||||
// Make sure its set as an update and not the default revision.
|
||||
$entity->setNewRevision(FALSE)->shouldBeCalled();
|
||||
$entity->isDefaultRevision(FALSE)->shouldBeCalled();
|
||||
|
||||
$row = new Row(['nid' => 1, 'vid' => 2], ['nid' => 1, 'vid' => 2]);
|
||||
$row->setDestinationProperty('vid', 2);
|
||||
$this->assertEquals($entity->reveal(), $destination->getEntity($row, []));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that new revisions are flagged to be written as new.
|
||||
*
|
||||
* @covers ::getEntity
|
||||
*/
|
||||
public function testGetEntityNewRevision() {
|
||||
$destination = $this->getEntityRevisionDestination([]);
|
||||
$entity = $this->prophesize('\Drupal\Core\Entity\EntityInterface')
|
||||
->willImplement('\Drupal\Core\Entity\RevisionableInterface');
|
||||
|
||||
$entity_type = $this->prophesize('\Drupal\Core\Entity\EntityTypeInterface');
|
||||
$entity_type->getKey('id')->willReturn('nid');
|
||||
$entity_type->getKey('revision')->willReturn('vid');
|
||||
$this->storage->getEntityType()->willReturn($entity_type->reveal());
|
||||
|
||||
// Enforce is new should be disabled.
|
||||
$entity->enforceIsNew(FALSE)->shouldBeCalled();
|
||||
// And toggle this as new revision but not the default revision.
|
||||
$entity->setNewRevision(TRUE)->shouldBeCalled();
|
||||
$entity->isDefaultRevision(FALSE)->shouldBeCalled();
|
||||
|
||||
// Assert we load the correct revision.
|
||||
$this->storage->load(1)
|
||||
->shouldBeCalled()
|
||||
->willReturn($entity->reveal());
|
||||
|
||||
$row = new Row(['nid' => 1, 'vid' => 2], ['nid' => 1, 'vid' => 2]);
|
||||
$row->setDestinationProperty('nid', 1);
|
||||
$this->assertEquals($entity->reveal(), $destination->getEntity($row, []));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test entity load failure.
|
||||
*
|
||||
* @covers ::getEntity
|
||||
*/
|
||||
public function testGetEntityLoadFailure() {
|
||||
$destination = $this->getEntityRevisionDestination([]);
|
||||
|
||||
$entity_type = $this->prophesize('\Drupal\Core\Entity\EntityTypeInterface');
|
||||
$entity_type->getKey('id')->willReturn('nid');
|
||||
$entity_type->getKey('revision')->willReturn('vid');
|
||||
$this->storage->getEntityType()->willReturn($entity_type->reveal());
|
||||
|
||||
// Return a failed load and make sure we don't fail and we return FALSE.
|
||||
$this->storage->load(1)
|
||||
->shouldBeCalled()
|
||||
->willReturn(FALSE);
|
||||
|
||||
$row = new Row(['nid' => 1, 'vid' => 2], ['nid' => 1, 'vid' => 2]);
|
||||
$row->setDestinationProperty('nid', 1);
|
||||
$this->assertFalse($destination->getEntity($row, []));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test entity revision save.
|
||||
*
|
||||
* @covers ::save
|
||||
*/
|
||||
public function testSave() {
|
||||
$entity = $this->prophesize('\Drupal\Core\Entity\ContentEntityInterface');
|
||||
$entity->save()
|
||||
->shouldBeCalled();
|
||||
$entity->getRevisionId()
|
||||
->shouldBeCalled()
|
||||
->willReturn(1234);
|
||||
$destination = $this->getEntityRevisionDestination();
|
||||
$this->assertEquals([1234], $destination->save($entity->reveal(), []));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to create an entity revision destination with mock services.
|
||||
*
|
||||
* @see \Drupal\Tests\migrate\Unit\Destination\EntityRevision
|
||||
*
|
||||
* @param $configuration
|
||||
* Configuration for the destination.
|
||||
* @param string $plugin_id
|
||||
* The plugin id.
|
||||
* @param array $plugin_definition
|
||||
* The plugin definition.
|
||||
*
|
||||
* @return \Drupal\Tests\migrate\Unit\destination\EntityRevision
|
||||
* Mocked destination.
|
||||
*/
|
||||
protected function getEntityRevisionDestination(array $configuration = [], $plugin_id = 'entity_revision', array $plugin_definition = []) {
|
||||
return new EntityRevision($configuration, $plugin_id, $plugin_definition,
|
||||
$this->migration->reveal(),
|
||||
$this->storage->reveal(),
|
||||
[],
|
||||
$this->entityManager->reveal());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock that exposes from internal methods for testing.
|
||||
*/
|
||||
class EntityRevision extends RealEntityRevision {
|
||||
|
||||
/**
|
||||
* Allow public access for testing.
|
||||
*/
|
||||
public function getEntity(Row $row, array $old_destination_id_values) {
|
||||
return parent::getEntity($row, $old_destination_id_values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow public access for testing.
|
||||
*/
|
||||
public function save(ContentEntityInterface $entity, array $old_destination_id_values = array()) {
|
||||
return parent::save($entity, $old_destination_id_values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't test method from base class.
|
||||
*
|
||||
* This method is from the parent and we aren't concerned with the inner
|
||||
* workings of its implementation which would trickle into mock assertions. An
|
||||
* empty implementation avoids this.
|
||||
*/
|
||||
protected function updateEntity(EntityInterface $entity, Row $row) {}
|
||||
|
||||
}
|
|
@ -7,7 +7,6 @@
|
|||
namespace Drupal\Tests\migrate\Unit\process;
|
||||
|
||||
use Drupal\migrate\Plugin\migrate\process\TestGet;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* Tests the get process plugin.
|
||||
|
|
|
@ -9,7 +9,6 @@ namespace Drupal\Tests\migrate\Unit\process;
|
|||
use Drupal\migrate\MigrateExecutable;
|
||||
use Drupal\migrate\Plugin\migrate\process\Get;
|
||||
use Drupal\migrate\Plugin\migrate\process\Iterator;
|
||||
use Drupal\migrate\Plugin\migrate\process\StaticMap;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\Tests\migrate\Unit\MigrateTestCase;
|
||||
|
||||
|
|
Reference in a new issue