Problem/Motivation
Our site has to (unfortunately) run with a base path in front of all URLs. Think http://example.com/web/node/1 or http://example.com/name-of-app/node/1.
Drupal 8 and 9 support this, but not perfectly everywhere. There is a specific issue with BusinessRulesUtil code that currently uses unaltered $_SERVER values to populate fake requests to to build new URL objects.
Steps to reproduce
- Configure your site to have a base path, possibly /web/.
- Use the "Add Action" AJAX link when creating a new rule.
You will get no response. If you disable JavasScript, you get an error like this:
The website encountered an unexpected error. Please try again later.
Error: Call to a member function toString() on null in Drupal\business_rules\Controller\BusinessRulesItemsController->itemsTable() (line 228 of modules/contrib/business_rules/src/Controller/BusinessRulesItemsController.php).
Drupal\business_rules\Controller\BusinessRulesItemsController->itemsTable('test', 'action', 'nojs')
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 573)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 158)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 80)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 706)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
This is a problem for two helper methods: BusinessRulesUtil::getCurrentUri and BusinessRulesUtil::getPreviousUri
Proposed resolution
I don't necessarily know if the right solution is to continue to rely on the actual Request. I'm not familiar enough with the module's code to understand how these two helper methods are used.
The key is getting \Drupal::request()->getBasePath() and removing that value from $current and $previousUrl strings.
I have seen a few open issues that may be connected to this. It depends on if those issue submitter also have to have a base path on all of their URLs.
| Comment | File | Size | Author |
|---|---|---|---|
| #2 | 3211671-support_base_paths.patch | 1.4 KB | jonmcl |
Comments
Comment #2
jonmcl commentedI'm not entirely sure why this works with ::getPreviousUri, because it technically uses an invalid URL if you have a base path, but I don't really understand how the $fake_request is working in general :)
Comment #3
jonmcl commentedComment #4
kris77 commentedThank you so much @JonMcL, with your patch in #2 now its possible to add action or condition in Rules form, with /web or without /web path.
To solve the problem of adding an action in the conditions form, you have to do this: https://www.drupal.org/project/business_rules/issues/3200711#comment-140....
Comment #5
coaston commentedTnkx, worked for me!