Comment ajouter un avis administrateur lors de la sauvegarde / mise à jour

16

J'ai un type de message qui utilise post_save pour prendre l'adresse du post-méta et récupérer les coordonnées lat / lng de l'API Google. J'ai besoin d'un moyen d'avertir l'utilisateur s'il y a eu un problème avec la récupération des coordonnées. J'ai essayé d'utiliser admin_notices, mais rien ne s'affiche:

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

Je ne sais pas si je l'utilise incorrectement ou dans le mauvais contexte. Pour être clair, dans le code réel, add_action est dans une autre fonction de la même classe. Ça marche bien.

Jason
la source
J'ai développé un script qui vous permet d'ajouter facilement des notifications administrateur licenciables / statiques github.com/askupasoftware/wp-admin-notification
Yoav Kadosh

Réponses:

30

La raison pour laquelle cela ne fonctionne pas est parce qu'une redirection se produit après l'action save_post. Vous pouvez obtenir ce que vous voulez en implémentant un travail rapide autour de l'utilisation des variables de requête.

Voici un exemple de classe pour démontrer:

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

J'espère que cela vous aide un peu. À votre santé

jonathanbardo
la source
Fonctionne très bien, merci! Mais il manque un crochet de fermeture dans la première ligne du public function admin_notices()(un crochet de fermeture supplémentaire dans la if ( ! isset(..ligne)
Rhys Wynne
J'ai ajouté remove_query_arg('YOUR_QUERY_VAR');car j'ai trouvé qu'il peut être défini à partir de la dernière mise à jour.
Tony O'Hagan
+1 Bonne réponse.
Mark
12

Création d'une classe wrapper pour ce type de scénario. En fait, la classe peut être utilisée dans n'importe quel scénario impliquant l'affichage d'avis. J'utilise les normes PSR, donc la dénomination est atypique du code 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
        ]);
    }
}

Usage:

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

L'avis s'affiche une fois.

DarkNeuron
la source
6

En plus de la réponse de @ jonathanbardo qui est excellente et fonctionne bien, si vous souhaitez supprimer l'argument de requête après le chargement de la nouvelle page, vous pouvez utiliser le filtre amovible_query_args . Vous obtenez un tableau de noms d'arguments auxquels vous pouvez ajouter votre propre argument. WP se chargera ensuite de supprimer tous les arguments de la liste de l'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;
}

Quelque chose comme:

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

Va devenir:

'...post.php?post=1'
AncientRo
la source
1

Simple, élégant, basé sur 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;
}

Usage

Dans votre gestionnaire de demandes de publication:

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

Où vous souhaitez utiliser l'avis d'administration, généralement dans le admin_noticescrochet.

$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
la source