summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Pott2017-04-03 13:36:59 (GMT)
committerAlex Pott2017-04-03 13:36:59 (GMT)
commit2c2a7a880c45791431e13060a0b65e49b3823599 (patch)
treefaa14b238d710952fa310ff23c70e24030486f87
parenta908c192db9b2aece9c4eccfd940269f332f438f (diff)
Issue #2820490 by mpdonadio, heddn, Manuel Garcia, Jo Fitzgerald, shabana.navas, mikeryan, tstoeckler, quietone, Grayside, phenaproxima, damondt: FormatDate process plugin
-rw-r--r--core/modules/migrate/src/Plugin/migrate/process/FormatDate.php113
-rw-r--r--core/modules/migrate/tests/src/Unit/process/FormatDateTest.php124
2 files changed, 237 insertions, 0 deletions
diff --git a/core/modules/migrate/src/Plugin/migrate/process/FormatDate.php b/core/modules/migrate/src/Plugin/migrate/process/FormatDate.php
new file mode 100644
index 0000000..b197f17
--- /dev/null
+++ b/core/modules/migrate/src/Plugin/migrate/process/FormatDate.php
@@ -0,0 +1,113 @@
+<?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;
+ }
+
+}
diff --git a/core/modules/migrate/tests/src/Unit/process/FormatDateTest.php b/core/modules/migrate/tests/src/Unit/process/FormatDateTest.php
new file mode 100644
index 0000000..c1e0c63
--- /dev/null
+++ b/core/modules/migrate/tests/src/Unit/process/FormatDateTest.php
@@ -0,0 +1,124 @@
+<?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',
+ ],
+ ];
+ }
+
+}