cms
cms copied to clipboard
[4.x] Allow entries to be drafted without requiring validation
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
Love this, the validation on unpublished drives us crazy sometimes.
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:
-
Introduce a second config option on the field to define publish-only rules.
validate: - 'max:3' validate_when_publishing: - required - 'min:2' -
Have some sort of special rule (thinking like the
bailorsometimesrules) that would result in rules being ignored.validate: - 'max:5' - when_publishing - required - 'min:2'So maybe the presence of
when_publishingwill 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.
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.
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.
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.
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.
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
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.
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 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));
}
}
}
}