如何在POST保存/更新时添加管理通知

时间:2014-06-27 作者:Jason

我有一个post类型,它使用post\\u save从post meta获取地址,并从Google API检索纬度/液化天然气坐标。如果检索坐标时出现问题,我需要一种通知用户的方法。我尝试使用admin\\u通知,但没有显示任何内容:

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\\u操作位于同一类中的另一个函数中。这很好用。

5 个回复
最合适的回答,由SO网友:jonathanbardo 整理而成

这不起作用的原因是,在save\\u 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
  }
}
希望这对你有点帮助。干杯

SO网友:DarkNeuron

为这种场景创建了一个包装器类。实际上,该类可以用于任何涉及显示通知的场景。我使用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.\'));
通知只显示一次。

SO网友:AncientRo

除了@jonathanbardo的答案很好而且功能很好之外,如果您想在加载新页面后删除查询参数,您可以使用removable_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\'

SO网友:luukvhoudt

简单、优雅,基于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;
}
post请求处理程序中的用法:

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>\';
}

SO网友:Niklas

您可以通过重定向并通过过滤器传递查询参数来实现这一点redirect_post_location. 还有redirect_term_location 这将适用于分类法/术语。

首先添加admin_notices 操作将始终处于活动状态,但仅在特定条件下显示通知。

add_action( \'admin_notices\', \'general_admin_notice\' );

function general_admin_notice(){
  global $pagenow;

  if ( \'post.php\' === $pagenow && isset($_GET[\'post\']) && \'custom_post_type\' === get_post_type( $_GET[\'post\'] ) ){

    if ( isset($_GET[\'empty\'])) {
      
      // Turn string into array, so we can loop trough it.
      $terms_id = explode( \',\', $_GET[\'empty\'] );

      echo \'<div class="notice notice-error is-dismissible">
                <p>\';
                foreach ( $terms_id as $term_id ) {
                  $term = get_term( $term_id, \'custom_taxonomy\' );
                  echo \'<a href="\'.get_term_link( $term ).\'">\'.$term->name.\'</a>, \';
                }
              echo \'nutrients are empty.</p>
            </div>\';
      }
    }
}
然后,需要在保存后重定向页面,并用传递查询参数add_query_arg. 按照我在这里所做的方式,您可以在管理通知中显示动态输入。

        if ( !empty($empty_error) ) {
            add_filter(\'redirect_post_location\', function($loc) use ($empty_error) {
                trigger_error( $empty_error);
                return add_query_arg( \'empty\', implode(\',\', $empty_error), $loc );
            }); 
        }
就我而言,我会array_push 在变量上$empty_error 使用术语id。管理员通知将显示所有有错误的术语,并链接到相应的术语。

您还可以使用removable_query_args 删除添加的查询参数,使url看起来更干净。如果你重新加载页面,管理通知就会消失。

add_filter(\'removable_query_args\', \'add_removable_arg\');

function add_removable_arg($args) {
    array_push($args, \'empty\');
    return $args;
}

结束