Skip to content
Snippets Groups Projects
Commit 2c2a7a88 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #2820490 by mpdonadio, heddn, Manuel Garcia, Jo Fitzgerald,...

Issue #2820490 by mpdonadio, heddn, Manuel Garcia, Jo Fitzgerald, shabana.navas, mikeryan, tstoeckler, quietone, Grayside, phenaproxima, damondt: FormatDate process plugin
parent a908c192
No related branches found
No related tags found
No related merge requests found
<?php
namespace Drupal\migrate\Plugin\migrate\process;
use Drupal\Component\Datetime\DateTimePlus;
use Drupal\migrate\MigrateException;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
/**
* Converts date/datetime from one format to another.
*
* Available configuration keys
* - from_format: The source format string as accepted by
* @link http://php.net/manual/datetime.createfromformat.php \DateTime::createFromFormat. @endlink
* - to_format: The destination format.
* - timezone: String identifying the required time zone, see
* DateTimePlus::__construct().
* - settings: keyed array of settings, see DateTimePlus::__construct().
*
* Examples:
*
* Example usage for date only fields (DATETIME_DATE_STORAGE_FORMAT):
* @code
* process:
* field_date:
* plugin: format_date
* from_format: 'm/d/Y'
* to_format: 'Y-m-d'
* source: event_date
* @endcode
*
* If the source value was '01/05/1955' the transformed value would be
* 1955-01-05.
*
* Example usage for datetime fields (DATETIME_DATETIME_STORAGE_FORMAT):
* @code
* process:
* field_time:
* plugin: format_date
* from_format: 'm/d/Y H:i:s'
* to_format: 'Y-m-d\TH:i:s'
* source: event_time
* @endcode
*
* If the source value was '01/05/1955 10:43:22' the transformed value would be
* 1955-01-05T10:43:22.
*
* Example usage for datetime fields with a timezone and settings:
* @code
* process:
* field_time:
* plugin: format_date
* from_format: 'Y-m-d\TH:i:sO'
* to_format: 'Y-m-d\TH:i:s'
* timezone: 'America/Managua'
* settings:
* validate_format: false
* source: event_time
* @endcode
*
* If the source value was '2004-12-19T10:19:42-0600' the transformed value
* would be 2004-12-19T10:19:42.
*
* @see \DateTime::createFromFormat()
* @see \Drupal\Component\Datetime\DateTimePlus::__construct()
* @see \Drupal\migrate\Plugin\MigrateProcessInterface
*
* @MigrateProcessPlugin(
* id = "format_date"
* )
*/
class FormatDate extends ProcessPluginBase {
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
if (empty($value)) {
return '';
}
// Validate the configuration.
if (empty($this->configuration['from_format'])) {
throw new MigrateException('Format date plugin is missing from_format configuration.');
}
if (empty($this->configuration['to_format'])) {
throw new MigrateException('Format date plugin is missing to_format configuration.');
}
$fromFormat = $this->configuration['from_format'];
$toFormat = $this->configuration['to_format'];
$timezone = isset($this->configuration['timezone']) ? $this->configuration['timezone'] : NULL;
$settings = isset($this->configuration['settings']) ? $this->configuration['settings'] : [];
// Attempts to transform the supplied date using the defined input format.
// DateTimePlus::createFromFormat can throw exceptions, so we need to
// explicitly check for problems.
try {
$transformed = DateTimePlus::createFromFormat($fromFormat, $value, $timezone, $settings)->format($toFormat);
}
catch (\InvalidArgumentException $e) {
throw new MigrateException(sprintf('Format date plugin could not transform "%s" using the format "%s". Error: %s', $value, $fromFormat, $e->getMessage()), $e->getCode(), $e);
}
catch (\UnexpectedValueException $e) {
throw new MigrateException(sprintf('Format date plugin could not transform "%s" using the format "%s". Error: %s', $value, $fromFormat, $e->getMessage()), $e->getCode(), $e);
}
return $transformed;
}
}
<?php
namespace Drupal\Tests\migrate\Unit\process;
use Drupal\migrate\MigrateException;
use Drupal\migrate\Plugin\migrate\process\FormatDate;
/**
* Tests the format date process plugin.
*
* @group migrate
*
* @coversDefaultClass Drupal\migrate\Plugin\migrate\process\FormatDate
*/
class FormatDateTest extends MigrateProcessTestCase {
/**
* Tests that missing configuration will throw an exception.
*/
public function testMigrateExceptionMissingFromFormat() {
$configuration = [
'from_format' => '',
'to_format' => 'Y-m-d',
];
$this->setExpectedException(MigrateException::class, 'Format date plugin is missing from_format configuration.');
$this->plugin = new FormatDate($configuration, 'test_format_date', []);
$this->plugin->transform('01/05/1955', $this->migrateExecutable, $this->row, 'field_date');
}
/**
* Tests that missing configuration will throw an exception.
*/
public function testMigrateExceptionMissingToFormat() {
$configuration = [
'from_format' => 'm/d/Y',
'to_format' => '',
];
$this->setExpectedException(MigrateException::class, 'Format date plugin is missing to_format configuration.');
$this->plugin = new FormatDate($configuration, 'test_format_date', []);
$this->plugin->transform('01/05/1955', $this->migrateExecutable, $this->row, 'field_date');
}
/**
* Tests that date format mismatches will throw an exception.
*/
public function testMigrateExceptionBadFormat() {
$configuration = [
'from_format' => 'm/d/Y',
'to_format' => 'Y-m-d',
];
$this->setExpectedException(MigrateException::class, 'Format date plugin could not transform "January 5, 1955" using the format "m/d/Y". Error: The date cannot be created from a format.');
$this->plugin = new FormatDate($configuration, 'test_format_date', []);
$this->plugin->transform('January 5, 1955', $this->migrateExecutable, $this->row, 'field_date');
}
/**
* Tests transformation.
*
* @covers ::transform
*
* @dataProvider datesDataProvider
*
* @param $configuration
* The configuration of the migration process plugin.
* @param $value
* The source value for the migration process plugin.
* @param $expected
* The expected value of the migration process plugin.
*/
public function testTransform($configuration, $value, $expected) {
$this->plugin = new FormatDate($configuration, 'test_format_date', []);
$actual = $this->plugin->transform($value, $this->migrateExecutable, $this->row, 'field_date');
$this->assertEquals($expected, $actual);
}
/**
* Data provider of test dates.
*
* @return array
* Array of date formats and actual/expected values.
*/
public function datesDataProvider() {
return [
'datetime_date' => [
'configuration' => [
'from_format' => 'm/d/Y',
'to_format' => 'Y-m-d',
],
'value' => '01/05/1955',
'expected' => '1955-01-05',
],
'datetime_datetime' => [
'configuration' => [
'from_format' => 'm/d/Y H:i:s',
'to_format' => 'Y-m-d\TH:i:s',
],
'value' => '01/05/1955 10:43:22',
'expected' => '1955-01-05T10:43:22',
],
'empty_values' => [
'configuration' => [
'from_format' => 'm/d/Y',
'to_format' => 'Y-m-d',
],
'value' => '',
'expected' => '',
],
'timezone' => [
'configuration' => [
'from_format' => 'Y-m-d\TH:i:sO',
'to_format' => 'Y-m-d\TH:i:s',
'timezone' => 'America/Managua',
],
'value' => '2004-12-19T10:19:42-0600',
'expected' => '2004-12-19T10:19:42',
],
];
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment