Problem/Motivation
When BR is processing multiple events within a single PHP request, variables are not evaluated for the consecutive calls, because they are cached by variable IDs (which will be the same for the same event type/entity type combination)
For example, running a migration will trigger entity_insert/entity_update events multiple times within the single PHP process, however with different entities as arguments. BR must evaluate variables based on the event and its data, and variable ID.
This leading to the PHP fatal errors like:
- Call to a member function getValue() on null in \Drupal\business_rules\Plugin\BusinessRulesAction\LoopThroughViewResult->execute()
- Call to a member function getValue() on null in \Drupal\BusinessRulesCondition\UserVariableHasRole->process()
Proposed resolution
Rewrite evaluated variables "caching" system to account for the passed event data and variable ID
Remaining tasks
Review patch
User interface changes
No
API changes
No
Data model changes
No
Original report
Using the latest 8.x-dev-version:
I need to run 5 loops at the same time during cron. I separated them in different business rules, to be able to enable and disable any of them. It runs fine as long only one loop is firing (due to a view providing 1 value).
as soon as two loops fire or one view has more than 1 result, I have the following error
Error: Call to a member function getValue() on null in Drupal\business_rules\Plugin\BusinessRulesAction\LoopThroughViewResult->execute() (line 340 of /var/aegir/platforms/--academy-002/modules/business_rules/src/Plugin/BusinessRulesAction/LoopThroughViewResult.php) #0 /var/aegir/platforms/--academy-002/modules/business_rules/src/Entity/Action.php(97): Drupal\business_rules\Plugin\BusinessRulesAction\LoopThroughViewResult->execute(Object(Drupal\business_rules\Entity\Action), Object(Drupal\business_rules\Events\BusinessRulesEvent)) #1 /var/aegir/platforms/--academy-002/modules/business_rules/src/Util/BusinessRulesProcessor.php(474): Drupal\business_rules\Entity\Action->execute(Object(Drupal\business_rules\Events\BusinessRulesEvent)) #2 /var/aegir/platforms/--academy-002/modules/business_rules/src/Util/BusinessRulesProcessor.php(316): Drupal\business_rules\Util\BusinessRulesProcessor->executeAction(Object(Drupal\business_rules\Entity\Action), Object(Drupal\business_rules\Events\BusinessRulesEvent)) #3 /var/aegir/platforms/--academy-002/modules/business_rules/src/Util/BusinessRulesProcessor.php(261): Drupal\business_rules\Util\BusinessRulesProcessor->processItems(Array, Object(Drupal\business_rules\Events\BusinessRulesEvent), 'internal_staff_...') #4 /var/aegir/platforms/--academy-002/modules/business_rules/src/Util/BusinessRulesProcessor.php(168): Drupal\business_rules\Util\BusinessRulesProcessor->processTriggeredRules(Array, Object(Drupal\business_rules\Events\BusinessRulesEvent)) #5 /var/aegir/platforms/--academy-002/modules/business_rules/src/EventSubscriber/BusinessRulesListener.php(136): Drupal\business_rules\Util\BusinessRulesProcessor->process(Object(Drupal\business_rules\Events\BusinessRulesEvent)) #6 [internal function]: Drupal\business_rules\EventSubscriber\BusinessRulesListener->process(Object(Drupal\business_rules\Events\BusinessRulesEvent), 'business_rules....', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #7 /var/aegir/platforms/--academy-002/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): call_user_func(Array, Object(Drupal\business_rules\Events\BusinessRulesEvent), 'business_rules....', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #8 /var/aegir/platforms/--academy-002/modules/business_rules/business_rules.module(90): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('business_rules....', Object(Drupal\business_rules\Events\BusinessRulesEvent)) #9 [internal function]: business_rules_entity_update(Object(Drupal\group\Entity\Group)) #10 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/Extension/ModuleHandler.php(403): call_user_func_array('business_rules_...', Array) #11 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/Entity/EntityStorageBase.php(206): Drupal\Core\Extension\ModuleHandler->invokeAll('entity_update', Array) #12 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php(773): Drupal\Core\Entity\EntityStorageBase->invokeHook('update', Object(Drupal\group\Entity\Group)) #13 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/Entity/EntityStorageBase.php(507): Drupal\Core\Entity\ContentEntityStorageBase->invokeHook('update', Object(Drupal\group\Entity\Group)) #14 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php(658): Drupal\Core\Entity\EntityStorageBase->doPostSave(Object(Drupal\group\Entity\Group), true) #15 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/Entity/EntityStorageBase.php(432): Drupal\Core\Entity\ContentEntityStorageBase->doPostSave(Object(Drupal\group\Entity\Group), true) #16 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(774): Drupal\Core\Entity\EntityStorageBase->save(Object(Drupal\group\Entity\Group)) #17 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/Entity/Entity.php(390): Drupal\Core\Entity\Sql\SqlContentEntityStorage->save(Object(Drupal\group\Entity\Group)) #18 /var/aegir/platforms/--academy-002/modules/business_rules/src/Plugin/BusinessRulesAction/SaveEntityVariableAction.php(115): Drupal\Core\Entity\Entity->save() #19 /var/aegir/platforms/--academy-002/modules/business_rules/src/Entity/Action.php(97): Drupal\business_rules\Plugin\BusinessRulesAction\SaveEntityVariableAction->execute(Object(Drupal\business_rules\Entity\Action), Object(Drupal\business_rules\Events\BusinessRulesEvent)) #20 /var/aegir/platforms/--academy-002/modules/business_rules/src/Util/BusinessRulesProcessor.php(474): Drupal\business_rules\Entity\Action->execute(Object(Drupal\business_rules\Events\BusinessRulesEvent)) #21 /var/aegir/platforms/--academy-002/modules/business_rules/src/Util/BusinessRulesProcessor.php(316): Drupal\business_rules\Util\BusinessRulesProcessor->executeAction(Object(Drupal\business_rules\Entity\Action), Object(Drupal\business_rules\Events\BusinessRulesEvent)) #22 /var/aegir/platforms/--academy-002/modules/business_rules/src/Plugin/BusinessRulesAction/LoopThroughViewResult.php(349): Drupal\business_rules\Util\BusinessRulesProcessor->processItems(Array, Object(Drupal\business_rules\Events\BusinessRulesEvent), 'loop2_elc') #23 /var/aegir/platforms/--academy-002/modules/business_rules/src/Entity/Action.php(97): Drupal\business_rules\Plugin\BusinessRulesAction\LoopThroughViewResult->execute(Object(Drupal\business_rules\Entity\Action), Object(Drupal\business_rules\Events\BusinessRulesEvent)) #24 /var/aegir/platforms/--academy-002/modules/business_rules/src/Util/BusinessRulesProcessor.php(474): Drupal\business_rules\Entity\Action->execute(Object(Drupal\business_rules\Events\BusinessRulesEvent)) #25 /var/aegir/platforms/--academy-002/modules/business_rules/src/Util/BusinessRulesProcessor.php(316): Drupal\business_rules\Util\BusinessRulesProcessor->executeAction(Object(Drupal\business_rules\Entity\Action), Object(Drupal\business_rules\Events\BusinessRulesEvent)) #26 /var/aegir/platforms/--academy-002/modules/business_rules/src/Util/BusinessRulesProcessor.php(261): Drupal\business_rules\Util\BusinessRulesProcessor->processItems(Array, Object(Drupal\business_rules\Events\BusinessRulesEvent), 'event_life_cycl...') #27 /var/aegir/platforms/--academy-002/modules/business_rules/src/Util/BusinessRulesProcessor.php(168): Drupal\business_rules\Util\BusinessRulesProcessor->processTriggeredRules(Array, Object(Drupal\business_rules\Events\BusinessRulesEvent)) #28 /var/aegir/platforms/--academy-002/modules/business_rules/src/EventSubscriber/BusinessRulesListener.php(136): Drupal\business_rules\Util\BusinessRulesProcessor->process(Object(Drupal\business_rules\Events\BusinessRulesEvent)) #29 [internal function]: Drupal\business_rules\EventSubscriber\BusinessRulesListener->process(Object(Drupal\business_rules\Events\BusinessRulesEvent), 'business_rules....', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #30 /var/aegir/platforms/--academy-002/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): call_user_func(Array, Object(Drupal\business_rules\Events\BusinessRulesEvent), 'business_rules....', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #31 /var/aegir/platforms/--academy-002/modules/business_rules/business_rules.module(478): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('business_rules....', Object(Drupal\business_rules\Events\BusinessRulesEvent)) #32 [internal function]: business_rules_cron() #33 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/Extension/ModuleHandler.php(392): call_user_func_array('business_rules_...', Array) #34 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/Cron.php(235): Drupal\Core\Extension\ModuleHandler->invoke('business_rules', 'cron') #35 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/Cron.php(133): Drupal\Core\Cron->invokeCronHandlers() #36 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/ProxyClass/Cron.php(75): Drupal\Core\Cron->run() #37 /var/aegir/platforms/--academy-002/modules/admin_toolbar/admin_toolbar_tools/src/Controller/ToolbarController.php(258): Drupal\Core\ProxyClass\Cron->run() #38 [internal function]: Drupal\admin_toolbar_tools\Controller\ToolbarController->runCron() #39 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array) #40 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/Render/Renderer.php(582): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #41 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #42 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) #43 /var/aegir/platforms/--academy-002/vendor/symfony/http-kernel/HttpKernel.php(151): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #44 /var/aegir/platforms/--academy-002/vendor/symfony/http-kernel/HttpKernel.php(68): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #45 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #46 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #47 /var/aegir/platforms/--academy-002/core/modules/page_cache/src/StackMiddleware/PageCache.php(99): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #48 /var/aegir/platforms/--academy-002/core/modules/page_cache/src/StackMiddleware/PageCache.php(78): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true) #49 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #50 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #51 /var/aegir/platforms/--academy-002/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #52 /var/aegir/platforms/--academy-002/core/lib/Drupal/Core/DrupalKernel.php(693): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #53 /var/aegir/platforms/--academy-002/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request)) #54 {main}.