Change Patch::originalEntity variable type along to Drupal 11.2

Created on 26 May 2025, about 1 month ago

Problem/Motivation

Since version 11.2 Drupal EntityBase class has variable $originalEntity defined as ?EntityInterface. We define this variable as not nullable EntityInterface that causes fatal error.

Steps to reproduce

To reproduce the error upgrade the core to version 11.2 - site will lay down in fatal error.

Proposed resolution

As we can't just remove this variable in favor of parent one to keep back compatibility with previous core versions, we can add nullable type «?EntityInterface» .

Remaining tasks

None

User interface changes

None

API changes

None

Data model changes

None

🐛 Bug report
Status

Active

Version

2.1

Component

Code

Created by

🇷🇺Russia Alezu

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @Alezu
  • I use the module with patch in #3428348. There's no problem.

    I tested MR!2 with Drupal 11.2.0-rc2.

    Here's the log

    The website encountered an unexpected error. Try again later.
    
    Error: Typed property Drupal\change_requests\Entity\Patch::$originalEntity must not be accessed before initialization in Drupal\Core\Entity\EntityBase->getOriginal() (line 697 of core/lib/Drupal/Core/Entity/EntityBase.php).
    

    Details:

    Drupal\Core\Field\Plugin\Field\FieldType\ChangedItem->preSave() (Line: 233)
    Drupal\Core\Field\FieldItemList->delegateMethod() (Line: 191)
    Drupal\Core\Field\FieldItemList->preSave() (Line: 953)
    Drupal\Core\Entity\ContentEntityStorageBase->invokeFieldMethod() (Line: 903)
    Drupal\Core\Entity\ContentEntityStorageBase->invokeHook() (Line: 530)
    Drupal\Core\Entity\EntityStorageBase->doPreSave() (Line: 760)
    Drupal\Core\Entity\ContentEntityStorageBase->doPreSave() (Line: 484)
    Drupal\Core\Entity\EntityStorageBase->save() (Line: 804)
    Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (Line: 370)
    Drupal\Core\Entity\EntityBase->save() (Line: 125)
    Drupal\change_requests\NodeObserver->update() (Line: 112)
    Drupal\changed_fields\EntitySubject->notify() (Line: 106)
    change_requests_node_presave()
    call_user_func_array() (Line: 402)
    Drupal\Core\Extension\ModuleHandler->Drupal\Core\Extension\{closure}() (Line: 355)
    Drupal\Core\Extension\ModuleHandler->invokeAllWith() (Line: 401)
    Drupal\Core\Extension\ModuleHandler->invokeAll() (Line: 215)
    Drupal\Core\Entity\EntityStorageBase->invokeHook() (Line: 915)
    Drupal\Core\Entity\ContentEntityStorageBase->invokeHook() (Line: 530)
    Drupal\Core\Entity\EntityStorageBase->doPreSave() (Line: 760)
    Drupal\Core\Entity\ContentEntityStorageBase->doPreSave() (Line: 484)
    Drupal\Core\Entity\EntityStorageBase->save() (Line: 804)
    Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (Line: 370)
    Drupal\Core\Entity\EntityBase->save() (Line: 281)
    Drupal\node\Form\NodeForm->save()
    call_user_func_array() (Line: 105)
    Drupal\Core\Form\FormSubmitter->executeSubmitHandlers() (Line: 43)
    Drupal\Core\Form\FormSubmitter->doSubmitForm() (Line: 589)
    Drupal\Core\Form\FormBuilder->processForm() (Line: 321)
    Drupal\Core\Form\FormBuilder->buildForm() (Line: 73)
    Drupal\Core\Controller\FormController->getContentResult()
    call_user_func_array() (Line: 123)
    Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 622)
    Drupal\Core\Render\Renderer->executeInRenderContext() (Line: 121)
    Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext() (Line: 97)
    Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 183)
    Symfony\Component\HttpKernel\HttpKernel->handleRaw() (Line: 76)
    Symfony\Component\HttpKernel\HttpKernel->handle() (Line: 53)
    Drupal\Core\StackMiddleware\Session->handle() (Line: 48)
    Drupal\Core\StackMiddleware\KernelPreHandle->handle() (Line: 28)
    Drupal\Core\StackMiddleware\ContentLength->handle() (Line: 32)
    Drupal\big_pipe\StackMiddleware\ContentLength->handle() (Line: 116)
    Drupal\page_cache\StackMiddleware\PageCache->pass() (Line: 90)
    Drupal\page_cache\StackMiddleware\PageCache->handle() (Line: 57)
    Drupal\advban\AdvbanMiddleware->handle() (Line: 50)
    Drupal\ban\BanMiddleware->handle() (Line: 48)
    Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() (Line: 51)
    Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() (Line: 53)
    Drupal\Core\StackMiddleware\AjaxPageState->handle() (Line: 51)
    Drupal\Core\StackMiddleware\StackedHttpKernel->handle() (Line: 715)
    Drupal\Core\DrupalKernel->handle() (Line: 19)
    
  • 🇷🇺Russia Alezu

    Hi @pearls,

    I do not have a project with this module right now but the previous change should fix it. Please test.

  • Hi @Alezu,
    Sorry for late test. I tested with Drupal 11.1.2

    Now, A Patch Entity (Change request) can be created but cannot be applied or any other action taken.

    The website encountered an unexpected error. Try again later.
    
    TypeError: Drupal\Core\Entity\EntityBase::getOriginal(): Return value must be of type ?Drupal\change_requests\Entity\Patch, Drupal\node\Entity\Node returned in Drupal\Core\Entity\EntityBase->getOriginal() (line 697 of core/lib/Drupal/Core/Entity/EntityBase.php).
    

    Details

    Drupal\Core\Entity\ContentEntityStorageBase->doPreSave() (Line: 484)
    Drupal\Core\Entity\EntityStorageBase->save() (Line: 804)
    Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (Line: 370)
    Drupal\Core\Entity\EntityBase->save() (Line: 182)
    Drupal\change_requests\Form\PatchApplyForm->submitForm()
    call_user_func_array() (Line: 105)
    Drupal\Core\Form\FormSubmitter->executeSubmitHandlers() (Line: 43)
    Drupal\Core\Form\FormSubmitter->doSubmitForm() (Line: 589)
    Drupal\Core\Form\FormBuilder->processForm() (Line: 321)
    Drupal\Core\Form\FormBuilder->buildForm() (Line: 73)
    Drupal\Core\Controller\FormController->getContentResult()
    call_user_func_array() (Line: 123)
    Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 622)
    Drupal\Core\Render\Renderer->executeInRenderContext() (Line: 121)
    Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext() (Line: 97)
    Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 183)
    Symfony\Component\HttpKernel\HttpKernel->handleRaw() (Line: 76)
    Symfony\Component\HttpKernel\HttpKernel->handle() (Line: 53)
    Drupal\Core\StackMiddleware\Session->handle() (Line: 48)
    Drupal\Core\StackMiddleware\KernelPreHandle->handle() (Line: 28)
    Drupal\Core\StackMiddleware\ContentLength->handle() (Line: 32)
    Drupal\big_pipe\StackMiddleware\ContentLength->handle() (Line: 116)
    Drupal\page_cache\StackMiddleware\PageCache->pass() (Line: 90)
    Drupal\page_cache\StackMiddleware\PageCache->handle() (Line: 57)
    Drupal\advban\AdvbanMiddleware->handle() (Line: 50)
    Drupal\ban\BanMiddleware->handle() (Line: 48)
    Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() (Line: 51)
    Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() (Line: 53)
    Drupal\Core\StackMiddleware\AjaxPageState->handle() (Line: 51)
    Drupal\Core\StackMiddleware\StackedHttpKernel->handle() (Line: 715)
    Drupal\Core\DrupalKernel->handle() (Line: 19)
    
  • 🇷🇺Russia Alezu

    The problem is we store in Patch::$original its variable the original node we request a patch ti, not the unchanged patch itself. But currently the parent function EntityInterface::getOriginal() returns null|static so we must return a Patch instance.

    I made a hotfix above to make the module work but the way I used (return the current Patch entity as the original one) is probably not proper as the Patch entity seems to be revisionable. Please review if we can fix it in this way or find a better solution.

  • From MR2 side, it seems to work without any issues.
    Tested with Drupal Version 11.2.2

Production build 0.71.5 2024