Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Karim Boudjema
committed
Nov 25, 2018
0 parents
commit e54b39f
Showing
7 changed files
with
253 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" | ||
} | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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'] |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 not shown.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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), | ||
] | ||
) | ||
); | ||
} | ||
} | ||
|
||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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.'); | ||
} | ||
|
||
} |