migmag-1.0.x-dev/migmag_process/src/Plugin/migrate/process/MigMagTry.php
migmag_process/src/Plugin/migrate/process/MigMagTry.php
<?php
namespace Drupal\migmag_process\Plugin\migrate\process;
use Drupal\migmag\Utility\MigMagMigrationUtility;
use Drupal\migrate\MigrateException;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\MigrateSkipRowException;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
/**
* Wraps the specified process pipeline into a try catch clause.
*
* Configuration options:
* - process: the process pipeline to process.
* - multiple: whether the plugin should handle multiple values or not.
* Optional, defaults to FALSE.
* - catch: an array of the values to return if a specific exception is thrown.
* Return values must be keyed by the exception FQCN. Optional, defaults to
* ['Exception' => NULL].
* - saveMessage: The plugin can be configured to catch MigrateException or
* MigrateSkipRowException. When these are caught, MigrateExecutable won't
* know about them, so it won't save anything into the corresponding migration
* message table. If saveMessage isn't set to FALSE, this plugin will save the
* messages the same way how MigrateExecutable would do. Defaults to TRUE.
*
* Example:
* @code
* process:
* link/uri:
* plugin: migmag_try
* catch:
* Exception: 'route:<current>'
* process:
* plugin: link_uri
* source: link_path
* saveMessage: false
* @endcode
*
* @see https://drupal.org/node/3253230
* @see \Drupal\Tests\migmag_process\Kernel\Plugin\MigMagTryTest
*
* @MigrateProcessPlugin(
* id = "migmag_try"
* )
*/
class MigMagTry extends ProcessPluginBase {
/**
* The migration being processed.
*
* @var \Drupal\migrate\Plugin\MigrationInterface
*/
protected $migration;
/**
* Constructs a new MigMagTry instance.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
* The actually processed migration.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration) {
$configuration += ['catch' => ['Exception' => NULL], 'saveMessage' => TRUE];
$configuration['process'] = MigMagMigrationUtility::getAssociativeMigrationProcess($configuration['process']);
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->migration = $migration;
}
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
try {
$row_clone = clone $row;
$migrate_executable->processRow(
$row_clone,
[$destination_property => $this->configuration['process']]
);
return $row_clone->getDestinationProperty($destination_property);
}
catch (\Exception | \Throwable $e_or_t) {
}
$return_value = NULL;
$return_value_set = FALSE;
$e_or_t_class_and_parents = array_merge(
[get_class($e_or_t)],
array_values(
class_parents($e_or_t, FALSE)
)
);
foreach ($e_or_t_class_and_parents as $e_or_t_class) {
if (array_key_exists($e_or_t_class, $this->configuration['catch'])) {
$return_value = $this->configuration['catch'][$e_or_t_class];
$return_value_set = TRUE;
break;
}
if (array_key_exists('\\' . $e_or_t_class, $this->configuration['catch'])) {
$return_value = $this->configuration['catch']['\\' . $e_or_t_class];
$return_value_set = TRUE;
break;
}
}
if (!$return_value_set) {
throw $e_or_t;
}
// Save the corresponding migration message.
// @see MigrateExecutableInterface::import().
if (
$this->configuration['saveMessage'] &&
(
$e_or_t instanceof MigrateException ||
$e_or_t instanceof MigrateSkipRowException
)
) {
$level = $e_or_t instanceof MigrateException
? $e_or_t->getLevel()
: MigrationInterface::MESSAGE_INFORMATIONAL;
if (
($message = trim($e_or_t->getMessage())) ||
$e_or_t instanceof MigrateException
) {
$migrate_executable->saveMessage(
sprintf(
"%s:%s: %s",
$this->migration->getPluginId(),
$destination_property,
$message
),
$level
);
}
}
return $return_value;
}
/**
* {@inheritdoc}
*/
public function multiple() {
return $this->configuration['multiple'] ?? FALSE;
}
}
