Skip to content

Commit

Permalink
Inicial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Karim Boudjema committed Nov 25, 2018
0 parents commit e54b39f
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 0 deletions.
23 changes: 23 additions & 0 deletions README.txt
@@ -0,0 +1,23 @@
EX_BATCH_DRUSH9
===============

This is a simple example of creating a custom Drush 9 command to launch
a batch process.

This kind of command can be launched by a *nix crontab or by the
console command line.

This command will first load the nid of the content type passed as argument.
Next it will launch a batch process for each node and simulate an long
operation.

Install
-------
- Download the module in your /modules/custom directory.
- Install it with Drupal Console: drupal moi ex_batch_drush9

Use
---
drush update-node
drush update-node page
drush update-node article
21 changes: 21 additions & 0 deletions composer.json
@@ -0,0 +1,21 @@
{
"name": "org/ex_batch_drush9",
"description": "This extension provides new commands for Drush.",
"type": "drupal-drush",
"authors": [
{
"name": "Author name",
"email": "author@example.com"
}
],
"require": {
"php": ">=5.6.0"
},
"extra": {
"drush": {
"services": {
"drush.services.yml": "^9"
}
}
}
}
6 changes: 6 additions & 0 deletions drush.services.yml
@@ -0,0 +1,6 @@
services:
ex_batch_drush9.commands:
class: \Drupal\ex_batch_drush9\Commands\ExBatchDrush9Commands
tags:
- { name: drush.command }
arguments: ['@entity_type.manager', '@logger.factory']
5 changes: 5 additions & 0 deletions ex_batch_drush9.info.yml
@@ -0,0 +1,5 @@
name: 'ex_batch_drush9'
type: module
description: 'Example using batch with a Drush 9 custom command'
core: 8.x
package: 'Custom'
Binary file added src/.DS_Store
Binary file not shown.
69 changes: 69 additions & 0 deletions src/BatchService.php
@@ -0,0 +1,69 @@
<?php

namespace Drupal\ex_batch_drush9;

/**
* Class BatchService.
*/
class BatchService {

/**
* Batch process callback.
*
* @param int $id
* Id of the batch.
* @param string $operation_details
* Details of the operation.
* @param object $context
* Context for operations.
*/
public function processMyNode($id, $operation_details, &$context) {

// Simulate long process by waiting 100 microseconds.
usleep(100);

// 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;

// Optional message displayed under the progressbar.
$context['message'] = t('Running Batch "@id" @details',
['@id' => $id, '@details' => $operation_details]
);

}

/**
* 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 processMyNodeFinished($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(t('@count results processed.', ['@count' => count($results)]));
}
else {
// An error occurred.
// $operations contains the operations that remained unprocessed.
$error_operation = reset($operations);
$messenger->addMessage(
t('An error occurred while processing @operation with arguments : @args',
[
'@operation' => $error_operation[0],
'@args' => print_r($error_operation[0], TRUE),
]
)
);
}
}

}
129 changes: 129 additions & 0 deletions src/Commands/ExBatchDrush9Commands.php
@@ -0,0 +1,129 @@
<?php

namespace Drupal\ex_batch_drush9\Commands;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drush\Commands\DrushCommands;

/**
* 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 ExBatchDrush9Commands extends DrushCommands {

/**
* Entity type service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
private $entityTypeManager;

/**
* Logger service.
*
* @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
*/
private $loggerChannelFactory;

/**
* Constructs a new UpdateVideosStatsController object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* Entity type service.
* @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $loggerChannelFactory
* Logger service.
*/
public function __construct(EntityTypeManagerInterface $entityTypeManager, LoggerChannelFactoryInterface $loggerChannelFactory) {
$this->entityTypeManager = $entityTypeManager;
$this->loggerChannelFactory = $loggerChannelFactory;
}

/**
* Update Node.
*
* @param string $type
* Type of node to update
* Argument provided to the drush command.
*
* @command update:node
* @aliases update-node
*
* @usage update:node foo
* foo is the type of node to update
*/
public function updateNode($type = '') {

// 1. Log the start of the script.
$this->loggerChannelFactory->get('ex_batch_drush9')->info('Update nodes batch operations start');

// Check the type of node given as argument, if not, set article as default.
if (strlen($type) == 0) {
$type = 'article';
}

// 2. Retrieve all nodes of this type.
try {
$storage = $this->entityTypeManager->getStorage('node');
$query = $storage->getQuery()
->condition('type', $type)
->condition('status', '1');
$nids = $query->execute();
}
catch (\Exception $e) {
$this->output()->writeln($e);
$this->loggerChannelFactory->get('ex_batch_drush9')->warning('Error found @e', ['@e' => $e]);
}

// 3. Create the operations array for the batch.
$operations = [];
$numOperations = 0;
$batchId = 1;

if (!empty($nids)) {
foreach ($nids as $nid) {
// Prepare the operation. Here we could do other operations on nodes.
$this->output()->writeln("Preparing batch: " . $batchId);

$operations[] = [
'\Drupal\ex_batch_drush9\BatchService::processMyNode',
[
$batchId,
t('Updating node @nid', ['@nid' => $nid]),
],
];
$batchId++;
$numOperations++;
}
}
else {
$this->logger()->warning('No nodes of this type @type', ['@type' => $type]);
}

// 4. Create the batch.
$batch = [
'title' => t('Updating @num node(s)', ['@num' => $numOperations]),
'operations' => $operations,
'finished' => '\Drupal\ex_batch_drush9\BatchService::processMyNodeFinished',
];

// 5. Add batch operations as new batch sets.
batch_set($batch);

// 6. Process the batch sets.
drush_backend_batch_process();

// 6. Show some information.
$this->logger()->notice("Batch operations end.");
// 7. Log some information.
$this->loggerChannelFactory->get('ex_batch_drush9')->info('Update batch operations end.');
}

}

0 comments on commit e54b39f

Please sign in to comment.