diff --git a/src/Controller/ScheduleController.php b/src/Controller/ScheduleController.php index 24ec7b9..53ffd84 100644 --- a/src/Controller/ScheduleController.php +++ b/src/Controller/ScheduleController.php @@ -3,6 +3,7 @@ namespace Drupal\business_rules\Controller; use Drupal\Core\Link; +use Drupal\business_rules\BusinessRulesItemObject; use Drupal\business_rules\Entity\Action; use Drupal\business_rules\Entity\Schedule; use Drupal\business_rules\Events\BusinessRulesEvent; @@ -110,70 +111,66 @@ class ScheduleController extends ControllerBase implements ContainerInjectionInt * The redirect response. */ public function execute($business_rules_schedule) { - $task = Schedule::load($business_rules_schedule); - - /** @var \Drupal\business_rules\Entity\Action $action */ - $action = $task->getTriggeredBy(); - $items = $action->getSettings('items'); $container = \Drupal::getContainer(); $util = new BusinessRulesUtil($container); - $reacts_on_definition = \Drupal::getContainer() - ->get('plugin.manager.business_rules.reacts_on') - ->getDefinition('cron_runs'); - - - $task_event = $task->getEvent(); - $loop_control = time(); - $dummy = new \stdClass(); - $variables = new VariablesSet(); - - $dummy_event = new BusinessRulesEvent($dummy, [ - 'entity_type_id' => '', - 'bundle' => NULL, - 'entity' => NULL, - 'entity_unchanged' => NULL, - 'variables' => $variables, - 'reacts_on' => $reacts_on_definition, - 'loop_control' => $loop_control, - ]); + $task = Schedule::load($business_rules_schedule); - $event = $task_event instanceof BusinessRulesEvent ? $task_event : $dummy_event; - /** @var \Drupal\Core\Entity\Entity $entity */ - $entity = $task_event ? $task_event->getSubject() instanceof Entity ? $task_event->getSubject() : FALSE : FALSE; - if ($entity) { - $entity = \Drupal::entityTypeManager() - ->getStorage($entity->getEntityTypeId()) - ->load($entity->id()); - $task_event->setArgument('entity', $entity); - $event = new BusinessRulesEvent($entity, $task_event->getArguments()); - } + /** @var \Drupal\business_rules\Entity\Action $action */ + $action = $task->getTriggeredBy(); + $items = $action->getSettings('items'); + $task_event = $task->getEvent(); try { - foreach ($items as $item) { - $action_item = Action::load($item['id']); - $action_item->execute($event); - } - - $entity = $event->getSubject() instanceof Entity ? $event->getSubject() : FALSE; - if ($entity && $task->getUpdateEntity()) { - $entity_exists = \Drupal::entityTypeManager() - ->getStorage($entity->getEntityTypeId()) - ->load($entity->id()); - if ($entity_exists instanceof EntityInterface) { + $reacts_on_definition = $container + ->get('plugin.manager.business_rules.reacts_on') + ->getDefinition($task_event['reacts_on']); + + $entity = \Drupal::entityTypeManager() + ->getStorage($task_event['entity_type_id']) + ->load($task_event['entity_id']); + + if ($entity) { + $event = new BusinessRulesEvent($entity, [ + 'entity_type_id' => $task_event['entity_type_id'], + 'bundle' => $entity->bundle(), + 'entity' => $entity, + 'entity_unchanged' => $entity, + 'reacts_on' => $reacts_on_definition, + 'loop_control' => $task_event['entity_type_id'] . $entity->id(), + 'variables' => new \Drupal\business_rules\VariablesSet(), + ]); + + // Execute items using business rules processor. + $processor = $container->get('business_rules.processor'); + $processor->ruleBeingExecuted = $action; + $processor->processItems(BusinessRulesItemObject::itemsArrayToItemsObject($items), $event, $task->id()); + + if ($task->getUpdateEntity()) { $entity->save(); } - } - $task->setExecuted(1); - $task->save(); - $util->logger->notice(t('Scheduled task id: @id, name: "@name", triggered by: "@by" has been executed at: @time', [ - '@id' => $task->id(), - '@name' => $task->getName(), - '@by' => $task->getTriggeredBy()->id(), - '@time' => $container->get('date.formatter') - ->format(time(), 'medium'), - ])); + $task->setExecuted(1); + $task->save(); + $util->logger->notice(t('Scheduled task id: @id, name: "@name", triggered by: "@by" has been executed at: @time', [ + '@id' => $task->id(), + '@name' => $task->getName(), + '@by' => $task->getTriggeredBy()->id(), + '@time' => $container->get('date.formatter') + ->format(time(), 'medium'), + ])); + } + else { + $util->logger->warning(t('Scheduled task id: @id, name: "@name", triggered by: "@by" has not been executed at: @time because target entity type: @entity_type, id: @entity_id does not exist anymore', [ + '@id' => $task->id(), + '@name' => $task->getName(), + '@by' => $task->getTriggeredBy()->id(), + '@time' => $container->get('date.formatter') + ->format(time(), 'medium'), + '@entity_type' => $task_event['entity_type_id'], + '@entity_id' => $task_event['entity_id'], + ])); + } } catch (\Exception $e) { $util->logger->error($e->getMessage()); diff --git a/src/Entity/Schedule.php b/src/Entity/Schedule.php index 528ad68..76a4ee9 100644 --- a/src/Entity/Schedule.php +++ b/src/Entity/Schedule.php @@ -2,9 +2,10 @@ namespace Drupal\business_rules\Entity; +use Drupal\business_rules\BusinessRulesItemObject; use Drupal\business_rules\Events\BusinessRulesEvent; use Drupal\business_rules\Util\BusinessRulesUtil; -use Drupal\Core\Entity\Entity; +use Drupal\business_rules\VariablesSet; use Drupal\Core\Entity\EntityChangedTrait; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityStorageInterface; @@ -225,20 +226,27 @@ class Schedule extends RevisionableContentEntityBase implements ScheduleInterfac * {@inheritdoc} */ public function getEvent() { - $value = $this->get('event')->getValue(); - $event = isset($value[0]) ? $value[0] : FALSE; - - return $event; + $data = []; + if (!$this->get('event')->isEmpty()) { + $data = $this->get('event')->first()->getValue(); + } + return isset($data['data']) ? $data['data'] : NULL; } /** * {@inheritdoc} */ public function setEvent(BusinessRulesEvent $event) { - $stored_event = new BusinessRulesEvent($event->getSubject(), $event->getArguments()); - $stored_event = serialize($stored_event); - $this->set('event', $stored_event); + $arguments = $event->getArguments(); + $entity = $event->getSubject(); + + $value = [ + 'reacts_on' => $arguments['reacts_on']['id'], + 'entity_type_id' => $arguments['entity_type_id'], + 'entity_id' => $entity->id(), + ]; + $this->set('event', ['data' => $value]); return $this; } @@ -424,39 +432,56 @@ class Schedule extends RevisionableContentEntityBase implements ScheduleInterfac $task_event = $task->getEvent(); try { - /** @var \Drupal\Core\Entity\Entity $entity */ - $entity = $task_event->getSubject() instanceof Entity ? $task_event->getSubject() : FALSE; - if ($entity) { - $entity = \Drupal::entityTypeManager() - ->getStorage($entity->getEntityTypeId()) - ->load($entity->id()); - $task_event->setArgument('entity', $entity); - $task_event = new BusinessRulesEvent($entity, $task_event->getArguments()); - } + $reacts_on_definition = $container + ->get('plugin.manager.business_rules.reacts_on') + ->getDefinition($task_event['reacts_on']); - foreach ($items as $item) { - $action_item = Action::load($item['id']); - $action_item->execute($task_event); - } - - if ($entity && $task->getUpdateEntity()) { - $entity_exists = \Drupal::entityTypeManager() - ->getStorage($entity->getEntityTypeId()) - ->load($entity->id()); - if ($entity_exists instanceof EntityInterface) { + $entity = \Drupal::entityTypeManager() + ->getStorage($task_event['entity_type_id']) + ->load($task_event['entity_id']); + + if ($entity) { + $event = new BusinessRulesEvent($entity, [ + 'entity_type_id' => $task_event['entity_type_id'], + 'bundle' => $entity->bundle(), + 'entity' => $entity, + 'entity_unchanged' => $entity, + 'reacts_on' => $reacts_on_definition, + 'loop_control' => $task_event['entity_type_id'] . $entity->id(), + 'variables' => new VariablesSet(), + ]); + + // Execute items using business rules processor. + $processor = $container->get('business_rules.processor'); + $processor->ruleBeingExecuted = $action; + $processor->processItems(BusinessRulesItemObject::itemsArrayToItemsObject($items), $event, $task->id()); + + if ($task->getUpdateEntity()) { $entity->save(); } - } - $task->setExecuted(1); - $task->save(); - $util->logger->notice(t('Scheduled task id: @id, name: "@name", triggered by: "@by" has been executed at: @time', [ - '@id' => $task->id(), - '@name' => $task->getName(), - '@by' => $task->getTriggeredBy()->id(), - '@time' => $container->get('date.formatter') - ->format(time(), 'medium'), - ])); + $task->setExecuted(1); + $task->save(); + $util->logger->notice(t('Scheduled task id: @id, name: "@name", triggered by: "@by" has been executed at: @time', [ + '@id' => $task->id(), + '@name' => $task->getName(), + '@by' => $task->getTriggeredBy()->id(), + '@time' => $container->get('date.formatter') + ->format(time(), 'medium'), + ])); + } + else { + $task->delete(); + $util->logger->warning(t('Scheduled task id: @id, name: "@name", triggered by: "@by" has been deleted at: @time because target entity type: @entity_type, id: @entity_id does not exist anymore', [ + '@id' => $task->id(), + '@name' => $task->getName(), + '@by' => $task->getTriggeredBy()->id(), + '@time' => $container->get('date.formatter') + ->format(time(), 'medium'), + '@entity_type' => $task_event['entity_type_id'], + '@entity_id' => $task_event['entity_id'], + ])); + } } catch (\Exception $e) { $util->logger->error($e->getMessage());