cms icon indicating copy to clipboard operation
cms copied to clipboard

[4.x] Allow entries to be drafted without requiring validation

Open ryanmitchell opened this issue 9 months ago • 1 comments

This PR adds a new opt-in collection configuration option draft_without_validation which allows unpublished entries to be created without applying any validation rules.

Validation rules continue to be applied when the entry is published, but while its in an unpublished state they will not be run.

This can be useful if you are populating content but haven't yet been supplied all the information, or you haven't yet received assets.

I've left this PR as a draft just to get your thoughts, if it's a direction you like I will work on test coverage.

There seems to be a similar idea here: https://github.com/statamic/ideas/issues/765

ryanmitchell avatar Nov 02 '23 21:11 ryanmitchell

Love this, the validation on unpublished drives us crazy sometimes.

edalzell avatar Nov 03 '23 16:11 edalzell

Thank you for this PR. I absolutely agree that there should be a way to save incomplete data.

However I'm not sure that completely bypassing validation is the right move.

I think what may be a more suitable solution is to have a way to define rules that should only be applied when publishing. I've two solutions that come to mind:

  1. Introduce a second config option on the field to define publish-only rules.

    CleanShot 2024-03-12 at 21 22 03

    validate:
      - 'max:3'
    validate_when_publishing:
      - required
      - 'min:2'
    
  2. Have some sort of special rule (thinking like the bail or sometimes rules) that would result in rules being ignored.

    CleanShot 2024-03-12 at 21 23 13

    validate:
      - 'max:5'
      - when_publishing
      - required
      - 'min:2'
    

    So maybe the presence of when_publishing will remove all the subsequent rules when editing a draft.

The second option is probably more feasible as we wouldn't need to pass two arrays all over the place. Also having this "publish only" option for non-entry blueprints becomes weird.

jasonvarga avatar Mar 13 '24 01:03 jasonvarga

However I'm not sure that completely bypassing validation is the right move.

@jasonvarga why do you say that? When our clients start new entries they rarely want any validation at all, they only need to start getting data in, regardless of its correctness.

edalzell avatar Mar 13 '24 03:03 edalzell

We still need some data integrity. When you save an entry, even a draft, stuff happens like fieldtype processing, events etc. The data should still be in the expected format. Fieldtypes may provide their own validation rules for this.

If you were using a traditional DB and you didn't have validation, you might end up putting invalid types into a column and you'd get query errors. There could also be the possibility of a security issue. (I don't know what yet, but I don't want to open it up as a possibility.)

I'd wager that most of the time, in a draft you only really care about leaving out required fields. You don't want to bypass all the validation rules.

This can be useful if you are populating content but haven't yet been supplied all the information, or you haven't yet received assets.

Stupid example but an integer field should still check that the submitted value is an integer. You shouldn't be able to submit a string just because it's a draft.

jasonvarga avatar Mar 13 '24 14:03 jasonvarga

I'd wager that most of the time, in a draft you only really care about leaving out required fields. You don't want to bypass all the validation rules.

Agreed, and that might be the best implementation actually, if draft then replace the required with sometimes. Nothing new (in the blueprint) needed.

edalzell avatar Mar 13 '24 16:03 edalzell

That's not how sometimes works. The sometimes rule prevents validation running on that field if it's missing from the request. When saving a draft the field will still be submitted.

I don't think just tweaking the required rule logic will work either though, because you could have some other rules that you might not care about in a draft, like min.

jasonvarga avatar Mar 13 '24 17:03 jasonvarga

OK, I'm back to "please remove all rules when in draft". I'd rather start there (cuz that's the easiest), then put things back if folks need them

edalzell avatar Mar 13 '24 18:03 edalzell

Respectfully, no. https://github.com/statamic/cms/pull/8919#issuecomment-1994513035

If you really want, you can try this in the mean time:

Use the container to rebind the controller. In your update method, check if it's a draft, then rebind the validator to one that does nothing.

jasonvarga avatar Mar 13 '24 22:03 jasonvarga

Somehow I missed this being closed and all this conversation, sorry for delayed replies.

I do think a good first step would be to allow required rules to be ignored when in draft mode - that would get around most of the issues. You still would have other validations, but they would only kick in if you choose to enter data in those fields, which is optional.

Would you be open to a new PR with that approach?

ryanmitchell avatar Apr 18 '24 11:04 ryanmitchell

@ryanmitchell I created a custom validator which handles the required rule nicely. The only issue I encountered for this one is with revisions, as revisions are being "promoted" and bypasses the validation.

<?php

namespace App\Rules;

use Closure;
use Illuminate\Support\Facades\Validator;
use Illuminate\Contracts\Validation\ValidationRule;

class RequiredOnPublish implements ValidationRule
{
    /**
     * Run the validation rule.
     *
     * @param  \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString  $fail
     */
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        $published = request()->input('published');
        if ($published) {
            $validator = Validator::make(request()->all(), [
                $attribute => ['required'],
            ]);
            if ($validator->fails()) {
                $fail($validator->getMessageBag()->first($attribute));
            }
        }
    }
}

SylvesterDamgaard avatar Apr 19 '24 10:04 SylvesterDamgaard