Opened 13 years ago
Last modified 3 years ago
#18630 new feature request
Custom Comment Validation Error
Reported by: | bandonrandon | Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | minor | Version: | 3.3 |
Component: | Comments | Keywords: | has-patch |
Focuses: | Cc: |
Description
One of the things that bugs me about WordPress is not being able to customize the wp_die() function that is called on comment form validation. I have seen some people sugget core hacks, eek. I'm hoping that a hook is added to allow overriding of the default wp_die(). Maybe even a new template file wp_error.php that would be called first.
I haven't found a lot of discussion on this in trac just #11286 and #10551
Attachments (2)
Change History (14)
#2
@
13 years ago
- Cc jsherk added
Definitely something needs to be done. Even if you could at least customize the message that appears!
Anyways, here is a modified version of wp-comments-post.php for v3.2.1
It sends the error message back to the comment page you came from as GET data.
You need to place this code in whatever theme file is calling the comment form (for example single.php) but it would be nice if this was incorporated right into the comment form itself. This code will show the error message on the comment page that the error appeared on:
<?php if ($_GET['comment_error_msg']) { // Display Comment Error Message ?> <div class="comment_error_message">Comment <?php echo $_GET['comment_error_msg']; ?></div> <?php } ?>
And here is the modified part of the code for wp-comments-post.php (v3.2.1)
Changes start after line 74 where it says $comment_type = '';
:
<?php /** * Handles Comment Post to WordPress and prevents duplicate comment posting. * * @package WordPress */ if ( 'POST' != $_SERVER['REQUEST_METHOD'] ) { header('Allow: POST'); header('HTTP/1.1 405 Method Not Allowed'); header('Content-Type: text/plain'); exit; } /** Sets up the WordPress Environment. */ require( dirname(__FILE__) . '/wp-load.php' ); nocache_headers(); $comment_post_ID = isset($_POST['comment_post_ID']) ? (int) $_POST['comment_post_ID'] : 0; $post = get_post($comment_post_ID); if ( empty($post->comment_status) ) { do_action('comment_id_not_found', $comment_post_ID); exit; } // get_post_status() will get the parent status for attachments. $status = get_post_status($post); $status_obj = get_post_status_object($status); if ( !comments_open($comment_post_ID) ) { do_action('comment_closed', $comment_post_ID); wp_die( __('Sorry, comments are closed for this item.') ); } elseif ( 'trash' == $status ) { do_action('comment_on_trash', $comment_post_ID); exit; } elseif ( !$status_obj->public && !$status_obj->private ) { do_action('comment_on_draft', $comment_post_ID); exit; } elseif ( post_password_required($comment_post_ID) ) { do_action('comment_on_password_protected', $comment_post_ID); exit; } else { do_action('pre_comment_on_post', $comment_post_ID); } $comment_author = ( isset($_POST['author']) ) ? trim(strip_tags($_POST['author'])) : null; $comment_author_email = ( isset($_POST['email']) ) ? trim($_POST['email']) : null; $comment_author_url = ( isset($_POST['url']) ) ? trim($_POST['url']) : null; $comment_content = ( isset($_POST['comment']) ) ? trim($_POST['comment']) : null; // If the user is logged in $user = wp_get_current_user(); if ( $user->ID ) { if ( empty( $user->display_name ) ) $user->display_name=$user->user_login; $comment_author = $wpdb->escape($user->display_name); $comment_author_email = $wpdb->escape($user->user_email); $comment_author_url = $wpdb->escape($user->user_url); if ( current_user_can('unfiltered_html') ) { if ( wp_create_nonce('unfiltered-html-comment_' . $comment_post_ID) != $_POST['_wp_unfiltered_html_comment'] ) { kses_remove_filters(); // start with a clean slate kses_init_filters(); // set up the filters } } } else { if ( get_option('comment_registration') || 'private' == $status ) wp_die( __('Sorry, you must be logged in to post a comment.') ); } $comment_type = ''; //MOD Customize comment error message. //Need to add the following code to your comments.php file wherever you want error message to display: /* <?php if ($_GET['comment_error_msg']) { // Display Comment Error Message ?> <div class="comment_error_message">Comment <?php echo $_GET['comment_error_msg']; ?><br>Note: If your comment text disappeared, try clicking your browser BACK button.</div> <?php } ?> */ $comment_error_true = false; //MOD new code if ( '' == $comment_content ) { $comment_error_msg = __('Error: please type a comment.'); //MOD new code $comment_error_true = true; //MOD new code //wp_die( __('Error: please type a comment.') ); //original } if ( get_option('require_name_email') && !$user->ID ) { if ( 6 > strlen($comment_author_email) || '' == $comment_author ) { $comment_error_msg = __('Error: please fill the required fields (name, email).'); //MOD new code $comment_error_true = true; //MOD new code //wp_die( __('Error: please fill the required fields (name, email).') ); //original } elseif ( !is_email($comment_author_email)) { $comment_error_msg = __('Error: please enter a valid email address.'); //MOD new code $comment_error_true = true; //MOD new code //wp_die( __('Error: please enter a valid email address.') ); //original } } //MOD Original code is now in the ELSE statement if (true == $comment_error_true) { //MOD new code //Set this to false to use default wp_die page $use_comment_custom_error_page = true; //MOD new code if ($use_comment_custom_error_page) { //MOD new code $location = get_permalink() . '?comment_error_msg=' . urlencode($comment_error_msg); //MOD new code if ( !$user->ID ) { //MOD new code $comment_cookie_lifetime = apply_filters('comment_cookie_lifetime', 30000000); //MOD new code setcookie('comment_author_' . COOKIEHASH, $comment_author, time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN); //MOD new code setcookie('comment_author_email_' . COOKIEHASH, $comment_author_email, time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN); //MOD new code setcookie('comment_author_url_' . COOKIEHASH, esc_url($comment_author_url), time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN); //MOD new code //setcookie('comment_content_' . COOKIEHASH, $comment_content, time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN); //MOD new code //TO DO: Figure out how to get Comment field to re-appear and not be deleted. } //MOD new code } else { //MOD new code wp_die($comment_error_msg); //MOD new code //This performs the default comment error page action } //MOD new code } else { //MOD new code //Original unmodified code STARTS here $comment_parent = isset($_POST['comment_parent']) ? absint($_POST['comment_parent']) : 0; $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_ID'); $comment_id = wp_new_comment( $commentdata ); $comment = get_comment($comment_id); if ( !$user->ID ) { $comment_cookie_lifetime = apply_filters('comment_cookie_lifetime', 30000000); setcookie('comment_author_' . COOKIEHASH, $comment->comment_author, time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN); setcookie('comment_author_email_' . COOKIEHASH, $comment->comment_author_email, time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN); setcookie('comment_author_url_' . COOKIEHASH, esc_url($comment->comment_author_url), time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN); } $location = empty($_POST['redirect_to']) ? get_comment_link($comment_id) : $_POST['redirect_to'] . '#comment-' . $comment_id; $location = apply_filters('comment_post_redirect', $location, $comment); //Original unmodified code ENDS here } //MOD new code wp_redirect($location); exit; ?>
#5
@
10 years ago
- Keywords has-patch added; needs-patch removed
Patch uploaded that adds an optional parameter to wp_new_comment()
enabling callers to receive a WP_Error
object return rather than dying. This follows the idiom used on wp_insert_post()
and wp_set_comment_status()
for example.
The treatment for check_comment_flood_db()
uses private global variables and is rather ugly but I cannot think of a cleaner way of maintaining complete backwards compatibility with filter/action order and so on. Suggestions for better solutions are welcome!
With this fix, callers such as wp-comments-post.php
, wp-trackback.php
, the Ajax admin, XML-RPC and JSON APIs, JetPack and other plugins are now able to add comments safely and perform proper reasonable error handling.
#6
@
10 years ago
Patch updated to include slightly more robust error handling (relying function should also reset error indicator).
There's likely a ticket or five regarding this, beyond those two.
I don't think overriding the default wp_die() is what should be done here. (And theming it is currently possible.) Rather, the theme should be able to register support for error handling -- add_theme_support('comment-error-handling'). Or perhaps comment_form(), if used, would be enough. (Or require both.) Then we could send stuff back to that page.
Unfortunately we'd probably want to store content in a cookie so we can display it again, rather than lose it, but that's too much data for a cookie. So we might need to change how we POST, and send it to the post instead of wp-comments-post.php. Big changes here.