View source
<?php
namespace Drupal\entityqueue_smartqueue\Plugin\EntityQueueHandler;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityTypeRepositoryInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\entityqueue\Entity\EntitySubqueue;
use Drupal\entityqueue\EntityQueueInterface;
use Drupal\entityqueue\Plugin\EntityQueueHandler\Multiple;
use Symfony\Component\DependencyInjection\ContainerInterface;
class SmartQueue extends Multiple implements ContainerFactoryPluginInterface {
protected $entityTypeBundleInfo;
protected $entityTypeRepository;
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityTypeRepositoryInterface $entity_type_repository, EntityTypeBundleInfoInterface $entity_type_bundle_info) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager);
$this->entityTypeRepository = $entity_type_repository;
$this->entityTypeBundleInfo = $entity_type_bundle_info;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('entity_type.manager'), $container
->get('entity_type.repository'), $container
->get('entity_type.bundle.info'));
}
public function defaultConfiguration() {
return parent::defaultConfiguration() + [
'entity_type' => '',
'bundles' => '',
];
}
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$form['entity_type'] = [
'#type' => 'select',
'#title' => $this
->t('Entity type'),
'#description' => $this
->t('The entity type for which subqueues will be created automatically.'),
'#options' => $this->entityTypeRepository
->getEntityTypeLabels(TRUE),
'#default_value' => $this->configuration['entity_type'],
'#empty_option' => $this
->t('- Select -'),
'#required' => TRUE,
'#disabled' => !$this->queue
->isNew(),
'#ajax' => [
'wrapper' => 'smartqueue-bundle-wrapper',
'callback' => [
get_class($this),
'smartqueueSettingsAjax',
],
'method' => 'replace',
],
];
$form_state_values = $form_state
->getCompleteFormState()
->getValues();
$entity_type_id = isset($form_state_values['handler_settings_wrapper']) ? $form_state_values['handler_settings_wrapper']['handler_settings']['entity_type'] : $this->configuration['entity_type'];
if ($bundle_options = $this
->getBundleOptions($entity_type_id)) {
$form['bundles'] = [
'#type' => 'checkboxes',
'#title' => $this->entityTypeManager
->getDefinition($entity_type_id)
->getBundleLabel(),
'#options' => $bundle_options,
'#default_value' => (array) $this->configuration['bundles'],
'#required' => TRUE,
'#size' => 6,
'#multiple' => TRUE,
'#prefix' => '<div id="smartqueue-bundle-wrapper">',
'#suffix' => '</div>',
];
}
else {
$form['bundles'] = [
'#type' => 'value',
'#value' => [
$entity_type_id => $entity_type_id,
],
'#prefix' => '<div id="smartqueue-bundle-wrapper">',
'#suffix' => '</div>',
];
}
return $form;
}
public function getBundleOptions($entity_type_id) {
$bundle_options = [];
if (!$entity_type_id) {
return $bundle_options;
}
$entity_type = $this->entityTypeManager
->getDefinition($entity_type_id);
if ($entity_type
->hasKey('bundle')) {
foreach ($this->entityTypeBundleInfo
->getBundleInfo($entity_type_id) as $bundle_name => $bundle_info) {
$bundle_options[$bundle_name] = $bundle_info['label'];
}
natsort($bundle_options);
}
return $bundle_options;
}
public static function smartqueueSettingsAjax($form, FormStateInterface $form_state) {
return $form['handler_settings_wrapper']['handler_settings']['bundles'];
}
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
parent::submitConfigurationForm($form, $form_state);
$this->configuration['entity_type'] = $form_state
->getValue('entity_type');
$this->configuration['bundles'] = $form_state
->getValue('bundles');
}
public function hasAutomatedSubqueues() {
return TRUE;
}
public function onQueuePostSave(EntityQueueInterface $queue, EntityStorageInterface $storage, $update = TRUE) {
parent::onQueuePostSave($queue, $storage, $update);
$operations = [];
$subqueue_ids = $this->entityTypeManager
->getStorage('entity_subqueue')
->getQuery()
->condition('queue', $queue
->id())
->execute();
$subqueue_id_list = array_map(function ($subqueue_id) use ($queue) {
return $queue
->id() . '__' . $subqueue_id;
}, $this
->getEntityIds());
$subqueue_diff = array_diff($subqueue_ids, $subqueue_id_list);
$subqueue_diff_chunks = array_chunk($subqueue_diff, 20);
foreach ($subqueue_diff_chunks as $subqueue_diff_chunk) {
$operations[] = [
[
$this,
'deleteSubqueues',
],
[
$subqueue_diff_chunk,
],
];
}
$entity_ids = $this
->getEntityIds();
$entity_id_chunks = array_chunk($entity_ids, 20);
foreach ($entity_id_chunks as $entity_id_chunk) {
$operations[] = [
[
$this,
'initSubqueuesCreate',
],
[
$queue,
$entity_id_chunk,
$this->configuration['entity_type'],
],
];
}
$batch = [
'title' => t('Creating/deleting subqueues according to configuration'),
'operations' => $operations,
'finished' => [
get_class($this),
'initSubqueuesFinished',
],
];
batch_set($batch);
}
public function onQueuePostDelete(EntityQueueInterface $queue, EntityStorageInterface $storage) {
$subqueue_ids = $this->entityTypeManager
->getStorage('entity_subqueue')
->getQuery()
->condition('queue', $queue
->id())
->execute();
$subqueue_id_chunks = array_chunk($subqueue_ids, 20);
$operations = [];
foreach ($subqueue_id_chunks as $subqueue_id_chunk) {
$operations[] = [
[
$this,
'deleteSubqueues',
],
[
$subqueue_id_chunk,
],
];
}
$batch = [
'title' => t('Deleting subqueues'),
'operations' => $operations,
'finished' => [
get_class($this),
'deleteSubqueuesFinished',
],
];
batch_set($batch);
}
public function initSubqueuesCreate($queue, $entity_ids, $entity_type_id, &$context) {
$subqueue_ids = $this->entityTypeManager
->getStorage('entity_subqueue')
->getQuery()
->condition('queue', $queue
->id())
->execute();
$entities = $this->entityTypeManager
->getStorage($entity_type_id)
->loadMultiple($entity_ids);
foreach ($entities as $entity) {
$new_subqueue_id = $queue
->id() . '__' . $entity
->id();
if (in_array($new_subqueue_id, $subqueue_ids)) {
continue;
}
$subqueue = EntitySubqueue::create([
'queue' => $queue
->id(),
'name' => $new_subqueue_id,
'title' => $entity
->label(),
'langcode' => $queue
->language()
->getId(),
'attached_entity' => $entity,
]);
$subqueue
->save();
$context['results'][] = $subqueue
->id();
$context['message'] = $this
->t('Created subqueue for entity with @id', [
'@id' => $entity
->id(),
]);
}
}
public static function initSubqueuesFinished($success, $result, $operations) {
if ($success) {
$message = new TranslatableMarkup('Subqueues successfully initialized.');
}
else {
$message = new TranslatableMarkup('Subqueues could not the created.');
}
\Drupal::messenger()
->addMessage($message);
}
public function deleteSubqueues($subqueue_ids, &$context) {
$storage = $this->entityTypeManager
->getStorage('entity_subqueue');
$subqueues = $storage
->loadMultiple($subqueue_ids);
$storage
->delete($subqueues);
foreach ($subqueues as $subqueue) {
$context['message'] = $this
->t('Deleted subqueue @id', [
'@id' => $subqueue
->id(),
]);
}
}
public static function deleteSubqueuesFinished($success, $result, $operations) {
if ($success) {
$message = new TranslatableMarkup('Subqueues successfully deleted.');
}
else {
$message = new TranslatableMarkup('Subqueues could not be deleted.');
}
\Drupal::messenger()
->addMessage($message);
}
public function getEntityIds() {
$entity_type_id = $this->configuration['entity_type'];
$entity_type = $this->entityTypeManager
->getDefinition($entity_type_id);
$query = $this->entityTypeManager
->getStorage($entity_type_id)
->getQuery();
if ($entity_type
->hasKey('bundle') && !empty($this->configuration['bundles'])) {
$query
->condition($entity_type
->getKey('bundle'), $this->configuration['bundles'], 'IN');
}
return $query
->execute();
}
}