저장 후 업데이트시 관리자 통지를 추가하는 방법


16

post_save를 사용하여 post-meta에서 주소를 가져 와서 Google API에서 위도 / 경도 좌표를 검색하는 게시물 유형이 있습니다. 좌표 검색에 문제가있는 경우 사용자에게 알리는 방법이 필요합니다. admin_notices를 사용해 보았지만 아무것도 표시되지 않았습니다.

public static function update_notice() {
  echo "<div class='error'><p>Failed to retrieve coordinates. Please check key and address.<p></div>";
  remove_action('admin_notices', 'update_notice');
}

add_action('admin_notices', array('GeoPost', 'update_notice'));

잘못 사용하거나 잘못된 컨텍스트에서 사용하고 있는지 확실하지 않습니다. 분명히, 실제 코드에서 add_action은 같은 클래스의 다른 함수에 있습니다. 잘 작동합니다.


나는 당신이 쉽게 해제
Yoav Kadosh

답변:


30

이것이 작동하지 않는 이유는 save_post 조치 이후에 경로 재 지정이 발생하기 때문입니다. 원하는 것을 얻을 수있는 한 가지 방법은 쿼리 변수를 사용하여 빠른 해결 방법을 구현하는 것입니다.

다음은 시연 할 샘플 클래스입니다.

class My_Awesome_Plugin {
  public function __construct(){
   add_action( 'save_post', array( $this, 'save_post' ) );
   add_action( 'admin_notices', array( $this, 'admin_notices' ) );
  }

  public function save_post( $post_id, $post, $update ) {
   // Do you stuff here
   // ...

   // Add your query var if the coordinates are not retreive correctly.
   add_filter( 'redirect_post_location', array( $this, 'add_notice_query_var' ), 99 );
  }

  public function add_notice_query_var( $location ) {
   remove_filter( 'redirect_post_location', array( $this, 'add_notice_query_var' ), 99 );
   return add_query_arg( array( 'YOUR_QUERY_VAR' => 'ID' ), $location );
  }

  public function admin_notices() {
   if ( ! isset( $_GET['YOUR_QUERY_VAR'] ) ) {
     return;
   }
   ?>
   <div class="updated">
      <p><?php esc_html_e( 'YOUR MESSAGE', 'text-domain' ); ?></p>
   </div>
   <?php
  }
}

희망이 조금 도움이되기를 바랍니다. 건배


잘 작동합니다, 감사합니다! 그러나 첫 번째 줄에 누락 된 닫는 괄호가 있습니다 public function admin_notices()( 줄에 여분의 닫는 괄호 if ( ! isset(..)
Rhys Wynne

내가 추가 한 remove_query_arg('YOUR_QUERY_VAR');내가이 마지막 업데이트에서 설정할 수 있습니다 발견.
Tony O'Hagan

+1 좋은 답변입니다.
Mark

12

이런 종류의 시나리오를 위해 래퍼 클래스를 만들었습니다. 실제로 클래스는 알림 표시와 관련된 모든 시나리오에서 사용할 수 있습니다. PSR 표준을 사용하므로 이름 지정은 Wordpress 코드의 비정형입니다.

class AdminNotice
{
    const NOTICE_FIELD = 'my_admin_notice_message';

    public function displayAdminNotice()
    {
        $option      = get_option(self::NOTICE_FIELD);
        $message     = isset($option['message']) ? $option['message'] : false;
        $noticeLevel = ! empty($option['notice-level']) ? $option['notice-level'] : 'notice-error';

        if ($message) {
            echo "<div class='notice {$noticeLevel} is-dismissible'><p>{$message}</p></div>";
            delete_option(self::NOTICE_FIELD);
        }
    }

    public static function displayError($message)
    {
        self::updateOption($message, 'notice-error');
    }

    public static function displayWarning($message)
    {
        self::updateOption($message, 'notice-warning');
    }

    public static function displayInfo($message)
    {
        self::updateOption($message, 'notice-info');
    }

    public static function displaySuccess($message)
    {
        self::updateOption($message, 'notice-success');
    }

    protected static function updateOption($message, $noticeLevel) {
        update_option(self::NOTICE_FIELD, [
            'message' => $message,
            'notice-level' => $noticeLevel
        ]);
    }
}

용법:

add_action('admin_notices', [new AdminNotice(), 'displayAdminNotice']);
AdminNotice::displayError(__('An error occurred, check logs.'));

통지가 한 번 표시됩니다.


6

새롭고 잘 작동하는 @jonathanbardo의 답변 외에도 새 페이지가로드 된 후 쿼리 인수를 제거하려면 detach_query_args 필터를 사용할 수 있습니다 . 자신 만의 인수를 추가 할 수있는 인수 이름 배열을 얻습니다. 그런 다음 WP는 URL에서 목록의 모든 인수를 제거합니다.

public function __construct() {
    ...
    add_filter('removable_query_args', array($this, 'add_removable_arg'));
}

public function add_removable_arg($args) {
    array_push($args, 'my-query-arg');
    return $args;
}

다음과 같은 것 :

'...post.php?post=1&my-query-arg=10'

될 것입니다:

'...post.php?post=1'

1

에 기반한 단순하고 우아합니다 get_settings_errors().

function wpse152033_set_admin_notice($id, $message, $status = 'success') {
    set_transient('wpse152033' . '_' . $id, [
        'message' => $message,
        'status' => $status
    ], 30);
}

function wpse152033_get_admin_notice($id) {
    $transient = get_transient( 'wpse152033' . '_' . $id );
    if ( isset( $_GET['settings-updated'] ) && $_GET['settings-updated'] && $transient ) {
        delete_transient( 'wpse152033' . '_' . $id );
    }
    return $transient;
}

용법

사후 요청 핸들러에서 :

wpse152033_set_admin_notice(get_current_user_id(), 'Hello world', 'error');
wp_redirect(add_query_arg('settings-updated', 'true',  wp_get_referer()));

일반적으로 admin_notices후크 에서 관리자 통지를 사용하려는 경우 .

$notice = $this->get_admin_notice(get_current_user_id());
if (!empty($notice) && is_array($notice)) {
    $status = array_key_exists('status', $notice) ? $notice['status'] : 'success';
    $message = array_key_exists('message', $notice) ? $notice['message'] : '';
    print '<div class="notice notice-'.$status.' is-dismissible">'.$message.'</div>';
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.