Opened 2 years ago
Last modified 2 years ago
#57105 new enhancement
Enhance wp_handle_comment_submission() with a custom validation
Reported by: | apermo | Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | 6.2 |
Component: | Comments | Keywords: | |
Focuses: | Cc: |
Description
As of now, there is no way to do a custom validation on comments, but it is pretty much mandatory in most European countries to ask for consent when storing the data.
In 4.4.0 the filter comment_form_fields
was introduced, which allows to add a custom checkbox for that very consent.
My example below shows exactly this case, it comes with an html5 form validation via the required
attribute, by due to the missing server side component, that is a weak validation(at best).
I propose to add a counterpart filter inside of wp_handle_comment_submission()
that will allow exactly this missing server side validation.
<?php /** * Allows a custom validation. * * @since TBD * * @param null|WP_Error $custom_validation Your possible custom error. * @param array $commentdata Array of comment data to be sent to wp_insert_comment(). * @param array $comment_data The raw comment data from the function call. */ $custom_validation = apply_filters( 'comment_form_fields_validation', null, $commentdata, $comment_data ); if ( is_wp_error( $custom_validation ) ) { return $custom_validation; }
$comment_data
will pretty much contain the content of $_POST
.
(Patch with exact position see attachment)
Example use case(simplied):
<?php namespace CustomNamespace // This is already working since 4.4.0 function comment_privacy_field( array $fields ): array { $fields['privacy'] = '<input id="privacy consent" name="privacy-consent" type="checkbox" value="yes" required><label for="comment-form-privacy-consent">Yes I consent...</label></p>'; return $fields; } add_filter( 'comment_form_fields', __NAMESPACE__ . '\comment_privacy_field' ); // This is new in my proposal function comment_validation( $custom_validation, $commentdata, $comment_data ): ?\WP_Error { if ( ! isset( $comment_data['privacy-consent'] ) || empty( $comment_data['privacy-consent'] ) ) { return new \WP_Error( 'require_consent', 'You have to consent', 200 ); } return $custom_validation; } add_filter( 'comment_form_fields_validation', __NAMESPACE__ . '\comment_validation', 10, 3 );
This would allow us to add any custom validation.
Note: Any comment form error will result in a wp_die()
page, which would likely need an overhaul in this case too. But I will create a separate ticket for that topic.
Attachments (1)
Change History (4)
#1
@
2 years ago
Note:
! isset( $comment_data['privacy-consent'] ) ||
`
Can be removed from both the example above and the patch, since it is redundant.
#3
@
2 years ago
Well you are mostly right. I can somehow achieve what I tried to achieve with my suggestion with that filter.
But.
My use-case as described above enhances the set of comment fields by a custom field. Which is missing in $commentdata
.
While it is perfectly possible to access the data via the $_POST
, I guess you will have to agree, that this is a little hacky.
I see two advantages of my suggestion.
- it fires earlier, I did not expect a possible exit hidden further 2 functions deep, so that would be easier to find.
- It contains the raw comment data, which is missing inside that filter.
I see three potential approaches to make the pre_comment_approved
filter work for that use-case without the need for $_POST
- Add all custom form data to
$commentdata
. - Allow to add selected custom data to
$commentmeta
via filter. - Pass on the raw data within
$comment_data
all the way topre_comment_approved
, yet with a name like$raw_commentdata
`
My thoughts on these, after noting them down:
- All data, feels wrong, and could lead to unexpected flaws, especially if there is some attack.
- Adding the data via filter, just to use them 2 functions deeper to get the an exit, does seem like a weird compromise, in that case I would still prefer the original proposal.
- That would likely be the better compromise.
I still see the advantage of my suggestion, that it is earlier and also easier to find.
Before doing the suggestion, I searched google, stackoverflow etc. and did not find anything on how to do a custom validation for the comment feature. And since I could not find anything, I went step by step into the code and into wp_handle_comment_submission
and stopped there since I did not expect a filter/short circuit hidden that deep.
On top, it is arguable wether pre_comment_approved
does comply with the single responsibility principle. Since it serves two purposes in a kind of way, it does set the status to 1, 0, 'spam' & 'trash' and adds a short circuit, which is at least 1.5 responsibilities.
I would argue that a distinct filter for an early rejection is beneficial, but I can agree that having two filters that serve the same purpose is even worse. So unless you see anything now that I don't see, I think the best compromise. Would be 3. (pass along the new $raw_commentdata
)
If you want we can have a chat tomorrow via Slack if you need further explanation on my train of thought.
Patch for wp_handle_comment_submission to enrich it with a custom validation.