View source
<?php
namespace Drupal\views_bulk_operations\Service;
use Drupal\Core\TypedData\TranslatableInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\views\Views;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Entity\EntityInterface;
use Drupal\views_bulk_operations\ViewsBulkOperationsBatch;
class ViewsBulkOperationsActionProcessor implements ViewsBulkOperationsActionProcessorInterface {
use StringTranslationTrait;
protected $viewDataService;
protected $entityTypeManager;
protected $actionManager;
protected $user;
protected $moduleHandler;
protected $initialized = FALSE;
protected $actionDefinition;
protected $action;
protected $view;
protected $bulkFormData;
protected $queue = [];
public function __construct(ViewsbulkOperationsViewDataInterface $viewDataService, EntityTypeManagerInterface $entityTypeManager, ViewsBulkOperationsActionManager $actionManager, AccountProxyInterface $user, ModuleHandlerInterface $moduleHandler) {
$this->viewDataService = $viewDataService;
$this->entityTypeManager = $entityTypeManager;
$this->actionManager = $actionManager;
$this->user = $user;
$this->moduleHandler = $moduleHandler;
}
public function initialize(array $view_data, $view = NULL) {
if ($this->initialized) {
$this->queue = [];
}
if (!isset($view_data['configuration'])) {
$view_data['configuration'] = [];
}
if (!empty($view_data['preconfiguration'])) {
$view_data['configuration'] += $view_data['preconfiguration'];
}
$this->actionDefinition = $this->actionManager
->getDefinition($view_data['action_id']);
$this->action = $this->actionManager
->createInstance($view_data['action_id'], $view_data['configuration']);
$this
->setActionContext($view_data);
$this->bulkFormData = $view_data;
$this
->setView($view);
$this->initialized = TRUE;
}
protected function setView($view = NULL) {
if (!is_null($view)) {
$this->view = $view;
}
else {
$this->view = Views::getView($this->bulkFormData['view_id']);
$this->view
->setDisplay($this->bulkFormData['display_id']);
if (!empty($this->bulkFormData['arguments'])) {
$this->view
->setArguments($this->bulkFormData['arguments']);
}
if (!empty($this->bulkFormData['exposed_input'])) {
$this->view
->setExposedInput($this->bulkFormData['exposed_input']);
}
}
}
public function populateQueue(array $list, array &$context = []) {
if (!empty($context)) {
$batch_size = $this->bulkFormData['batch_size'];
if (!isset($context['sandbox']['current_batch'])) {
$context['sandbox']['current_batch'] = 0;
}
$current_batch =& $context['sandbox']['current_batch'];
$offset = $current_batch * $batch_size;
}
else {
$batch_size = 0;
$current_batch = 0;
$offset = 0;
}
if (empty($list)) {
$this->view
->setItemsPerPage($batch_size);
$this->view
->setCurrentPage($current_batch);
$this->view
->build();
if ($view_offset = $this->view->pager
->getOffset()) {
$offset += $view_offset;
}
$this->view->query
->setLimit($batch_size);
$this->view->query
->setOffset($offset);
$this->moduleHandler
->invokeAll('views_pre_execute', [
$this->view,
]);
$this->view->query
->execute($this->view);
$this->viewDataService
->init($this->view, $this->view
->getDisplay(), $this->bulkFormData['relationship_id']);
foreach ($this->view->result as $row) {
$this->queue[] = $this->viewDataService
->getEntity($row);
}
}
else {
if ($batch_size) {
$batch_list = array_slice($list, $offset, $batch_size);
}
else {
$batch_list = $list;
}
foreach ($batch_list as $item) {
$this->queue[] = $this
->getEntity($item);
}
if ($this->actionDefinition['pass_view']) {
$this
->populateViewResult($batch_list, $context, $current_batch);
}
}
if (!empty($context)) {
if (!isset($context['sandbox']['total'])) {
if (empty($list)) {
$context['sandbox']['total'] = $this->viewDataService
->getTotalResults();
}
else {
$context['sandbox']['total'] = count($list);
}
}
if ($this->actionDefinition['pass_context']) {
$context['sandbox']['batch_size'] = $batch_size;
$this->action
->setContext($context);
}
}
if ($batch_size) {
$current_batch++;
}
if ($this->actionDefinition['pass_view']) {
$this->action
->setView($this->view);
}
return count($this->queue);
}
public function setActionContext(array $context) {
if (isset($this->action) && method_exists($this->action, 'setContext')) {
$this->action
->setContext($context);
}
}
public function process() {
$output = [];
foreach ($this->queue as $delta => $entity) {
if (!$entity instanceof EntityInterface) {
$output[] = $this
->t('Skipped');
unset($this->queue[$delta]);
}
}
if (!empty($this->actionDefinition['type'])) {
foreach ($this->queue as $delta => $entity) {
if ($entity
->getEntityTypeId() !== $this->actionDefinition['type']) {
$output[] = $this
->t('Entity type not supported');
unset($this->queue[$delta]);
}
}
}
foreach ($this->queue as $delta => $entity) {
if (!$this->action
->access($entity, $this->user)) {
$output[] = $this
->t('Access denied');
unset($this->queue[$delta]);
}
}
$results = $this->action
->executeMultiple($this->queue);
if (empty($results)) {
$count = count($this->queue);
for ($i = 0; $i < $count; $i++) {
$output[] = $this->bulkFormData['action_label'];
}
}
else {
foreach ($results as $result) {
$output[] = $result;
}
}
return $output;
}
public function executeProcessing(array &$data, $view = NULL) {
if ($data['batch']) {
$batch = ViewsBulkOperationsBatch::getBatch($data);
batch_set($batch);
}
else {
$list = $data['list'];
if (!$this->initialized) {
$this
->initialize($data, $view);
}
if ($this
->populateQueue($list)) {
$batch_results = $this
->process();
}
$results = [
'operations' => [],
];
foreach ($batch_results as $result) {
$results['operations'][] = (string) $result;
}
ViewsBulkOperationsBatch::finished(TRUE, $results, []);
}
}
public function getEntity(array $entity_data) {
if (!isset($entity_data[4])) {
$entity_data[4] = FALSE;
}
list(, $langcode, $entity_type_id, $id, $revision_id) = $entity_data;
$entityStorage = $this->entityTypeManager
->getStorage($entity_type_id);
$entity = $revision_id ? $entityStorage
->loadRevision($revision_id) : $entityStorage
->load($id);
if ($entity instanceof TranslatableInterface) {
$entity = $entity
->getTranslation($langcode);
}
return $entity;
}
protected function populateViewResult(array $list, array $context, $current_batch) {
if (!empty($this->bulkFormData['prepopulated'])) {
$this->view
->setItemsPerPage($this->bulkFormData['batch_size']);
$this->view
->setCurrentPage($current_batch);
$this->view
->build();
$this->moduleHandler
->invokeAll('views_pre_execute', [
$this->view,
]);
$this->view->query
->execute($this->view);
}
else {
if ($this->bulkFormData['current_page']) {
$this->view
->setCurrentPage($this->bulkFormData['current_page']);
}
$this->view
->build();
$this->moduleHandler
->invokeAll('views_pre_execute', [
$this->view,
]);
$this->view->query
->execute($this->view);
foreach ($this->view->result as $delta => $row) {
$entity = $this->viewDataService
->getEntity($row);
$unset = TRUE;
foreach ($list as $item) {
if ($item[1] === $entity
->language()
->getId() && $item[2] === $entity
->getEntityTypeId() && $item[3] === $entity
->id()) {
$unset = FALSE;
break;
}
}
if ($unset) {
unset($this->view->result[$delta]);
}
}
}
}
public function getQueue() {
return $this->queue;
}
}