Created
November 25, 2022 12:49
-
-
Save msankhala/2eff08854d83804ec045656fe14ea1e6 to your computer and use it in GitHub Desktop.
Drupal 9 batch api example using BatchBuilder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Drupal\miax_content\Command; | |
use Drupal\Core\Batch\BatchBuilder; | |
use Drupal\Core\Entity\EntityTypeManagerInterface; | |
use Drupal\Core\Logger\LoggerChannelFactoryInterface; | |
use Drupal\Core\StringTranslation\StringTranslationTrait; | |
use Drush\Commands\DrushCommands; | |
use Drupal\miax_content\Services\DeleteFeedsBatchService; | |
/** | |
* A Drush commandfile. | |
* | |
* In addition to this file, you need a drush.services.yml | |
* in root of your module, and a composer.json file that provides the name | |
* of the services file to use. | |
* | |
* See these files for an example of injecting Drupal services: | |
* - http://cgit.drupalcode.org/devel/tree/src/Commands/DevelCommands.php | |
* - http://cgit.drupalcode.org/devel/tree/drush.services.yml | |
*/ | |
class DeleteFeeds extends DrushCommands { | |
use StringTranslationTrait; | |
/** | |
* Entity type service. | |
* | |
* @var \Drupal\Core\Entity\EntityTypeManagerInterface | |
*/ | |
private $entityTypeManager; | |
/** | |
* Logger service. | |
* | |
* @var \Drupal\Core\Logger\LoggerChannelFactoryInterface | |
*/ | |
private $loggerChannelFactory; | |
/** | |
* Feeds batch service. | |
* | |
* @var \Drupal\miax_content\Services\DeleteFeedsBatchService | |
*/ | |
private $deleteFeedsBatchService; | |
/** | |
* Constructs a new UpdateVideosStatsController object. | |
* | |
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager | |
* Entity type service. | |
* @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $loggerChannelFactory | |
* Logger service. | |
* @param \Drupal\miax_content\Services\FeedsBatchService $feedsBatchService | |
* Feeds batch service. | |
*/ | |
public function __construct(EntityTypeManagerInterface $entityTypeManager, LoggerChannelFactoryInterface $loggerChannelFactory, DeleteFeedsBatchService $deleteFeedsBatchService) { | |
$this->entityTypeManager = $entityTypeManager; | |
$this->loggerChannelFactory = $loggerChannelFactory; | |
$this->deleteFeedsBatchService = $deleteFeedsBatchService; | |
} | |
/** | |
* Delete the feeds of a given type. | |
* | |
* @param string $type | |
* Type of feed to update | |
* Argument provided to the drush command. | |
* | |
* @command test:feeds:delete-feeds | |
* @aliases test-fdel | |
* | |
* @usage test:feeds:delete-feeds foo | |
* foo is the type of feeds to delete. | |
*/ | |
public function deleteFeed($type = '') { | |
// Ask for confirmation as this operation can not be undone. | |
$this->io()->warning(dt('This operation can not be undone. Are you sure you want to delete all feeds of type @type?', ['@type' => $type])); | |
$confirm = $this->io()->confirm(dt('Are you sure you want to delete all feeds of type @type?', ['@type' => $type])); | |
if (!$confirm) { | |
return; | |
} | |
// 1. Log the start of the script. | |
$this->loggerChannelFactory->get('miax_content')->info('Feeds @type delete batch operations start', ['@type' => $type]); | |
// Check the type of node given as argument, if not, set article as default. | |
if (strlen($type) == 0) { | |
print "No type of feed given, please provide a type of feed to delete."; | |
return; | |
} | |
// 2. Retrieve all feeds of this type. | |
try { | |
$storage = $this->entityTypeManager->getStorage('feeds_feed'); | |
$query = $storage->getQuery() | |
->condition('type', $type); | |
// ->range(0, 1); | |
$fids = $query->execute(); | |
} | |
catch (\Exception $e) { | |
$this->output()->writeln($e); | |
$this->loggerChannelFactory->get('miax_content')->warning('Error found @e', ['@e' => $e]); | |
} | |
// 3. Create the operations array for the batch. | |
$batchBuilder = new BatchBuilder(); | |
// $operations = []; | |
$numOperations = 0; | |
$batchId = 1; | |
if (!empty($fids)) { | |
foreach ($fids as $fid) { | |
// Prepare the operation. Here we could do other operations on nodes. | |
$this->output()->writeln($this->t('Preparing batch: ') . $batchId); | |
$batchBuilder->addOperation([$this->deleteFeedsBatchService, 'deleteFeed'], [ | |
$batchId, | |
$fid, | |
]); | |
$batchId++; | |
$numOperations++; | |
} | |
} | |
else { | |
$this->logger->warning($this->t('No feeds of this type @type', ['@type' => $type])); | |
} | |
// 4. Create the batch. | |
$batchBuilder | |
->setTitle($this->t('Deleting @num node(s)', ['@num' => $numOperations])) | |
->setFinishCallback([$this->deleteFeedsBatchService, 'deleteFeedFinished']) | |
->setErrorMessage($this->t('Batch has encountered an error')); | |
// 5. Add batch operations as new batch sets. | |
batch_set($batchBuilder->toArray()); | |
// 6. Process the batch sets. | |
drush_backend_batch_process(); | |
// 6. Show some information. | |
$this->logger()->notice($this->t("Batch operations end.")); | |
// 7. Log some information. | |
$this->loggerChannelFactory->get('miax_content')->info($this->t('Delete batch operations end.')); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Drupal\miax_content\Services; | |
use Drupal\Core\StringTranslation\StringTranslationTrait; | |
use Drupal\Core\DependencyInjection\DependencySerializationTrait; | |
/** | |
* Class DeleteFeedsBatchService provides the batch processing delete for feeds. | |
*/ | |
class DeleteFeedsBatchService { | |
use StringTranslationTrait; | |
use DependencySerializationTrait; | |
/** | |
* Batch process callback. | |
* | |
* @param int $id | |
* Id of the batch. | |
* @param string $fid | |
* Feed id. | |
* @param object $context | |
* Context for operations. | |
*/ | |
public function deleteFeed($id, $fid, &$context) { | |
// Simulate long process by waiting 100 microseconds. | |
// usleep(100); | |
// Delete the feed. | |
$feed = \Drupal::entityTypeManager()->getStorage('feeds_feed')->load($fid); | |
// print($feed->label()); | |
// die; | |
// $feed->delete(); | |
// Store some results for post-processing in the 'finished' callback. | |
// The contents of 'results' will be available as $results in the | |
// 'finished' function (in this example, batch_example_finished()). | |
$context['results'][] = $id; | |
$context['results'][] = $feed->label(); | |
// Optional message displayed under the progressbar. | |
$context['message'] = $this->t('Running Batch "@id" @fid', | |
['@id' => $id, '@fid' => $feed->label()] | |
); | |
} | |
/** | |
* Batch Finished callback. | |
* | |
* @param bool $success | |
* Success of the operation. | |
* @param array $results | |
* Array of results for post processing. | |
* @param array $operations | |
* Array of operations. | |
*/ | |
public function deleteFeedFinished($success, array $results, array $operations) { | |
$messenger = \Drupal::messenger(); | |
if ($success) { | |
// Here we could do something meaningful with the results. | |
// We just display the number of nodes we processed... | |
$messenger->addMessage($this->t('@count results processed.', ['@count' => count($results)])); | |
} | |
else { | |
// An error occurred. | |
// $operations contains the operations that remained unprocessed. | |
$error_operation = reset($operations); | |
$messenger->addMessage( | |
$this->t('An error occurred while processing @operation with arguments : @args', | |
[ | |
'@operation' => $error_operation[0], | |
'@args' => print_r($error_operation[0], TRUE), | |
] | |
) | |
); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment