Wordpress: displaying an error message - hook admi

2019-01-28 04:03发布

问题:

I'm adding validation so if a post is in a particular category, it needs certain Custom Fields to be set.

This should be easy hooking wp_insert_post_data and admin_notices, but there is a redirect that causes the admin_notices callback to disappear.

OK - So I created a hack that uses the Session to store my error message across the redirect:

function set_post_pending($data, $postarr) {
    // If it's not valid...
        $error = "You are missing some Custom Fields.";
        $_SESSION['admin_notices'] = $error;
        $data['post_status'] = 'pending';
    return $data;
}
add_filter('wp_insert_post_data', 'set_post_pending',1,2);

function session_admin_notice() {
    if($out = $_SESSION['admin_notices']) {
        $_SESSION["admin_notices"] = "";
        echo $out;
    }
    return false;
}
add_action('admin_notices', "session_admin_notice");

The problem with this solution is that somehow the session is not available when calling session_admin_notice, which has an easy (but crazy) solution:

public static function fix_session_bs() {
    // TODO: Why do I have to do this?
    if(!session_id() && $_COOKIE["PHPSESSID"]) {
        session_start($_COOKIE["PHPSESSID"]);
    }
}
add_action('admin_init', 'fix_session_bs');

The question is: Why do I have to go through all this craziness to throw an error message?

What am I doing wrong?

回答1:

Wordpress doesn't use sessions, and if register_globals is on it will clear the $_SESSION array.

Wordpress passes it's messages along using a message integer in the URL, an array of messages is then defined in the relevant edit-[type]-form.php file in the wp-admin folder. I think you could probably append your own variable to the redirect and then get that in your admin_notices hook function. Take a look at the edit-[type]-form.php files to get an idea of how this might work.



回答2:

You can simply do like WordPress do : using transients like this :

function set_post_pending($data, $postarr) {
    // If it's not valid...
        $error = "You are missing some Custom Fields.";
        set_transient( get_current_user_id().'missingfield', $error );
        $data['post_status'] = 'pending';
    return $data;
}
add_filter('wp_insert_post_data', 'set_post_pending',1,2);

function show_admin_notice() {
    if($out = get_transient( get_current_user_id().'missingfield' ) ) {
        delete_transient( get_current_user_id().'missingfield' );
        echo "<div class=\"error\"><p>$out</p></div>";
    }
    // return false; // nothing to return here
}
add_action('admin_notices', "session_admin_notice");

ps : avoid $_SESSION in WordPress, thx



回答3:

if($out = $_SESSION['admin_notices']) { 
      $_SESSION["admin_notices"] = ""; 
      echo $out; 
}

This condition is always TRUE so it always reset your $_SESSION['admin_notices'] var