Bagaimana cara menambahkan pemberitahuan admin setelah menyimpan / memperbarui

16

Saya memiliki posting ketik yang menggunakan post_save untuk mengambil alamat dari post-meta dan mengambil koordinat lat / lng dari Google API. Saya perlu cara memberi tahu pengguna jika ada masalah dengan mengambil coordintes. Saya mencoba menggunakan admin_notices, tetapi tidak ada yang ditampilkan:

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

Saya tidak yakin apakah saya menggunakannya secara salah atau dalam konteks yang salah. Agar jelas, dalam kode aktual add_action ada di fungsi lain di kelas yang sama. Itu bekerja dengan baik.

Jason
sumber
Saya telah mengembangkan skrip yang memungkinkan Anda menambahkan notifikasi admin yang dapat diterima
Yoav Kadosh

Jawaban:

30

Alasan ini tidak berhasil adalah karena ada pengalihan yang terjadi setelah tindakan save_post. Salah satu cara Anda dapat mencapai keinginan yang Anda inginkan adalah dengan mengimplementasikan kerja cepat menggunakan vars kueri.

Berikut adalah contoh kelas untuk diperagakan:

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

Semoga ini bisa membantu Anda sedikit. Bersulang

Jonathanbardo
sumber
Bagus sekali, terima kasih! Tapi ada braket penutupan yang hilang di baris pertama di public function admin_notices()(braket penutupan tambahan di if ( ! isset(..baris)
Rhys Wynne
Saya telah menambahkan remove_query_arg('YOUR_QUERY_VAR');karena saya dapat mengaturnya dari pembaruan terakhir.
Tony O'Hagan
+1 Jawaban yang bagus.
Markus
12

Membuat kelas pembungkus untuk skenario semacam ini. Sebenarnya kelas dapat digunakan dalam skenario apa pun yang melibatkan menampilkan pemberitahuan. Saya menggunakan standar PSR, jadi penamaannya tidak biasa pada kode 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
        ]);
    }
}

Pemakaian:

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

Pemberitahuan ditampilkan sekali.

DarkNeuron
sumber
6

Selain jawaban jonathanbardo yang hebat dan berfungsi dengan baik, jika Anda ingin menghapus argumen kueri setelah halaman baru dimuat, Anda dapat menggunakan filter removable_query_args . Anda mendapatkan berbagai nama argumen yang dapat Anda tambahkan argumen Anda sendiri. Kemudian WP akan menghapus semua argumen dalam daftar dari 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;
}

Sesuatu seperti:

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

Akan menjadi:

'...post.php?post=1'
AncientRo
sumber
1

Sederhana, elegan, berdasarkan 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;
}

Pemakaian

Dalam penangan permintaan pos Anda:

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

Di mana Anda ingin menggunakan pemberitahuan admin, biasanya di 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>';
}
Fleuv
sumber