Commit d0ef1908 authored by webchick's avatar webchick

Issue #2147815 by chx: Migrate: add an entity deduplication process plugin.

parent e447e4c3
<?php
/**
* @file
* Contains \Drupal\migrate\Plugin\migrate\process\DedupeBase.
*/
namespace Drupal\migrate\Plugin\migrate\process;
use Drupal\Core\Plugin\PluginBase;
use Drupal\migrate\MigrateExecutable;
use Drupal\migrate\Plugin\MigrateProcessInterface;
use Drupal\migrate\Row;
/**
* This abstract base contains the dedupe logic.
*
* These plugins avoid duplication at the destination. For example, when
* creating filter format names, the current value is checked against the
* existing filter format names and if it exists, a numeric postfix is added
* and incremented until a unique value is created.
*/
abstract class DedupeBase extends PluginBase implements MigrateProcessInterface {
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutable $migrate_executable, Row $row, $destination_property) {
$i = 1;
$postfix = isset($this->configuration['postfix']) ? $this->configuration['postfix'] : '';
$new_value = $value;
while ($this->exists($new_value)) {
$new_value = $value . $postfix . $i++;
}
return $new_value;
}
/**
* This is a query checking the existence of some value.
*
* @return bool
*/
abstract protected function exists($value);
}
<?php
/**
* @file
* Contains \Drupal\migrate\Plugin\migrate\process\DedupeEntity.
*/
namespace Drupal\migrate\Plugin\migrate\process;
/**
* Ensures value is not duplicated against an entity field.
*
* @PluginId("dedupe_entity")
*/
class DedupeEntity extends DedupeBase {
/**
* @var \Drupal\Core\Entity\Query\QueryInterface
*/
protected $entityQuery;
/**
* {@inheritdoc}
*/
protected function exists($value) {
return $this->getEntityQuery()->condition($this->configuration['field'], $value)->count()->execute();
}
/**
* Returns an entity query object.
*
* @return \Drupal\Core\Entity\Query\QueryInterface
* The entity query object for the configured entity type.
*/
protected function getEntityQuery() {
if (!isset($this->entityQuery)) {
$this->entityQuery = \Drupal::entityQuery($this->configuration['entity_type']);
}
return $this->entityQuery;
}
}
<?php
/**
* @file
* Contains \Drupal\migrate\Tests\process\DedupeEntityTest.
*/
namespace Drupal\migrate\Tests\process;
use Drupal\Core\Entity\Query\QueryInterface;
use Drupal\migrate\Plugin\migrate\process\DedupeEntity;
/**
* @group migrate
* @group Drupal
*/
class DedupeEntityTest extends MigrateProcessTestCase {
/**
* The mock entity query.
*
* @var \Drupal\Core\Entity\Query\QueryInterface
*/
protected $entityQuery;
/**
* {@inheritdoc}
*/
public static function getInfo() {
return array(
'name' => 'Dedupe entity process plugin',
'description' => 'Tests the entity deduplication process plugin.',
'group' => 'Migrate',
);
}
/**
* {@inheritdoc}
*/
public function setUp() {
$this->entityQuery = $this->getMockBuilder('Drupal\Core\Entity\Query\QueryInterface')
->disableOriginalConstructor()
->getMock();
parent::setUp();
}
/**
* Tests the entity deduplication plugin when there is no duplication.
*/
public function testDedupeEntityNoDuplication() {
$configuration = array(
'entity_type' => 'test_entity_type',
'field' => 'test_field',
);
$plugin = new TestDedupeEntity($configuration, 'dedupe_entity', array());
$this->entityQueryExpects(0);
$plugin->setEntityQuery($this->entityQuery);
$return = $plugin->transform('test', $this->migrateExecutable, $this->row, 'testpropertty');
$this->assertSame($return, 'test');
}
/**
* Tests the entity deduplication plugin when there is duplication.
*/
public function testDedupeEntityDuplication() {
$configuration = array(
'entity_type' => 'test_entity_type',
'field' => 'test_field',
);
$plugin = new TestDedupeEntity($configuration, 'dedupe_entity', array());
$this->entityQueryExpects(3);
$plugin->setEntityQuery($this->entityQuery);
$return = $plugin->transform('test', $this->migrateExecutable, $this->row, 'testpropertty');
$this->assertSame($return, 'test3');
}
/**
* Tests the entity deduplication plugin when there is no duplication.
*/
public function testDedupeEntityNoDuplicationWithPostfix() {
$configuration = array(
'entity_type' => 'test_entity_type',
'field' => 'test_field',
'postfix' => '_',
);
$plugin = new TestDedupeEntity($configuration, 'dedupe_entity', array());
$this->entityQueryExpects(0);
$plugin->setEntityQuery($this->entityQuery);
$return = $plugin->transform('test', $this->migrateExecutable, $this->row, 'testpropertty');
$this->assertSame($return, 'test');
}
/**
* Tests the entity deduplication plugin when there is duplication.
*/
public function testDedupeEntityDuplicationWithPostfix() {
$configuration = array(
'entity_type' => 'test_entity_type',
'field' => 'test_field',
'postfix' => '_',
);
$plugin = new TestDedupeEntity($configuration, 'dedupe_entity', array());
$this->entityQueryExpects(2);
$plugin->setEntityQuery($this->entityQuery);
$return = $plugin->transform('test', $this->migrateExecutable, $this->row, 'testpropertty');
$this->assertSame($return, 'test_2');
}
/**
* Helper function to add expectations to the mock entity query object.
*
* @param int $count
* The number of deduplications to be set up.
*/
protected function entityQueryExpects($count) {
$this->entityQuery->expects($this->exactly($count + 1))
->method('condition')
->will($this->returnValue($this->entityQuery));
$this->entityQuery->expects($this->exactly($count + 1))
->method('count')
->will($this->returnValue($this->entityQuery));
$this->entityQuery->expects($this->exactly($count + 1))
->method('execute')
->will($this->returnCallback(function () use (&$count) { return $count--;}));
}
}
class TestDedupeEntity extends DedupeEntity {
function setEntityQuery(QueryInterface $entity_query) {
$this->entityQuery = $entity_query;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment