Skip to content

Instantly share code, notes, and snippets.

@Mykola-Veryha
Created April 15, 2020 16:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Mykola-Veryha/34c5af4169dc7a63c761cca8f28780b8 to your computer and use it in GitHub Desktop.
Save Mykola-Veryha/34c5af4169dc7a63c761cca8f28780b8 to your computer and use it in GitHub Desktop.
<?php
namespace Drupal\ln_follow_and_alert\Form;
use Drupal\Core\Batch\BatchBuilder;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* BuildFollowEntitiesBatchForm.
*/
class BuildFollowEntitiesBatchForm extends FormBase {
/**
* Batch Builder.
*
* @var \Drupal\Core\Batch\BatchBuilder
*/
protected $batchBuilder;
/**
* Node storage.
*
* @var \Drupal\node\NodeStorageInterface
*/
protected $nodeStorage;
/**
* BuildFollowEntitiesBatchForm constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function __construct(
EntityTypeManagerInterface $entity_type_manager
) {
$this->nodeStorage = $entity_type_manager->getStorage('node');
$this->batchBuilder = new BatchBuilder();
}
/**
* {@inheritdoc}
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*
* @noinspection PhpParamsInspection
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager')
);
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'ln_build_follow_entities_batch_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['help'] = [
'#markup' => $this->t('Create follow entities for news.'),
];
$form['actions'] = ['#type' => 'actions'];
$form['actions']['run'] = [
'#type' => 'submit',
'#value' => $this->t('Run batch'),
'#button_type' => 'primary',
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$nids = $this->nodeStorage->getQuery()
->condition('type', 'news')
->execute();
$this->batchBuilder
->setTitle($this->t('Processing'))
->setInitMessage($this->t('Initializing.'))
->setProgressMessage($this->t('Completed @current of @total.'))
->setErrorMessage($this->t('An error has occurred.'));
$this->batchBuilder->setFile(
drupal_get_path('module', 'ln_follow_and_alert') . '/src/Form/BuildFollowEntitiesBatchForm.php'
);
$this->batchBuilder->addOperation([$this, 'processItems'], [$nids]);
$this->batchBuilder->setFinishCallback([$this, 'finished']);
batch_set($this->batchBuilder->toArray());
}
/**
* Processor for batch operations.
*
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function processItems($items, array &$context) {
// Elements per operation.
$limit = 5;
// Set default progress values.
if (empty($context['sandbox']['progress'])) {
$context['sandbox']['progress'] = 0;
$context['sandbox']['max'] = count($items);
}
// Save items to array which will be changed during processing.
if (empty($context['sandbox']['items'])) {
$context['sandbox']['items'] = $items;
}
$counter = 0;
if (!empty($context['sandbox']['items'])) {
// Remove already processed items.
if ($context['sandbox']['progress'] != 0) {
array_splice($context['sandbox']['items'], 0, $limit);
}
foreach ($context['sandbox']['items'] as $item) {
if ($counter != $limit) {
$this->processItem($item);
$counter++;
$context['sandbox']['progress']++;
$context['message'] = $this->t('Now processing node :progress of :count', [
':progress' => $context['sandbox']['progress'],
':count' => $context['sandbox']['max'],
]);
// Increment total processed item values. Will be used in finished
// callback.
$context['results']['processed'] = $context['sandbox']['progress'];
}
}
}
// If not finished all tasks, we count percentage of process. 1 = 100%.
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
}
/**
* Process single item.
*
* @param int|string $nid
* An id of Node.
*
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function processItem($nid) {
/** @var \Drupal\node\NodeInterface $node */
$node = $this->nodeStorage->load($nid);
_news_node_postsave($node);
}
/**
* Finished callback for batch.
*
* @noinspection PhpUnusedParameterInspection
*/
public function finished($success, $results, $operations) {
$message = $this->t('Number of nodes affected by batch: @count', [
'@count' => $results['processed'],
]);
$this->messenger()
->addStatus($message);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment