clean install

This commit is contained in:
2024-12-10 15:08:16 +01:00
commit e14eb2d8fd
31193 changed files with 3555714 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
<?php
declare(strict_types = 1);
namespace Drupal\migrate_tools\Form;
use Drupal\Core\Form\FormStateInterface;
/**
* Class MigrationAddForm.
*
* Provides the add form for our migration entity.
*
* @package Drupal\migrate_tools\Form
*
* @ingroup migrate_tools
*/
class MigrationAddForm extends MigrationFormBase {
/**
* Returns the actions provided by this form.
*
* For our add form, we only need to change the text of the submit button.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* An associative array containing the current state of the form.
*
* @return array
* An array of supported actions for the current entity form.
*/
protected function actions(array $form, FormStateInterface $form_state): array {
$actions = parent::actions($form, $form_state);
unset($actions['submit']);
return $actions;
}
}

View File

@@ -0,0 +1,74 @@
<?php
declare(strict_types = 1);
namespace Drupal\migrate_tools\Form;
use Drupal\Core\Entity\EntityConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
/**
* Provides the delete form for our Migration entity.
*
* @package Drupal\migrate_tools\Form
*
* @ingroup migrate_tools
*/
class MigrationDeleteForm extends EntityConfirmFormBase {
/**
* Gathers a confirmation question.
*
* @return string
* Translated string.
*/
public function getQuestion(): TranslatableMarkup {
return $this->t('Are you sure you want to delete migration %label?', [
'%label' => $this->entity->label(),
]);
}
/**
* Gather the confirmation text.
*
* @return string
* Translated string.
*/
public function getConfirmText(): TranslatableMarkup {
return $this->t('Delete Migration');
}
/**
* Gets the cancel URL.
*
* @return \Drupal\Core\Url
* The URL to go to if the user cancels the deletion.
*/
public function getCancelUrl(): Url {
return new Url('entity.migration_group.list');
}
/**
* The submit handler for the confirm form.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* An associative array containing the current state of the form.
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
// Delete the entity.
$this->entity->delete();
// Set a message that the entity was deleted.
$this->messenger()->addStatus($this->t('Migration %label was deleted.', [
'%label' => $this->entity->label(),
]));
// Redirect the user to the list controller when complete.
$form_state->setRedirectUrl($this->getCancelUrl());
}
}

View File

@@ -0,0 +1,52 @@
<?php
declare(strict_types = 1);
namespace Drupal\migrate_tools\Form;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
/**
* Provides the edit form for our Migration entity.
*
* @package Drupal\migrate_tools\Form
*
* @ingroup migrate_tools
*/
class MigrationEditForm extends MigrationFormBase {
/**
* Returns the actions provided by this form.
*
* For the edit form, we only need to change the text of the submit button.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* An associative array containing the current state of the form.
*
* @return array
* An array of supported actions for the current entity form.
*/
public function actions(array $form, FormStateInterface $form_state): array {
$actions = parent::actions($form, $form_state);
$actions['submit']['#value'] = $this->t('Update Migration');
return $actions;
}
/**
* Add group route parameter.
*
* @param \Drupal\Core\Url $url
* The URL associated with an operation.
* @param string $migration_group
* The migration's parent group.
*/
protected function addGroupParameter(Url $url, string $migration_group): void {
$route_parameters = $url->getRouteParameters() + ['migration_group' => $migration_group];
$url->setRouteParameters($route_parameters);
}
}

View File

@@ -0,0 +1,265 @@
<?php
declare(strict_types = 1);
namespace Drupal\migrate_tools\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\migrate\MigrateMessage;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
use Drupal\migrate_tools\MigrateBatchExecutable;
use Drupal\migrate_tools\MigrateTools;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* This form is specifically for configuring process pipelines.
*/
class MigrationExecuteForm extends FormBase {
/**
* Plugin manager for migration plugins.
*/
protected MigrationPluginManagerInterface $migrationPluginManager;
/**
* Constructs a new MigrationExecuteForm object.
*
* @param \Drupal\migrate\Plugin\MigrationPluginManagerInterface $migration_plugin_manager
* The plugin manager for config entity-based migrations.
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The current route match.
*/
public function __construct(MigrationPluginManagerInterface $migration_plugin_manager, RouteMatchInterface $route_match) {
$this->migrationPluginManager = $migration_plugin_manager;
$this->routeMatch = $route_match;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container): self {
return new static(
$container->get('plugin.manager.migration'),
$container->get('current_route_match')
);
}
/**
* {@inheritdoc}
*/
public function getFormId(): string {
return 'migration_execute_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state): array {
$form = $form ?: [];
/** @var \Drupal\migrate_plus\Entity\MigrationInterface $migration */
$migration = $this->getRouteMatch()->getParameter('migration');
$form['#title'] = $this->t('Execute migration %label', ['%label' => $migration->label()]);
$form = $this->buildFormOperations($form, $form_state);
$form = $this->buildFormOptions($form, $form_state);
$form['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Execute'),
];
return $form;
}
/**
* Build the operation form field.
*
* @param array $form
* The execution form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return array
* The execution form updated with the operations.
*/
protected function buildFormOperations(array $form, FormStateInterface $form_state): array {
// Build the migration execution form.
$options = [
'import' => $this->t('Import'),
'rollback' => $this->t('Rollback'),
'stop' => $this->t('Stop'),
'reset' => $this->t('Reset'),
];
$form['operation'] = [
'#type' => 'radios',
'#title' => $this->t('Operation'),
'#description' => $this->t('Choose an operation to run.'),
'#options' => $options,
'#default_value' => 'import',
'#required' => TRUE,
'import' => [
'#description' => $this->t('Imports all previously unprocessed records from the source, plus any records marked for update, into destination Drupal objects.'),
],
'rollback' => [
'#description' => $this->t('Deletes all Drupal objects created by the import.'),
],
'stop' => [
'#description' => $this->t('Cleanly interrupts any import or rollback processes that may currently be running.'),
],
'reset' => [
'#description' => $this->t('Sometimes a process may fail to stop cleanly, and be left stuck in an Importing or Rolling Back status. Choose Reset to clear the status and permit other operations to proceed.'),
],
];
return $form;
}
/**
* Build the execution options form field.
*
* @param array $form
* The execution form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return array
* The execution form updated with the execution options.
*/
protected function buildFormOptions(array $form, FormStateInterface $form_state): array {
$form['options'] = [
'#type' => 'details',
'#title' => $this->t('Additional execution options'),
'#open' => FALSE,
];
$form['options']['update'] = [
'#type' => 'checkbox',
'#title' => $this->t('Update'),
'#description' => $this->t('Check this box to update all previously-imported content in addition to importing new content. Leave unchecked to only import new content'),
];
$form['options']['force'] = [
'#type' => 'checkbox',
'#title' => $this->t('Ignore dependencies'),
'#description' => $this->t('Check this box to ignore dependencies when running imports - all tasks will run whether or not their dependent tasks have completed.'),
];
$form['options']['limit'] = [
'#type' => 'number',
'#title' => $this->t('Limit to:'),
'#size' => 10,
'#description' => $this->t('Set a limit of how many items to process for each migration task.'),
'#min' => 1,
];
$form['options']['idlist'] = [
'#type' => 'textfield',
'#title' => $this->t('ID List'),
'#maxlength' => 255,
'#size' => 60,
'#pattern' => '^[0-9]+(' . MigrateTools::DEFAULT_ID_LIST_DELIMITER . '[0-9]+)?(,?[0-9]+(' . MigrateTools::DEFAULT_ID_LIST_DELIMITER . '[0-9]+)?)*$',
'#description' => $this->t('Comma-separated list of IDs to process.'),
'#states' => [
'enabled' => [
':input[name="operation"]' => [['value' => 'import'], 'or', ['value' => 'rollback']],
],
],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
$migration = $this->getRouteMatch()->getParameter('migration');
if ($migration) {
$migration_id = $migration->id();
/** @var \Drupal\migrate\Plugin\MigrationInterface $migration_plugin */
$migration_plugin = $this->migrationPluginManager->createInstance($migration_id, $migration->toArray());
$migrateMessage = new MigrateMessage();
switch ($form_state->getValue('operation')) {
case 'import':
$executable = new MigrateBatchExecutable($migration_plugin, $migrateMessage, $this->buildOptions($form_state));
$executable->batchImport();
break;
case 'rollback':
$executable = new MigrateBatchExecutable($migration_plugin, $migrateMessage, $this->buildOptions($form_state));
$status = $executable->rollback();
if ($status === MigrationInterface::RESULT_COMPLETED) {
$this->messenger()->addStatus($this->t('Rollback completed', ['@id' => $migration_id]));
}
else {
$this->messenger()->addError($this->t('Rollback of !name migration failed.', ['!name' => $migration_id]));
}
break;
case 'stop':
$migration_plugin->interruptMigration(MigrationInterface::RESULT_STOPPED);
$status = $migration_plugin->getStatus();
switch ($status) {
case MigrationInterface::STATUS_IDLE:
$this->messenger()->addStatus($this->t('Migration @id is idle', ['@id' => $migration_id]));
break;
case MigrationInterface::STATUS_DISABLED:
$this->messenger()->addWarning($this->t('Migration @id is disabled', ['@id' => $migration_id]));
break;
case MigrationInterface::STATUS_STOPPING:
$this->messenger()->addWarning($this->t('Migration @id is already stopping', ['@id' => $migration_id]));
break;
default:
$migration->interruptMigration(MigrationInterface::RESULT_STOPPED);
$this->messenger()->addStatus($this->t('Migration @id requested to stop', ['@id' => $migration_id]));
break;
}
break;
case 'reset':
$status = $migration_plugin->getStatus();
if ($status === MigrationInterface::STATUS_IDLE) {
$this->messenger()->addWarning($this->t('Migration @id is already Idle', ['@id' => $migration_id]));
}
else {
$this->messenger()->addStatus($this->t('Migration @id reset to Idle', ['@id' => $migration_id]));
}
$migration_plugin->setStatus(MigrationInterface::STATUS_IDLE);
break;
}
}
}
/**
* Build migrate execute options from the submitted form values.
*
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return array
* Options array for the migrate execution.
*/
protected function buildOptions(FormStateInterface $form_state) {
$options = [
'limit' => $form_state->getValue('limit') ?: 0,
'update' => $form_state->getValue('update') ?: 0,
'force' => $form_state->getValue('force') ?: 0,
];
if ($idlist = $form_state->getValue('idlist')) {
$options['idlist'] = $idlist;
}
return $options;
}
}

View File

@@ -0,0 +1,157 @@
<?php
declare(strict_types = 1);
namespace Drupal\migrate_tools\Form;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\migrate_plus\Entity\Migration;
use Drupal\migrate_plus\Entity\MigrationGroup;
/**
* Base form for a migration.
*
* @package Drupal\migrate_tools\Form
*
* @ingroup migrate_tools
*/
class MigrationFormBase extends EntityForm {
/**
* Overrides Drupal\Core\Entity\EntityFormController::form().
*
* Builds the entity add/edit form.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* An associative array containing the current state of the form.
*
* @return array
* An associative array containing the migration add/edit form.
*/
public function buildForm(array $form, FormStateInterface $form_state): array {
// Get anything we need from the base class.
$form = parent::buildForm($form, $form_state);
$migration = $this->entity;
assert($migration instanceof Migration);
$form['warning'] = [
'#markup' => $this->t('Creating migrations is not yet supported. See <a href=":url">:url</a>', [
':url' => 'https://www.drupal.org/node/2573241',
]),
];
// Build the form.
$form['label'] = [
'#type' => 'textfield',
'#title' => $this->t('Label'),
'#maxlength' => 255,
'#default_value' => $migration->label(),
'#required' => TRUE,
];
$form['id'] = [
'#type' => 'machine_name',
'#title' => $this->t('Machine name'),
'#default_value' => $migration->id(),
'#machine_name' => [
'exists' => [$this, 'exists'],
'replace_pattern' => '([^a-z0-9_]+)|(^custom$)',
'error' => 'The machine-readable name must be unique, and can only contain lowercase letters, numbers, and underscores. Additionally, it can not be the reserved word "custom".',
],
'#disabled' => !$migration->isNew(),
];
$groups = MigrationGroup::loadMultiple();
$group_options = [];
foreach ($groups as $group) {
$group_options[$group->id()] = $group->label();
}
if (!$migration->migration_group && isset($group_options['default'])) {
$migration->set('migration_group', 'default');
}
$form['migration_group'] = [
'#type' => 'select',
'#title' => $this->t('Migration Group'),
'#empty_value' => '',
'#default_value' => $migration->migration_group,
'#options' => $group_options,
'#description' => $this->t('Assign this migration to an existing group.'),
];
return $form;
}
/**
* Checks for an existing migration group.
*
* @param string|int $entity_id
* The entity ID.
* @param array $element
* The form element.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return bool
* TRUE if this format already exists, FALSE otherwise.
*/
public function exists($entity_id, array $element, FormStateInterface $form_state): bool {
$query = $this->entityTypeManager->getStorage('migration')
->getQuery()
->accessCheck(TRUE);
// Query the entity ID to see if its in use.
$result = $query->condition('id', $element['#field_prefix'] . $entity_id)
->execute();
// We don't need to return the ID, only if it exists or not.
return (bool) $result;
}
/**
* Overrides Drupal\Core\Entity\EntityFormController::actions().
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* An associative array containing the current state of the form.
*
* @return array
* An array of supported actions for the current entity form.
*/
protected function actions(array $form, FormStateInterface $form_state): array {
// Get the basic actions from the base class.
$actions = parent::actions($form, $form_state);
// Change the submit button text.
$actions['submit']['#value'] = $this->t('Save');
// Return the result.
return $actions;
}
/**
* {@inheritdoc}
*/
public function save(array $form, FormStateInterface $form_state): void {
$migration = $this->getEntity();
$status = $migration->save();
if ($status == SAVED_UPDATED) {
// If we edited an existing entity...
$this->messenger()->addStatus($this->t('Migration %label has been updated.', ['%label' => $migration->label()]));
}
else {
// If we created a new entity...
$this->messenger()->addStatus($this->t('Migration %label has been added.', ['%label' => $migration->label()]));
}
// Redirect the user back to the listing route after the save operation.
$form_state->setRedirect('entity.migration.list',
['migration_group' => $migration->get('migration_group')]);
}
}

View File

@@ -0,0 +1,39 @@
<?php
declare(strict_types = 1);
namespace Drupal\migrate_tools\Form;
use Drupal\Core\Form\FormStateInterface;
/**
* Class MigrationGroupAddForm.
*
* Provides the add form for our migration_group entity.
*
* @package Drupal\migrate_tools\Form
*
* @ingroup migrate_tools
*/
class MigrationGroupAddForm extends MigrationGroupFormBase {
/**
* Returns the actions provided by this form.
*
* For our add form, we only need to change the text of the submit button.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* An associative array containing the current state of the form.
*
* @return array
* An array of supported actions for the current entity form.
*/
protected function actions(array $form, FormStateInterface $form_state): array {
$actions = parent::actions($form, $form_state);
$actions['submit']['#value'] = $this->t('Create Migration Group');
return $actions;
}
}

View File

@@ -0,0 +1,74 @@
<?php
declare(strict_types = 1);
namespace Drupal\migrate_tools\Form;
use Drupal\Core\Entity\EntityConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
/**
* Provides the delete form for our Migration Group entity.
*
* @package Drupal\migrate_tools\Form
*
* @ingroup migrate_tools
*/
class MigrationGroupDeleteForm extends EntityConfirmFormBase {
/**
* Gathers a confirmation question.
*
* @return string
* Translated string.
*/
public function getQuestion(): TranslatableMarkup {
return $this->t('Are you sure you want to delete migration group %label?', [
'%label' => $this->entity->label(),
]);
}
/**
* Gather the confirmation text.
*
* @return string
* Translated string.
*/
public function getConfirmText(): TranslatableMarkup {
return $this->t('Delete Migration Group');
}
/**
* Gets the cancel URL.
*
* @return \Drupal\Core\Url
* The URL to go to if the user cancels the deletion.
*/
public function getCancelUrl(): Url {
return new Url('entity.migration_group.list');
}
/**
* The submit handler for the confirm form.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* An associative array containing the current state of the form.
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
// Delete the entity.
$this->entity->delete();
// Set a message that the entity was deleted.
$this->messenger()->addStatus($this->t('Migration group %label was deleted.', [
'%label' => $this->entity->label(),
]));
// Redirect the user to the list controller when complete.
$form_state->setRedirectUrl($this->getCancelUrl());
}
}

View File

@@ -0,0 +1,37 @@
<?php
declare(strict_types = 1);
namespace Drupal\migrate_tools\Form;
use Drupal\Core\Form\FormStateInterface;
/**
* Provides the edit form for our Migration Group entity.
*
* @package Drupal\migrate_tools\Form
*
* @ingroup migrate_tools
*/
class MigrationGroupEditForm extends MigrationGroupFormBase {
/**
* Returns the actions provided by this form.
*
* For the edit form, we only need to change the text of the submit button.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* An associative array containing the current state of the form.
*
* @return array
* An array of supported actions for the current entity form.
*/
public function actions(array $form, FormStateInterface $form_state): array {
$actions = parent::actions($form, $form_state);
$actions['submit']['#value'] = $this->t('Update Migration Group');
return $actions;
}
}

View File

@@ -0,0 +1,144 @@
<?php
declare(strict_types = 1);
namespace Drupal\migrate_tools\Form;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormStateInterface;
/**
* Base form for migration groups.
*
* @package Drupal\migrate_tools\Form
*
* @ingroup migrate_tools
*/
class MigrationGroupFormBase extends EntityForm {
/**
* Overrides Drupal\Core\Entity\EntityFormController::form().
*
* Builds the entity add/edit form.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* An associative array containing the current state of the form.
*
* @return array
* An associative array containing the migration group add/edit form.
*/
public function buildForm(array $form, FormStateInterface $form_state): array {
// Get anything we need from the base class.
$form = parent::buildForm($form, $form_state);
/** @var \Drupal\migrate_plus\Entity\MigrationGroupInterface $migration_group */
$migration_group = $this->entity;
// Build the form.
$form['label'] = [
'#type' => 'textfield',
'#title' => $this->t('Label'),
'#maxlength' => 255,
'#default_value' => $migration_group->label(),
'#required' => TRUE,
];
$form['id'] = [
'#type' => 'machine_name',
'#title' => $this->t('Machine name'),
'#default_value' => $migration_group->id(),
'#machine_name' => [
'exists' => [$this, 'exists'],
'replace_pattern' => '([^a-z0-9_]+)|(^custom$)',
'error' => 'The machine-readable name must be unique, and can only contain lowercase letters, numbers, and underscores. Additionally, it can not be the reserved word "custom".',
],
'#disabled' => !$migration_group->isNew(),
];
$form['description'] = [
'#type' => 'textfield',
'#title' => $this->t('Description'),
'#maxlength' => 255,
'#default_value' => $migration_group->get('description'),
];
$form['source_type'] = [
'#type' => 'textfield',
'#title' => $this->t('Source type'),
'#description' => $this->t('Type of source system the group is migrating from, for example "Drupal 6" or "WordPress 4".'),
'#maxlength' => 255,
'#default_value' => $migration_group->get('source_type'),
];
// Return the form.
return $form;
}
/**
* Checks for an existing migration group.
*
* @param string|int $entity_id
* The entity ID.
* @param array $element
* The form element.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return bool
* TRUE if this format already exists, FALSE otherwise.
*/
public function exists($entity_id, array $element, FormStateInterface $form_state): bool {
$query = $this->entityTypeManager->getStorage('migration_group')
->getQuery()
->accessCheck(TRUE);
// Query the entity ID to see if its in use.
$result = $query->condition('id', $element['#field_prefix'] . $entity_id)
->execute();
// We don't need to return the ID, only if it exists or not.
return (bool) $result;
}
/**
* Overrides Drupal\Core\Entity\EntityFormController::actions().
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* An associative array containing the current state of the form.
*
* @return array
* An array of supported actions for the current entity form.
*/
protected function actions(array $form, FormStateInterface $form_state): array {
// Get the basic actions from the base class.
$actions = parent::actions($form, $form_state);
// Change the submit button text.
$actions['submit']['#value'] = $this->t('Save');
// Return the result.
return $actions;
}
/**
* {@inheritdoc}
*/
public function save(array $form, FormStateInterface $form_state): void {
$migration_group = $this->getEntity();
$status = $migration_group->save();
if ($status == SAVED_UPDATED) {
// If we edited an existing entity...
$this->messenger()->addStatus($this->t('Migration group %label has been updated.', ['%label' => $migration_group->label()]));
}
else {
// If we created a new entity...
$this->messenger()->addStatus($this->t('Migration group %label has been added.', ['%label' => $migration_group->label()]));
}
// Redirect the user back to the listing route after the save operation.
$form_state->setRedirect('entity.migration_group.list');
}
}