diff --git a/core/modules/migrate/src/Plugin/migrate/process/Log.php b/core/modules/migrate/src/Plugin/migrate/process/Log.php index 62088f607e8899a92b2877889b481ac602f6416c..8807d51c1c770ea66e016479b97677e90c1020c0 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/Log.php +++ b/core/modules/migrate/src/Plugin/migrate/process/Log.php @@ -31,9 +31,38 @@ class Log extends ProcessPluginBase { * {@inheritdoc} */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { - // Log the value. - $migrate_executable->saveMessage($value); + if (is_null($value) || is_bool($value)) { + $export = var_export($value, TRUE); + } + elseif (is_float($value)) { + $export = sprintf('%f', $value); + } + elseif (method_exists($value, 'toString')) { + $export = print_r($value->toString(), TRUE); + } + elseif (method_exists($value, 'toArray')) { + $export = print_r($value->toArray(), TRUE); + } + elseif (is_string($value) || is_numeric($value) || is_array($value)) { + $export = print_r($value, TRUE); + } + elseif (method_exists($value, '__toString')) { + $export = print_r((string) $value, TRUE); + } + else { + $export = NULL; + } + + $class_name = $export !== NULL && is_object($value) + ? $class_name = get_class($value) . ":\n" + : ''; + $message = $export === NULL + ? "Unable to log the value for '$destination_property'" + : "'$destination_property' value is $class_name'$export'"; + + // Log the value. + $migrate_executable->saveMessage($message); // Pass through the same value we received. return $value; } diff --git a/core/modules/migrate/tests/src/Kernel/Plugin/LogTest.php b/core/modules/migrate/tests/src/Kernel/Plugin/LogTest.php index 85b125604ca09076e11a7114c5461c522347a7ce..707144c668b1c4eae0ff5fee8ba965a1c1aec08d 100644 --- a/core/modules/migrate/tests/src/Kernel/Plugin/LogTest.php +++ b/core/modules/migrate/tests/src/Kernel/Plugin/LogTest.php @@ -2,9 +2,11 @@ namespace Drupal\Tests\migrate\Kernel\Plugin; +use Drupal\Core\Url; use Drupal\KernelTests\KernelTestBase; -use Drupal\migrate\MigrateExecutableInterface; +use Drupal\migrate\MigrateExecutable; use Drupal\migrate\Row; +use Drupal\node\Entity\Node; /** * Tests the Log process plugin. @@ -16,21 +18,192 @@ class LogTest extends KernelTestBase { /** * {@inheritdoc} */ - protected static $modules = ['migrate']; + protected static $modules = ['node', 'migrate']; + + /** + * The Log process plugin. + * + * @var \Drupal\migrate\Plugin\migrate\process\Log + */ + protected $logPlugin; + + /** + * Migrate executable. + * + * @var \Drupal\Tests\migrate\Kernel\Plugin\TestMigrateExecutable + */ + protected $executable; + + /** + * {@inheritdoc} + */ + public function setUp(): void { + parent::setUp(); + $definition = [ + 'source' => [ + 'plugin' => 'embedded_data', + 'data_rows' => [ + ['id' => '1'], + ], + 'ids' => [ + 'id' => ['type' => 'integer'], + ], + ], + 'destination' => [ + 'plugin' => 'null', + ], + ]; + + /** @var \Drupal\migrate\Plugin\migration $migration */ + $migration = \Drupal::service('plugin.manager.migration') + ->createStubMigration($definition); + $this->executable = new TestMigrateExecutable($migration); + + // Plugin being tested. + $this->logPlugin = \Drupal::service('plugin.manager.migrate.process') + ->createInstance('log'); + } /** * Test the Log plugin. */ public function testLog() { - $plugin = \Drupal::service('plugin.manager.migrate.process') - ->createInstance('log'); - $executable = $this->prophesize(MigrateExecutableInterface::class)->reveal(); - $row = new Row(); - $log_message = "Testing the log message"; + $values = [ + 'nid' => 2, + 'type' => 'page', + 'title' => 'page', + ]; + + $node = new Node($values, 'node', 'test'); + $node_array = <<< NODE +Array +( + [nid] => Array + ( + ) + + [uuid] => Array + ( + ) + + [vid] => Array + ( + ) + + [langcode] => Array + ( + ) + + [type] => Array + ( + ) + + [revision_timestamp] => Array + ( + ) + + [revision_uid] => Array + ( + ) + + [revision_log] => Array + ( + ) + + [status] => Array + ( + ) + + [uid] => Array + ( + ) - // Ensure the log is getting saved. - $saved_message = $plugin->transform($log_message, $executable, $row, 'buffalo'); - $this->assertSame($log_message, $saved_message); + [title] => Array + ( + ) + + [created] => Array + ( + ) + + [changed] => Array + ( + ) + + [promote] => Array + ( + ) + + [sticky] => Array + ( + ) + + [default_langcode] => Array + ( + ) + + [revision_default] => Array + ( + ) + + [revision_translation_affected] => Array + ( + ) + +) + +NODE; + + $data = [ + 'node' => [ + 'value' => $node, + 'expected_message' => "'foo' value is Drupal\\node\Entity\Node:\n'$node_array'", + ], + 'url' => [ + 'value' => Url::fromUri('https://en.wikipedia.org/wiki/Drupal#Community'), + 'expected_message' => "'foo' value is Drupal\Core\Url:\n'https://en.wikipedia.org/wiki/Drupal#Community'", + ], + ]; + + $i = 1; + foreach ($data as $datum) { + $this->executable->sourceIdValues = ['id' => $i++]; + + // Test the input value is not altered. + $new_value = $this->logPlugin->transform($datum['value'], $this->executable, new Row(), 'foo'); + $this->assertSame($datum['value'], $new_value); + + // Test the stored message. + $message = $this->executable->getIdMap() + ->getMessages($this->executable->sourceIdValues) + ->fetchAllAssoc('message'); + $actual_message = key($message); + $this->assertSame($datum['expected_message'], $actual_message); + } + } + +} + +/** + * MigrateExecutable test class. + */ +class TestMigrateExecutable extends MigrateExecutable { + + /** + * The configuration values of the source. + * + * @var array + */ + public $sourceIdValues; + + /** + * Get the ID map from the current migration. + * + * @return \Drupal\migrate\Plugin\MigrateIdMapInterface + * The ID map. + */ + public function getIdMap() { + return parent::getIdMap(); } } diff --git a/core/modules/migrate/tests/src/Unit/process/LogTest.php b/core/modules/migrate/tests/src/Unit/process/LogTest.php new file mode 100644 index 0000000000000000000000000000000000000000..56c6817d524fddeeb3f34c606bbbc5e616d9c28d --- /dev/null +++ b/core/modules/migrate/tests/src/Unit/process/LogTest.php @@ -0,0 +1,111 @@ +<?php + +namespace Drupal\Tests\migrate\Unit\process; + +use Drupal\migrate\Plugin\migrate\process\Log; +use Drupal\migrate\Row; + +/** + * Tests the Log process plugin. + * + * @group migrate + */ +class LogTest extends MigrateProcessTestCase { + + /** + * Tests the Log plugin. + * + * @dataProvider providerTestLog() + */ + public function testLog($value, $expected_message) { + // Test the expected log message. + $this->migrateExecutable->expects($this->once()) + ->method('saveMessage') + ->with($expected_message); + $plugin = new Log([], 'log', []); + + // Test the input value is not altered. + $new_value = $plugin->transform($value, $this->migrateExecutable, new Row(), 'foo'); + $this->assertSame($value, $new_value); + } + + /** + * Provides data for testLog. + * + * @return \string[][] + * An array of test data arrays. + */ + public function providerTestLog() { + $object = (object) [ + 'a' => 'test', + 'b' => 'test2', + 'c' => 'test3', + ]; + $xml_str = <<<XML +<?xml version='1.0'?> +<mathematician> + <name>Ada Lovelace</name> +</mathematician> +XML; + return [ + 'int zero' => [ + 'value' => 0, + 'expected_message' => "'foo' value is '0'", + ], + 'string empty' => [ + 'value' => '', + 'expected_message' => "'foo' value is ''", + ], + 'string' => [ + 'value' => 'Testing the log message', + 'expected_message' => "'foo' value is 'Testing the log message'", + ], + 'array' => [ + 'value' => ['key' => 'value'], + 'expected_message' => "'foo' value is 'Array\n(\n [key] => value\n)\n'", + ], + 'float' => [ + 'value' => 1.123, + 'expected_message' => "'foo' value is '1.123000'", + ], + 'NULL' => [ + 'value' => NULL, + 'expected_message' => "'foo' value is 'NULL'", + ], + 'boolean' => [ + 'value' => TRUE, + 'expected_message' => "'foo' value is 'true'", + ], + 'object_with_to_String' => [ + 'value' => new ObjWithString(), + 'expected_message' => "'foo' value is Drupal\Tests\migrate\Unit\process\ObjWithString:\n'a test string'", + ], + 'object_no_to_string' => [ + 'value' => $object, + 'expected_message' => "Unable to log the value for 'foo'", + ], + 'simple_xml' => [ + 'value' => new \SimpleXMLElement($xml_str), + 'expected_message' => "'foo' value is SimpleXMLElement:\n'\n \n'", + ], + ]; + } + +} + +/** + * Test class with a __toString() method. + */ +class ObjWithString { + + /** + * Returns a string. + * + * @return string + * A string. + */ + public function __toString() { + return 'a test string'; + } + +}