Node: this belongs in the workflows component which hasn't been created yet.

Problem/Motivation

When creating a new state, the machine name causes an exception in Workflow::addState before the machine name element has a chance to validate it.

Proposed resolution

Find a way for the normal machine name validation to take place before trying to build the workflow entity into a valid state.

Remaining tasks

Validate and patch.

User interface changes

API changes

Data model changes

Comments

Sam152 created an issue. See original summary.

sam152’s picture

Status: Active » Needs review
StatusFileSize
new1.14 KB

Quick test case for this bug.

sam152’s picture

Issue summary: View changes
sam152’s picture

Issue tags: +workflows.module

Status: Needs review » Needs work

The last submitted patch, 2: 2842193-machine-name-test-case-2.patch, failed testing.

sam152’s picture

Status: Needs work » Needs review
StatusFileSize
new1.89 KB

And the fix. The entity isn't required during validation, so this works.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

scott_euser’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +SprintWeekend2017, +london_2017_january

I have taken a look at your patch, it took a bit to figure out how to reproduce the error but once I did I can confirm your patch solves it.

Steps followed:

  1. Go to admin > config > workflows
  2. Edit the Editorial workflow
  3. Add a new state
  4. Type a new label
  5. Edit the machine name that is generated and add special characters to invalidate

Saving before patch, white screen with fatal error as you described.
Saving after patch, drupal form error message as is desirable.

Nice work!

tstoeckler’s picture

Version: 8.4.x-dev » 8.3.x-dev
Status: Reviewed & tested by the community » Needs review
StatusFileSize
new1.02 KB

This kind of an override is very problematic as it can lead to unexpected behavior when calling buildEntity() in other places.

I am providing an alternate patch that simply duplicates the validation in copyFormValuesToEntity().

If you do not like duplication and you see the fact that unvalidated form values are put into entity objects as problematic, see you in #2813073: Don't update $this->entity in EntityForm::afterBuild(). For the scope of this issue, I think this is all we can do.

tstoeckler’s picture

StatusFileSize
new2.16 KB

Oops, should have included the test in the patch as well.

The last submitted patch, 9: 2842193-9-alternate.patch, failed testing.

berdir’s picture

Version: 8.3.x-dev » 8.4.x-dev
Status: Needs review » Reviewed & tested by the community

Hm, this (the previous patch at least, this is a crosspost with @tstoeckler) is problematic, because if we don't build the entity then this prevents us from ever relying on using the entity validation/constraint API for config entities as well.

IMHO a better fix would be to not let the workflow entity explode like this. This doesn't happen with any other config entity AFAIK..

berdir’s picture

Version: 8.4.x-dev » 8.3.x-dev
Status: Reviewed & tested by the community » Needs review

As I said, crosspost.

sam152’s picture

Can the entity validation/constraint API be used for config entities as well?

scott_euser’s picture

Here is a different approach, it appears to save and work as expected but fatal error is avoided by waiting until form state validation is completed first (perhaps has something to do with the 'This is fired twice', but I couldn't see why it is fired twice).

hchonov’s picture

Well currently it is not right that the entity is built twice on submission as it might happen that we save an entity that is not validated because of the entity builders. There is an issue to avoid this for content entities, but the approach might be used for config entities as well - #2833682: In submit use the entity built during the validation instead of building it again - for performance and consistency ensuring we are saving the entity that has been validated.

Status: Needs review » Needs work

The last submitted patch, 15: drupal-core-invalid-machine-name-2842193-15-D8.patch, failed testing.

hchonov’s picture

Status: Needs work » Needs review
StatusFileSize
new1.71 KB

Status: Needs review » Needs work

The last submitted patch, 18: 2842193-18-save-entity-from-after-build.patch, failed testing.

scott_euser’s picture

Status: Needs work » Needs review

I am not sure if there is anything relying on that or further consequences of that if any, but hopefully someone who knows the ins and outs of workflow can review that. Otherwise my patch in #15 should solve the issue without knock-on effects.

Perhaps preventing double build can be addressed in a separate issue so solving this one isn't held up?

timmillwood’s picture

I agree with @hchonov that it is not right that the entity is built twice on submission, but I don't think that is for this issue. To fix the issue in hand I like the solution in #15, but would also be happy if #10 were committed.

I don't think we need to fix all the underlying issues here, just prevent the user from seeing a WSOD.

hchonov’s picture

Well if we fix all the issues by a way where the entity builders are checking that they've already run and that the result from the previous execution is already there then we are only curing the symptoms but not the problem itself and we have to start at some point when there is an issue really showing the problem...

scott_euser’s picture

Resubmitting #15 so it's the latest for review to at least fix the WSOD.

scott_euser’s picture

Would help if I attached it...

tstoeckler’s picture

Mhh, I guess we need a maintainer's input about this. With the three patches and @Berdir's comment we have 4 different directions to go in...

scott_euser’s picture

Ah I thought from your comment in #21 I'd resubmit to keep things moving, sorry!

tstoeckler’s picture

Discussed this with @timmillwood and @Berdir in IRC (see attached log). We (at least Berdir and I) agreed that while my patch is ugly in that it duplicates the validation logic it is the best we can do given the current state of form validation vs. entity validation vs. form building etc.

Re-uploading my patch.

scott_euser’s picture

Sounds good. I don't know my regular expressions very well; do the @ signs before and after that machine name uses in its validation make a difference? If so, perhaps we should match that?
!preg_match('@[^a-z0-9_]+@', $values['id'])

sam152’s picture

Version: 8.3.x-dev » 8.4.x-dev
sam152’s picture

Status: Needs review » Reviewed & tested by the community
tstoeckler’s picture

Re #28, no it really doesn't make a difference. The version I chose is the one used in Workflow::addState() so I think it should be fine.

wim leers’s picture

Status: Reviewed & tested by the community » Needs review

Nit: Can we have a failing test-only patch? That'll make it easier for committers.

sam152’s picture

StatusFileSize
new1.14 KB
new2.16 KB

The last submitted patch, 33: 2842193-TEST-ONLY-33.patch, failed testing. View results

sam152’s picture

Status: Needs review » Reviewed & tested by the community
timmillwood’s picture

Issue tags: +Workflow Initiative

+1 to RTBC

larowlan’s picture

+++ b/core/modules/workflows/src/Form/WorkflowStateAddForm.php
@@ -82,9 +82,9 @@ protected function copyFormValuesToEntity(EntityInterface $entity, array $form,
-    // This is fired twice so we have to check that the entity does not already
-    // have the state.
-    if (!$entity->hasState($values['id'])) {
+    // Replicate the validation that Workflow::addState() does internally as the
+    // form values have not been validated at this point.
+    if (!$entity->hasState($values['id']) && !preg_match('/[^a-z0-9_]+/', $values['id'])) {

Should we link this issue to #2164373: [META] Untie config validation from form validation — enables validatable Recipes, decoupled admin UIs … because we're adding validation that only runs in a form? I.e. to move to validation constraints once they're supported for config entities?

Given what we have to work with, I think this is the best we can do.

larowlan’s picture

Updating issue credits

larowlan’s picture

Status: Reviewed & tested by the community » Fixed

Reviewed this.

We have buy in from the maintainer (@timmillwood) and entity subsystem maintainers (@Berdir, @tstoeckler) and we have a follow-up for cleaning this up - #2845517: Enforce allowed characters of machine names in config entities.

This fixes the fatal/WSOD seen in the UI.

Committed 6d68ffd and pushed to 8.4.x. Thanks!

  • larowlan committed 6d68ffd on 8.4.x
    Issue #2842193 by Sam152, tstoeckler, scott_euser, hchonov: Exception in...
timmillwood’s picture

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.