metatags_quick-4.0.x-dev/metatags_quick.drush.inc
metatags_quick.drush.inc
<?php
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
/**
* Drush commands for metatags_quick.
*/
class MetatagsQuickCommands {
/**
* The database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The messenger service.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
/**
* MetatagsQuickCommands constructor.
*
* @param \Drupal\Core\Database\Connection $database
* The database connection.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
* The module handler.
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
* The messenger service.
*/
public function __construct(Connection $database, EntityTypeManagerInterface $entityTypeManager, ModuleHandlerInterface $moduleHandler, MessengerInterface $messenger) {
$this->database = $database;
$this->entityTypeManager = $entityTypeManager;
$this->moduleHandler = $moduleHandler;
$this->messenger = $messenger;
}
/**
* Migrate from nodewords to metatags-quick.
*
* @command metatags-quick-migrate
* @aliases mqm
*
* @param array $fieldNames
* An optional list of field names. If not specified, all available fields will be migrated.
*
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function metatagsQuickMigrate(array $fieldNames = []) {
$fieldNames = $this->metatagsQuickMigrateGetFields($fieldNames);
if (empty($fieldNames)) {
$this->messenger->addError(new TranslatableMarkup('No fields to migrate.'));
return;
}
$this->messenger->addStatus(new TranslatableMarkup('The following fields will be migrated: @fields', ['@fields' => implode(', ', $fieldNames)]));
if (!$this->moduleHandler->moduleExists('metatags_quick')) {
$this->messenger->addError(new TranslatableMarkup('The metatags_quick module is not installed or enabled.'));
return;
}
if (!$this->moduleHandler->moduleExists('metatags_quick_import')) {
$this->messenger->addError(new TranslatableMarkup('The metatags_quick_import module is not installed or enabled.'));
return;
}
$confirmationMessage = new TranslatableMarkup('Do you really want to continue?');
if (!$confirmationMessage) {
return;
}
foreach ($fieldNames as $fieldName) {
$fields[$fieldName] = $fieldName;
}
$this->metatagsQuickMigrateFields($fields);
// Log Drupal messages and output a completion message.
$this->logDrupalMessages();
$this->messenger->addStatus(new TranslatableMarkup('Migration complete'));
}
/**
* Migrate fields.
*
* @param array $fieldNames
* An array of field names to migrate.
*
* @throws \Drupal\Core\Entity\EntityStorageException
*/
protected function metatagsQuickMigrateFields(array $fieldNames) {
if (empty($fieldNames)) {
return;
}
// Step 1: Create fields if they don't exist.
// Note: We upgrade only node data!
$nodeBundles = $this->entityTypeManager->getStorage('node_type')->loadMultiple();
if (empty($nodeBundles)) {
$this->messenger->addError(new TranslatableMarkup('No content types found. Define them first.'));
return;
}
foreach ($fieldNames as $fieldName) {
if (empty($fieldName)) {
continue;
}
foreach ($nodeBundles as $bundle) {
$this->entityTypeManager->getStorage('field_storage_config')->create([
'field_name' => $fieldName,
'entity_type' => 'node',
'type' => 'string',
])->save();
$this->entityTypeManager->getStorage('field_config')->create([
'field_name' => $fieldName,
'entity_type' => 'node',
'bundle' => $bundle->id(),
])->save();
}
}
$fieldsToImport = array_filter($fieldNames);
$numOperations = $this->metatagsQuickGetNodeCount();
$_SESSION['nodewords_upgrade_total'] = $numOperations;
$_SESSION['nodewords_upgrade_processed'] = 0;
$this->messenger->addStatus(new TranslatableMarkup('Converting metatags for @num nodes', ['@num' => $numOperations]));
$nids = $this->database->select('node', 'n')
->fields('n', ['nid'])
->execute()
->fetchCol();
$batch = [
'operations' => [],
'progress_message' => new TranslatableMarkup('Completed @nodesCompleted of @nodesTotal', [
'@nodesCompleted' => $_SESSION['nodewords_upgrade_processed'],
'@nodesTotal' => $_SESSION['nodewords_upgrade_total'],
]),
'finished' => 'metatags_quick_upgrade_finished',
'file' => $this->moduleHandler->getModule('metatags_quick')->getPath() . '/metatags_quick_import.admin.inc',
];
$nidsChunks = array_chunk($nids, 1000);
foreach ($nidsChunks as $nidsChunk) {
$batch['operations'][] = [
'metatags_quick_convert_metatags',
[$nidsChunk, $fieldsToImport],
];
}
batch_set($batch);
batch_process();
}
/**
* Get the number of nodes to convert.
*
* @return int
* The number of nodes to convert.
*/
protected function metatagsQuickGetNodeCount() {
return $this->database->select('node', 'n')
->countQuery()
->execute()
->fetchField();
}
/**
* Get the available fields to migrate.
*
* @param array $requests
* An array of field names.
*
* @return array
* The available fields to migrate.
*/
protected function metatagsQuickMigrateGetFields(array $requests = []) {
$fields = [
'abstract' => 'abstract',
'copyright' => 'copyright',
'description' => 'description',
'geourl' => 'location',
'keywords' => 'keywords',
'Revisit-After' => 'revisit-after',
'robots' => 'robots',
];
$options = array_intersect($fields, $requests);
if (!empty($requests) && !empty($options)) {
$notFound = array_diff($requests, $options);
if (!empty($notFound)) {
$this->messenger->addError(new TranslatableMarkup('The following fields were not found: @fields', ['@fields' => implode(', ', $notFound)]));
return [];
}
}
return array_values($options);
}
/**
* Log Drupal messages.
*/
protected function logDrupalMessages() {
$messages = $this->messenger->all();
foreach ($messages as $type => $messageList) {
foreach ($messageList as $message) {
$this->messenger->addStatus($message);
}
}
}
}
