Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue together with userforms. Page can't be published when formfield is removed from form #676

Open
guyvanbael opened this issue Feb 1, 2021 · 12 comments

Comments

@guyvanbael
Copy link
Contributor

Adding extension to editableformfield, makes the userdefinedform translatable, but...
after removing a field from the form, it's not possible to publish the form anymore. ([Emergency] Uncaught Error: Call to a member function publishSingle() on null).
Unplushing an republishing the form solves the issue, but triggers another userforms issue which deletes the recipients from the form.

@guyvanbael guyvanbael changed the title issue together with userforms page can't be published when formfield is removed from from issue together with userforms. Page can't be published when formfield is removed from form Feb 1, 2021
@tractorcow
Copy link
Collaborator

@guyvanbael can you find out where that publishSingle() is being called from? what file and line number?

@guyvanbael
Copy link
Contributor Author

guyvanbael commented Feb 4, 2021

@tractorcow Here's the stack trace. Thanks for looking into it.

SilverStripe\Versioned\ChangeSetItem->publish()
ChangeSet.php:141
SilverStripe\Versioned\ChangeSet->SilverStripe\Versioned\{closure}()
call_user_func(Closure)
Database.php:695
SilverStripe\ORM\Connect\Database->withTransaction(Closure)
ChangeSet.php:160
SilverStripe\Versioned\ChangeSet->publish(1)
RecursivePublishable.php:90
SilverStripe\Versioned\RecursivePublishable->SilverStripe\Versioned\{closure}()
DBDatetime.php:227
SilverStripe\ORM\FieldType\DBDatetime::withFixedNow(2021-01-27 09:31:02, Closure)
RecursivePublishable.php:98
SilverStripe\Versioned\RecursivePublishable->publishRecursive()
call_user_func_array(Array, Array)
Extensible.php:144
SilverStripe\View\ViewableData->SilverStripe\Core\{closure}(SilverStripe\UserForms\Model\UserDefinedForm, Array)
CustomMethods.php:61
SilverStripe\View\ViewableData->__call(publishRecursive, Array)
CMSMain.php:1801
SilverStripe\CMS\Controllers\CMSMain->save(Array, SilverStripe\Forms\Form)
CMSMain.php:2019
SilverStripe\CMS\Controllers\CMSMain->publish(Array, SilverStripe\Forms\Form, SilverStripe\Control\HTTPRequest, SilverStripe\Admin\LeftAndMainFormRequestHandler)
FormRequestHandler.php:530
SilverStripe\Forms\FormRequestHandler->invokeFormHandler(SilverStripe\CMS\Controllers\CMSPageEditController, publish, SilverStripe\Control\HTTPRequest, Array)
FormRequestHandler.php:231
SilverStripe\Forms\FormRequestHandler->httpSubmission(SilverStripe\Control\HTTPRequest)
RequestHandler.php:323
SilverStripe\Control\RequestHandler->handleAction(SilverStripe\Control\HTTPRequest, httpSubmission)
RequestHandler.php:202
SilverStripe\Control\RequestHandler->handleRequest(SilverStripe\Control\HTTPRequest)
RequestHandler.php:226
SilverStripe\Control\RequestHandler->handleRequest(SilverStripe\Control\HTTPRequest)
Controller.php:212
SilverStripe\Control\Controller->handleRequest(SilverStripe\Control\HTTPRequest)
LeftAndMain.php:766
SilverStripe\Admin\LeftAndMain->handleRequest(SilverStripe\Control\HTTPRequest)
AdminRootController.php:123
SilverStripe\Admin\AdminRootController->handleRequest(SilverStripe\Control\HTTPRequest)
Director.php:360
SilverStripe\Control\Director->SilverStripe\Control\{closure}(SilverStripe\Control\HTTPRequest)
DetectLocaleMiddleware.php:122
TractorCow\Fluent\Middleware\DetectLocaleMiddleware->TractorCow\Fluent\Middleware\{closure}(TractorCow\Fluent\State\FluentState)
FluentState.php:152
TractorCow\Fluent\State\FluentState->withState(Closure)
DetectLocaleMiddleware.php:123
TractorCow\Fluent\Middleware\DetectLocaleMiddleware->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
InitStateMiddleware.php:51
TractorCow\Fluent\Middleware\InitStateMiddleware->TractorCow\Fluent\Middleware\{closure}(TractorCow\Fluent\State\FluentState)
FluentState.php:152
TractorCow\Fluent\State\FluentState->withState(Closure)
InitStateMiddleware.php:52
TractorCow\Fluent\Middleware\InitStateMiddleware->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
VersionedHTTPMiddleware.php:41
SilverStripe\Versioned\VersionedHTTPMiddleware->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
ConfirmationMiddleware.php:254
SilverStripe\Control\Middleware\ConfirmationMiddleware->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
ConfirmationMiddleware.php:254
SilverStripe\Control\Middleware\ConfirmationMiddleware->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
PasswordExpirationMiddleware.php:84
SilverStripe\Security\PasswordExpirationMiddleware->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
BasicAuthMiddleware.php:68
SilverStripe\Security\BasicAuthMiddleware->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
AuthenticationMiddleware.php:61
SilverStripe\Security\AuthenticationMiddleware->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
ExecMetricMiddleware.php:20
SilverStripe\Control\Middleware\ExecMetricMiddleware->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
TrailingSlashRedirector.php:102
Axllent\TrailingSlash\Middleware\TrailingSlashRedirector->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
CanonicalURLMiddleware.php:190
SilverStripe\Control\Middleware\CanonicalURLMiddleware->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
HTTPCacheControlMiddleware.php:42
SilverStripe\Control\Middleware\HTTPCacheControlMiddleware->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
ChangeDetectionMiddleware.php:28
SilverStripe\Control\Middleware\ChangeDetectionMiddleware->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
FlushMiddleware.php:27
SilverStripe\Control\Middleware\FlushMiddleware->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
RequestProcessor.php:66
SilverStripe\Control\RequestProcessor->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
SessionMiddleware.php:20
SilverStripe\Control\Middleware\SessionMiddleware->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
AllowedHostsMiddleware.php:60
SilverStripe\Control\Middleware\AllowedHostsMiddleware->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
TrustedProxyMiddleware.php:176
SilverStripe\Control\Middleware\TrustedProxyMiddleware->process(SilverStripe\Control\HTTPRequest, Closure)
HTTPMiddlewareAware.php:62
SilverStripe\Control\Director->SilverStripe\Control\Middleware\{closure}(SilverStripe\Control\HTTPRequest)
HTTPMiddlewareAware.php:65
SilverStripe\Control\Director->callMiddleware(SilverStripe\Control\HTTPRequest, Closure)
Director.php:369
SilverStripe\Control\Director->handleRequest(SilverStripe\Control\HTTPRequest)
HTTPApplication.php:117
SilverStripe\Control\HTTPApplication::SilverStripe\Control\{closure}(SilverStripe\Control\HTTPRequest)
call_user_func(Closure, SilverStripe\Control\HTTPRequest)
HTTPApplication.php:136
SilverStripe\Control\HTTPApplication->SilverStripe\Control\{closure}(SilverStripe\Control\HTTPRequest)
HTTPMiddlewareAware.php:65
SilverStripe\Control\HTTPApplication->callMiddleware(SilverStripe\Control\HTTPRequest, Closure)
HTTPApplication.php:137
SilverStripe\Control\HTTPApplication->execute(SilverStripe\Control\HTTPRequest, Closure, )
HTTPApplication.php:118
SilverStripe\Control\HTTPApplication->handle(SilverStripe\Control\HTTPRequest)
index.php:24

@guyvanbael
Copy link
Contributor Author

@tractorcow I also found this in my debug log file
Uncaught Exception Error: "Call to a member function publishSingle() on null" at /Volumes/guySSD/webroot/vekmo2020/vendor/silverstripe/versioned/src/ChangeSetItem.php line 307 {"exception":"[object] (Error(code: 0): Call to a member function publishSingle() on null at /Volumes/guySSD/webroot/vekmo2020/vendor/silverstripe/versioned/src/ChangeSetItem.php:307)"} []

@tractorcow
Copy link
Collaborator

tractorcow commented Feb 4, 2021

Yeah it's this

                // Non-recursive publish
                $object = $this->getObjectInStage(Versioned::DRAFT);
                $object->publishSingle();

It would seem that the record is not being loaded properly in draft mode; If we are in the CMS, fluent should not prevent items being queried.

UNLESS you are using FluentIsolatedExtension. does your project use this?

@guyvanbael
Copy link
Contributor Author

guyvanbael commented Feb 4, 2021 via email

@guyvanbael
Copy link
Contributor Author

@tractorcow is there something i can do as a workaround untill this issue is adressed?

@tractorcow
Copy link
Collaborator

Still trying to figure out what the issue is sorry =(

@guyvanbael
Copy link
Contributor Author

guyvanbael commented Apr 2, 2021

@tractorcow adding a check for null object in ChangeSetItem.php right before $object->publishSingle(); (like if($object == null) break;) fixes the issue and probably isn't a bad idea either, but maybe fluent should implement a check before it reaches silverstripe\versioned\ChangeSetItem.php

@adrexia
Copy link

adrexia commented Aug 10, 2021

We are also hitting this. I guess everyone with both fluent and userforms will at some point. Here's the issue on the userforms module, since I haven't seen it linked here yet and its got some good context: silverstripe/silverstripe-userforms#996

What is supposed to happen in fluent when an object is deleted in one locale? Does it populate that change to other locales? This might be obvious, but I think it's trying to publish a deleted record.

Related: Userforms uses delete, rather than the archive action. When I replace with this it works as expected (and allows publish).

$config->addComponent(new GridFieldArchiveAction(), GridFieldDeleteAction::class);

Is there a reason we know of why Userforms is using a delete action on a versioned record? Would it be worth trying to get that replaced in the Userforms module?

@tractorcow
Copy link
Collaborator

What is supposed to happen in fluent when an object is deleted in one locale? Does it populate that change to other locales? This might be obvious, but I think it's trying to publish a deleted record.

It's supposed to delete only that locale, and from the root record on the LAST locale deleted.

Check out the deletion policy API that goes into more detail.

Simple fix, you could try adding frontend_publish_required to false for the editable form field class (via yml).

We had to do this for siteconfig.

SilverStripe\SiteConfig\SiteConfig:
  frontend_publish_required: false

This will , probably, prevent ChangeSet from loading "null" for the deleted field.

It's not fully deleted, it exists in the db, but not for the current locale. That flag still filters it out though, so it's "soft deleted" in the current locale.

@adrexia
Copy link

adrexia commented Aug 10, 2021

@tractorcow Unfortunately it doesn't help in this case.

This:

SilverStripe\UserForms\Model\EditableFormField:
  frontend_publish_required: false

will still result in the same error.

@RoyalPulp
Copy link
Contributor

Hello !!
This same error has just occurred to a now project with UserForms and Fluent!
How do I solve this?
(workaround -> just delete a DB record?)
Thanks for any help!!
Hendrik

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants