메타 상자에서“admin_notices”로 오류 / 경고 메시지 전달


20

게시물 사용자 정의 필드를 업데이트하는 간단한 메타 상자가 있습니다 (을 사용하여 update_post_meta()).

사용자가 게시물을 게시 / 업데이트하고 메타 상자 필드 중 하나를 채우지 않거나 잘못된 데이터로 채운 후 다음 페이지에 오류 또는 경고 메시지를 보내려면 어떻게해야합니까?

답변:


9

이 작업은 수동으로 수행 할 수 있지만 WP는 기본적으로 설정 오류에 대해 다음과 같이 수행합니다.

  1. add_settings_error() 메시지를 작성합니다.
  2. 그때 set_transient('settings_errors', get_settings_errors(), 30);
  3. settings_errors()in admin_noticeshook to display (비 설정 화면의 경우 후크해야 함).

그것은 내가 원하는 것을하지만, 이것은 데이터베이스에 수많은 과도 전류를 채우지 않습니까?
onetrickpony

기본 프로세스 일시적인 @One Trick Pony가 명시 적으로 삭제됩니다 ( get_settings_errors()소스 참조 ). 비 설정 페이지에 논리를 적용하는 경우 직접 수행해야 할 수도 있습니다.
Rarst

2
여전히 나는 임시 오류 메시지를 db에 저장하는 것을 좋아하지 않는다. 입력 변경에 대해 사용자에게 경고하기 위해 ajax를 사용할 것입니다.
onetrickpony

개체 캐싱을 사용하면 데이터베이스 클러 터가 문제가되지 않습니다.
lkraav

15

당신은 admin_notices후크 를 사용할 수 있습니다

먼저 통지 기능을 정의하십시오.

function my_admin_notice(){
    //print the message
    echo '<div id="message">
       <p>metabox as errors on save message here!!!</p>
    </div>';
    //make sure to remove notice after its displayed so its only displayed when needed.
    remove_action('admin_notices', 'my_admin_notice');
}

필요한 경우 메타 박스 저장 기능을 추가해야합니다.

...
...
if($errors){
    add_action('admin_notices', 'my_admin_notice');
}
...
...

최신 정보

내가 약속 한 것처럼 내 메타 박스에서 오류 메시지를 추가하는 방법의 예입니다

<?php
/*
Plugin Name: one-trick-pony-notice
Plugin URI: http://en.bainternet.info
Description: Just to proof a point using admin notice form metabox
Version: 1.0
Author: Bainternet
Author URI: http://en.bainternet.info
*/

/*  admin notice */
function my_admin_notice(){
    //print the message
    global $post;
    $notice = get_option('otp_notice');
    if (empty($notice)) return '';
    foreach($notice as $pid => $m){
        if ($post->ID == $pid ){
            echo '<div id="message" class="error"><p>'.$m.'</p></div>';
            //make sure to remove notice after its displayed so its only displayed when needed.
            unset($notice[$pid]);
            update_option('otp_notice',$notice);
            break;
        }
    }
}

//hooks

add_action('add_meta_boxes', 'OT_mt_add');
add_action('save_post', 'OT_mt_save');
add_action('admin_notices', 'my_admin_notice',0);

//add metabox
function OT_mt_add() {
    add_meta_box('OT_mt_sectionid', __( 'One Trick Meta Box notice', 'textdomain' ),'OT_mt_display','post');
}

//display metabox
function OT_mt_display() {

  // Use nonce for verification
  wp_nonce_field( plugin_basename(__FILE__), 'myplugin_noncename' );

  // The actual fields for data entry
  echo '<label for="myplugin_new_field">';
       _e("leave blank to get a notice on publish or update", 'textdomain' );
  echo '</label> ';
  echo '<input type="text" id="ot_field" name="ot_field" value="" size="25" />';

}


//save metabox here is were i check the fields and if empty i display a message
function OT_mt_save( $post_id ) {

  // verify this came from the our screen and with proper authorization,
  // because save_post can be triggered at other times
    if (!isset($_POST['myplugin_noncename'])) return $post_id;
  if ( !wp_verify_nonce( $_POST['myplugin_noncename'], plugin_basename(__FILE__) ) )
      return $post_id;

  // verify if this is an auto save routine. 
  // If it is our form has not been submitted, so we dont want to do anything
  if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) 
      return $post_id;


  if(!isset($_POST['ot_field']) || empty($_POST['ot_field'])){
    //field left empty so we add a notice
    $notice = get_option('otp_notice');
    $notice[$post_id] = "You have left the field empty";
    update_option('otp_notice',$notice);
  }

}

이제이 코드를 찾을 때 post_updated_messages필터 후크를 사용 하여 동일한 방식으로 필터를 사용하는 오래된 방법을 찾았 으므로 추가 할 것입니다.

<?php
/*
Plugin Name: one-trick-pony-notice2
Plugin URI: http://en.bainternet.info
Description: just like the one above but this time using post_updated_messages hook
Version: 1.0
Author: Bainternet
Author URI: http://en.bainternet.info
*/

//hooks
add_filter('post_updated_messages','my_messages',0);
add_action('add_meta_boxes', 'OT_mt_add');
add_action('save_post', 'OT_mt_save');


//add metabox
function OT_mt_add() {
    add_meta_box('OT_mt_sectionid', __( 'One Trick Meta Box notice', 'textdomain' ),'OT_mt_display','post');
}

//display metabox
function OT_mt_display() {

  // Use nonce for verification
  wp_nonce_field( plugin_basename(__FILE__), 'myplugin_noncename' );

  // The actual fields for data entry
  echo '<label for="myplugin_new_field">';
       _e("leave blank to get a notice on publish or update", 'textdomain' );
  echo '</label> ';
  echo '<input type="text" id="ot_field" name="ot_field" value="" size="25" />';

}


//save metabox here is were i check the fields and if empty i display a message
function OT_mt_save( $post_id ) {

  // verify this came from the our screen and with proper authorization,
  // because save_post can be triggered at other times
    if (!isset($_POST['myplugin_noncename'])) return $post_id;
  if ( !wp_verify_nonce( $_POST['myplugin_noncename'], plugin_basename(__FILE__) ) )
      return $post_id;

  // verify if this is an auto save routine. 
  // If it is our form has not been submitted, so we dont want to do anything
  if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) 
      return $post_id;


  if(!isset($_POST['ot_field']) || empty($_POST['ot_field'])){
    //field left empty so we add a notice
    $notice = get_option('otp_notice');
    $notice[$post_id] = "You have left the field empty";
    update_option('otp_notice',$notice);
  }

}

//messages filter
function my_messages($m){
    global $post;
    $notice = get_option('otp_notice');
    if (empty($notice)) return $m;
    foreach($notice as $pid => $mm){
        if ($post->ID == $pid ){
            foreach ($m['post'] as $i => $message){
                $m['post'][$i] = $message.'<p>'.$mm.'</p>';

            }
            unset($notice[$pid]);
            update_option('otp_notice',$notice);
            break;
        }
    }
    return $m;
}

게시물을 저장 한 후 리디렉션되어 작업이 실행되지 않기 때문에 실제로 작동하지 않습니다.
onetrickpony

1
어디로 리디렉션? 그리고 위의 코드는 내가 사용하는 것이므로 작동한다는 것을 알고 있습니다.
Bainternet

메타 박스 저장 기능이 연결되어 save_post있습니까?
onetrickpony

1
감사합니다. 그러나 이것은 Rarst가 지적한 것과 동일합니다. 오류 메시지는 db에 저장되고 다음 페이지에서 검색 및 삭제됩니다.
onetrickpony

1
DB를 사용하는 경우 -1입니다. 올바른 사용자에게 오류가 표시 될 것이라고 보장 할 수 없습니다. 또한 불필요한 오버 헤드의 가치가 없습니다. 메타 박스 오류를 처리 할 수있는 명확한 방법이 없기 때문에이 방법은 훌륭하지만 여전히 효율적이지 않습니다. 다른 사람들을 돕기 위해 새로운 답변 으로이 작업을 수행하는 방법에 대한 예를 추가했습니다.
제레미

11

이 답변 [ 거울 ] WP 선술집에서 오토에서 실제로 워드 프레스 자체가 리디렉션 문제를 극복하기 위해 무엇을 수행하여 일시적인 문제를 해결한다. 완전히 나를 위해 일했습니다.

문제는 모든 사람에게 과도 현상이 있다는 것입니다. 동시에 여러 사용자가 작업을 수행하는 경우 오류 메시지가 잘못된 사람에게 전달 될 수 있습니다. 경쟁 조건입니다.

실제로 WordPress는 URL에 메시지 매개 변수를 전달하여이를 수행합니다. 메시지 번호는 표시 할 메시지를 나타냅니다.

redirect_post_location필터 를 연결 한 다음 add_query_arg요청에 고유 한 매개 변수를 추가 하는 데 사용하여 동일한 작업을 수행 할 수 있습니다 . 이렇게 :

add_filter('redirect_post_location','my_message');
function my_message($loc) {
 return add_query_arg( 'my_message', 123, $loc );
}

my_message=123쿼리에 추가 됩니다. 그런 다음 리디렉션 후에서에서 my_message 설정을 감지하고 $_GET그에 따라 적절한 메시지를 표시 할 수 있습니다 .


3

나는이 질문이 오래되었다는 것을 알고 있지만 문제를 해결하지 못하는 대답을 찾습니다.

Otto의 방법을 사용하여 Ana Ban의 답변 확장 이것이 오류를 처리하는 가장 좋은 방법이라는 것을 알았습니다. db에 오류를 저장할 필요가 없습니다.

내가 사용하는 Metabox 객체의 제거 버전을 포함시켰다. 이를 통해 새 오류 메시지를 쉽게 추가하고 올바른 사용자에게 오류 메시지가 표시되도록 할 수 있습니다 (db를 사용하면 보장되지 않음).

<?php
/**
 * Class MetaboxExample
 */
class MetaboxExample {

    /**
     * Defines the whitelist for allowed screens (post_types)
     */
    private $_allowedScreens = array( 'SCREENS_TO_ALLOW_METABOX' );

    /**
     * Get parameter for the error box error code
     */
    const GET_METABOX_ERROR_PARAM = 'meta-error';

    /**
     * Defines admin hooks
     */
    public function __construct() {
        add_action('add_meta_boxes', array($this, 'addMetabox'), 50);
        add_action('save_post', array($this, 'saveMetabox'), 50);
        add_action('edit_form_top', array($this, 'adminNotices')); // NOTE: admin_notices doesn't position this right on custom post type pages, haven't testes this on POST or PAGE but I don't see this an issue
    }

    /**
     * Adds the metabox to specified post types
     */
    public function addMetabox() {
        foreach ( $this->_allowedScreens as $screen ) {
            add_meta_box(
                'PLUGIN_METABOX',
                __( 'TITLE', 'text_domain' ),
                array($this, 'metaBox'),
                $screen,
                'side',
                'high'
            );
        }
    }

    /**
     * Output metabox content
     * @param $post
     */
    public function metaBox($post) {
        // Add an nonce field so we can check for it later.
        wp_nonce_field( 'metaboxnonce', 'metaboxnonce' );
        // Load meta data for this metabox
        $someValue = get_post_meta( $post->ID, 'META_KEY_IDENTIFIER', true );
        ?>
        <p>
            <label for="some-value" style="width: 120px; display: inline-block;">
                <?php _e( 'Some Field:', 'text_domain' ); ?>
            </label>
            &nbsp;
            <input type="text" id="some-value" name="some_value" value="<?php esc_attr_e( $someValue ); ?>" size="25" />
        </p>
    <?php
    }

    /**
     * Save method for the metabox
     * @param $post_id
     */
    public function saveMetabox($post_id) {
        global $wpdb;

        // Check if our nonce is set.
        if ( ! isset( $_POST['metaboxnonce'] ) ) {
            return $post_id;
        }
        // Verify that the nonce is valid.
        if ( ! wp_verify_nonce( $_POST['metaboxnonce'], 'metaboxnonce' ) ) {
            return $post_id;
        }
        // If this is an autosave, our form has not been submitted, so we don't want to do anything.
        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
            return $post_id;
        }
        // Check the user's permissions.
        if ( isset( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) {
            if ( ! current_user_can( 'edit_page', $post_id ) ) {
                return $post_id;
            }
        } else {
            if ( ! current_user_can( 'edit_post', $post_id ) ) {
                return $post_id;
            }
        }
        // Make sure that it is set.
        if ( !isset( $_POST['some_value'] ) ) {
            return $post_id;
        }
        // Sanitize user input.
        $someValue = sanitize_text_field( $_POST['some_value'] );
        // Check to make sure there is a value
        if (empty($someValue)) {
            // Add our error code
            add_filter('redirect_post_location', function($loc) {
                return add_query_arg( self::GET_METABOX_ERROR_PARAM, 1, $loc );
            });
            return $post_id; // make sure to return so we don't allow further processing
        }
        // Update the meta field in the database.
        update_post_meta( $post_id, 'META_KEY_IDENTIFIER', $someValue );
    }

    /**
     * Metabox admin notices
     */
    public function adminNotices() {
        if (isset($_GET[self::GET_METABOX_ERROR_PARAM])) {
            $screen = get_current_screen();
            // Make sure we are in the proper post type
            if (in_array($screen->post_type, $this->_allowedScreens)) {
                $errorCode = (int) $_GET[self::GET_METABOX_ERROR_PARAM];
                switch($errorCode) {
                    case 1:
                        $this->_showAdminNotice( __('Some error happened', 'text_domain') );
                        break;
                    // More error codes go here for outputting errors
                }
            }
        }
    }

    /**
     * Shows the admin notice for the metabox
     * @param $message
     * @param string $type
     */
    private function _showAdminNotice($message, $type='error') {
        ?>
        <div class="<?php esc_attr_e($type); ?> below-h2">
            <p><?php echo $message; ?></p>
        </div>
    <?php
    }

}

이 답변에 대한 유일한 문제는 PHP 5.2에서 작동하지 않는다는 것입니다. 우리 모두가 HPP 5.2를 지원해야한다고 말하지는 않지만 WordPress에 최소 요구 사항으로 PHP 5.2가 설치 될 때까지 플러그인을 배포하는 경우이를 지원해야합니다. (
Sudar

1
익명 함수를 제거하고 공용 메소드로 만들면 정상적으로 작동합니다. 귀하의 문제를 이해하지만 개인적으로 PHP의 EOL 버전 ( php.net/eol.php )을 개발하지는 않습니다 5.2 EOL은 2011 년 1 월 6 일입니다. WordPress는 EOL 버전을 지원하지 않기 위해 더 많은 노력을 기울여야하지만 또 다른 이야기입니다. 그리고 여전히 EOL 버전을 제공하는 많은 나쁜 호스팅 회사들 ...
Jeremy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.