Problem/Motivation
The state machine module route subscriber does not define allowed methods on the state transition form.
It's creating some issues with the router matching system, for example when using REST module to PATCH a commerce order shipment.
In the Router class, there are these lines of codes :
$collection = $this->applyRouteFilters($collection, $request);
$collection = $this->applyFitOrder($collection);
if ($ret = $this->matchCollection(rawurldecode($this->currentPath->getPath($request)), $collection)) {
return $this->applyRouteEnhancers($ret, $request);
}
Without declaring the allowed methods on the "state-transition-form" route, it would get a match and cause an 500 error on our project.
Steps to reproduce
- Enable the REST module & Commerce & Commerce shipping.
- Enable PATCH on the commerce shipment endpoint : /admin/commerce/orders/{commerce_order}/shipments/{commerce_shipment}: PATCH
- Use curl to experiment with the endpoint :
curl -X PATCH --location "https://localhost/admin/commerce/orders/XXXX/shipments/XXXX?_format=json" \
-H "authorization: Bearer XXXX" \
-H "Content-Type: application/json" \
-d '{
"type": "default",
"shipment_id": [
{
"value": XXXX
}
],
}'
- Receive an error 500 :
The website encountered an unexpected error. Please try again later.<br/><em
class="placeholder">Error</em>: Call to undefined method Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem::getTransitions() in
<em class="placeholder">Drupal\state_machine\Access\StateTransitionAccessCheck->access()</em> (line <em
class="placeholder">51</em> of <em class="placeholder">modules/contrib/state_machine/src/Access/StateTransitionAccessCheck.php</em>).
<pre class="backtrace">Drupal\state_machine\Access\StateTransitionAccessCheck->access(Object, Object)
call_user_func_array(Array, Array) (Line: 160)
Drupal\Core\Access\AccessManager->performCheck('access_check.state_transition', Object) (Line: 136)
Drupal\Core\Access\AccessManager->check(Object, Object, Object, 1) (Line: 113)
Drupal\Core\Access\AccessManager->checkRequest(Object, Object, 1) (Line: 110)
Drupal\Core\Routing\AccessAwareRouter->checkAccess(Object) (Line: 95)
Drupal\Core\Routing\AccessAwareRouter->matchRequest(Object) (Line: 151)
Drupal\Core\Routing\AccessAwareRouter->match('/admin/commerce/orders/6450/shipments/1408') (Line: 139)
Drupal\user\Plugin\LanguageNegotiation\LanguageNegotiationUserAdmin->isAdminPath(Object) (Line: 105)
Drupal\user\Plugin\LanguageNegotiation\LanguageNegotiationUserAdmin->getLangcode(Object) (Line: 197)
Drupal\language\LanguageNegotiator->negotiateLanguage('language_interface', 'language-user-admin') (Line: 137)
Drupal\language\LanguageNegotiator->initializeType('language_interface') (Line: 218)
Drupal\language\ConfigurableLanguageManager->getCurrentLanguage() (Line: 92)
Drupal\language\EventSubscriber\LanguageRequestSubscriber->setLanguageOverrides() (Line: 74)
Drupal\language\EventSubscriber\LanguageRequestSubscriber->onKernelRequestLanguage(Object, 'kernel.request', Object)
call_user_func(Array, Object, 'kernel.request', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.request') (Line: 145)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 51)
Drupal\ld_api\RequestLoggerMiddleware->handle(Object, 1, 1) (Line: 48)
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: 50)
Drupal\ban\BanMiddleware->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 36)
Drupal\ld_api\ContentTypeMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 718)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Proposed resolution
Define the allowed methods GET and POST on the state machine form routes.