Cách thêm thông báo quản trị khi lưu bài / cập nhật


16

Tôi có một loại bài đăng sử dụng post_save để lấy địa chỉ từ post-meta và lấy tọa độ lat / lng từ Google API. Tôi cần một cách thông báo cho người dùng nếu có vấn đề với việc truy xuất các tọa độ. Tôi đã thử sử dụng admin_notices, nhưng không có gì hiển thị:

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'));

Tôi không chắc chắn nếu tôi sử dụng nó không đúng hoặc trong bối cảnh sai. Để rõ ràng, trong mã thực tế, add_action nằm trong một hàm khác trong cùng một lớp. Điều đó làm việc tốt.


Tôi đã phát triển một tập lệnh cho phép bạn dễ dàng thêm các thông báo quản trị viên có thể bỏ qua / tĩnh github.com/askupasoftware/wp-admin-notification
Yoav Kadosh

Câu trả lời:


30

Lý do điều này không hoạt động là vì có một sự chuyển hướng xảy ra sau hành động save_post. Một cách bạn có thể đạt được muốn bạn muốn là thực hiện một công việc nhanh chóng xung quanh bằng cách sử dụng các vars truy vấn.

Đây là một lớp mẫu để chứng minh:

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
  }
}

Hy vọng điều này sẽ giúp bạn một chút. Chúc mừng


Công trình tuyệt vời, cảm ơn! Nhưng có một khung đóng bị thiếu trong dòng đầu tiên trong public function admin_notices()(một khung đóng thêm trong if ( ! isset(..dòng)
Rhys Wynne

Tôi đã thêm remove_query_arg('YOUR_QUERY_VAR');khi tôi thấy nó có thể được đặt từ bản cập nhật cuối cùng.
Tony O'Hagan

+1 Câu trả lời hay.
Đánh dấu

12

Tạo một lớp bao bọc cho loại kịch bản này. Trên thực tế, lớp có thể được sử dụng trong bất kỳ kịch bản nào liên quan đến việc hiển thị các thông báo. Tôi sử dụng các tiêu chuẩn PSR, vì vậy việc đặt tên không điển hình của mã 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
        ]);
    }
}

Sử dụng:

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

Thông báo được hiển thị một lần.


6

Ngoài câu trả lời @ của jonathanbardo đó là rất tốt và hoạt động tốt, nếu bạn muốn loại bỏ các tham số truy vấn sau khi trang mới được nạp, bạn có thể sử dụng removable_query_args lọc. Bạn nhận được một loạt các tên đối số mà bạn có thể nối thêm đối số của riêng mình. Sau đó, WP sẽ đảm nhiệm việc xóa tất cả các đối số trong danh sách khỏi 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;
}

Cái gì đó như:

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

Sẽ trở thành:

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

1

Đơn giản, thanh lịch, dựa trên 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;
}

Sử dụng

Trong xử lý yêu cầu bài viết của bạn:

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

Nơi bạn muốn sử dụng thông báo quản trị, thường là trong admin_noticeshook.

$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>';
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.