Issue #3007102 by mikelutz, juampynr, DamienMcKenna, vpa24: Migrating to Date-only field does not drop time value

merge-requests/55/head
Lee Rowlands 2019-08-21 18:42:29 +10:00
parent 52a07405f9
commit 626a6aa3e1
No known key found for this signature in database
GPG Key ID: 2B829A3DF9204DC4
4 changed files with 110 additions and 10 deletions

View File

@ -2,11 +2,14 @@
namespace Drupal\datetime\Plugin\migrate\field;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\MigrateException;
use Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase;
/**
* Provides a field plugin for date and time fields.
*
* @MigrateField(
* id = "datetime",
* type_map = {
@ -45,19 +48,35 @@ class DateField extends FieldPluginBase {
* {@inheritdoc}
*/
public function defineValueProcessPipeline(MigrationInterface $migration, $field_name, $data) {
$to_format = DateTimeItemInterface::DATETIME_STORAGE_FORMAT;
if (isset($data['field_definition']['data'])) {
$field_data = unserialize($data['field_definition']['data']);
if (isset($field_data['settings']['granularity'])) {
$granularity = $field_data['settings']['granularity'];
if ($granularity = $field_data['settings']['granularity'] &&
$granularity['hour'] === 0 &&
$granularity['minute'] === 0 &&
$granularity['second'] === 0) {
$to_format = DateTimeItemInterface::DATE_STORAGE_FORMAT;
}
}
}
switch ($data['type']) {
case 'date':
$from_format = 'Y-m-d\TH:i:s';
$to_format = 'Y-m-d\TH:i:s';
break;
case 'datestamp':
$from_format = 'U';
$to_format = 'U';
break;
case 'datetime':
$from_format = 'Y-m-d H:i:s';
$to_format = 'Y-m-d\TH:i:s';
break;
default:
throw new MigrateException(sprintf('Field %s of type %s is an unknown date field type.', $field_name, var_export($data['type'], TRUE)));
}

View File

@ -2,17 +2,30 @@
namespace Drupal\Tests\datetime\Unit\Plugin\migrate\field;
use Drupal\datetime\Plugin\migrate\field\DateField;
use Drupal\migrate\MigrateException;
use Drupal\Tests\UnitTestCase;
/**
* Tests legacy methods on the date_field plugin.
*
* @group migrate
* @group legacy
*/
class DateFieldLegacyTest extends DateFieldTest {
class DateFieldLegacyTest extends UnitTestCase {
/**
* Tests deprecation on calling processFieldValues().
*
* @expectedDeprecation Deprecated in Drupal 8.6.0, to be removed before Drupal 9.0.0. Use defineValueProcessPipeline() instead. See https://www.drupal.org/node/2944598.
*/
public function testUnknownDateType($method = 'processFieldValues') {
parent::testUnknownDateType($method);
public function testUnknownDateType() {
$migration = $this->prophesize('Drupal\migrate\Plugin\MigrationInterface')->reveal();
$plugin = new DateField([], '', []);
$this->expectException(MigrateException::class);
$this->expectExceptionMessage("Field field_date of type 'timestamp' is an unknown date field type.");
$plugin->processFieldValues($migration, 'field_date', ['type' => 'timestamp']);
}
}

View File

@ -7,20 +7,85 @@ use Drupal\migrate\MigrateException;
use Drupal\Tests\UnitTestCase;
/**
* Provides unit tests for the DateField Plugin.
*
* @coversDefaultClass \Drupal\datetime\Plugin\migrate\field\DateField
*
* @group migrate
*/
class DateFieldTest extends UnitTestCase {
/**
* Tests an Exception is thrown when the field type is not a known date type.
* Tests defineValueProcessPipeline.
*
* @covers ::defineValueProcessPipeline
*
* @dataProvider providerTestDefineValueProcessPipeline
*/
public function testUnknownDateType($method = 'defineValueProcessPipeline') {
$migration = $this->prophesize('Drupal\migrate\Plugin\MigrationInterface')->reveal();
public function testDefineValueProcessPipeline($data, $from_format, $to_format) {
$migration = $this->createMock('Drupal\migrate\Plugin\MigrationInterface');
$migration->expects($this->once())
->method('mergeProcessOfProperty')
->with('field_date', [
'plugin' => 'sub_process',
'source' => 'field_date',
'process' => [
'value' => [
'plugin' => 'format_date',
'from_format' => $from_format,
'to_format' => $to_format,
'source' => 'value',
],
],
])
->will($this->returnValue($migration));
$plugin = new DateField([], '', []);
$plugin->defineValueProcessPipeline($migration, 'field_date', $data);
}
/**
* Provides data for testDefineValueProcessPipeline().
*/
public function providerTestDefineValueProcessPipeline() {
return [
[['type' => 'date'], 'Y-m-d\TH:i:s', 'Y-m-d\TH:i:s'],
[['type' => 'datestamp'], 'U', 'U'],
[['type' => 'datetime'], 'Y-m-d H:i:s', 'Y-m-d\TH:i:s'],
[
[
'type' => 'datetime',
'field_definition' => [
'data' => serialize([
'settings' => [
'granularity' => [
'hour' => 0,
'minute' => 0,
'second' => 0,
],
],
]),
],
],
'Y-m-d H:i:s',
'Y-m-d',
],
];
}
/**
* Tests invalid date types throw an exception.
*
* @covers ::defineValueProcessPipeline
*/
public function testDefineValueProcessPipelineException() {
$migration = $this->createMock('Drupal\migrate\Plugin\MigrationInterface');
$plugin = new DateField([], '', []);
$this->expectException(MigrateException::class);
$this->expectExceptionMessage("Field field_date of type 'timestamp' is an unknown date field type.");
$plugin->$method($migration, 'field_date', ['type' => 'timestamp']);
$plugin->defineValueProcessPipeline($migration, 'field_date', ['type' => 'totoro']);
}
}

View File

@ -149,6 +149,9 @@ class MigrateNodeTest extends MigrateDrupal7TestBase {
$node = Node::load(1);
$this->assertTrue($node->field_boolean->value);
$this->assertEquals('99-99-99-99', $node->field_phone->value);
$this->assertSame('2015-01-20T04:15:00', $node->field_date->value);
$this->assertSame('2015-01-20', $node->field_date_without_time->value);
$this->assertSame('2015-01-20', $node->field_datetime_without_time->value);
$this->assertEquals('1', $node->field_float->value);
$this->assertEquals('5', $node->field_integer->value);
$this->assertEquals('Some more text', $node->field_text_list[0]->value);