J'ai un mécanisme de gestion des erreurs configuré dans l'un de mes plugins pour ajouter des notifications et des erreurs à la zone d'administration, comme le fait le noyau. Cela fonctionne bien dans la plupart des cas, mais il existe certaines situations (comme la sauvegarde d'un type d'article personnalisé) dans lesquelles cela ne fonctionne pas. J'imagine qu'une redirection se produit en coulisse et que les messages sont imprimés avant la redirection, de sorte qu'ils ne semblent jamais s'afficher.
Donc, je suppose que c'est ce qui se passe
Dans des circonstances normales, les étapes 4 et 5 ne se produisent pas, donc tout fonctionne bien, mais je pense que lorsque Wordpress enregistre les publications, il introduit la redirection supplémentaire. Est-ce que je peux faire quelque chose pour m'assurer que cela fonctionne toujours? Je pensais que je pourrais peut-être vérifier quelque chose dans printMessages () et revenir immédiatement si c'est à l'étape 4, mais je ne sais pas quoi.
Ces deux questions peuvent éclaircir le problème, mais ne donnent pas une solution complète: Ajoute une validation et une gestion des erreurs lors de la sauvegarde des champs personnalisés? , Comment afficher la notification d'erreur d'administrateur si les paramètres ont été enregistrés avec succès? .
Voici le code:
/**
* Constructor
* @author Ian Dunn <[email protected]>
*/
public function __construct()
{
// Initialize variables
$defaultOptions = array( 'updates' => array(), 'errors' => array() );
$this->options = array_merge( get_option( self::PREFIX . 'options', array() ), $defaultOptions );
$this->updatedOptions = false;
$this->userMessageCount = array( 'updates' => 0, 'errors' => 0 );
// more
add_action( 'admin_notices', array($this, 'printMessages') );
add_action( 'post_updated', array($this, 'saveCustomFields') );
// does other stuff
}
/**
* Saves values of the the custom post type's extra fields
* @author Ian Dunn <[email protected]>
*/
public function saveCustomFields()
{
// does stuff
if( true ) // if there was an error
$this->enqueueMessage( 'foo', 'error' );
}
/**
* Displays updates and errors
* @author Ian Dunn <[email protected]>
*/
public function printMessages()
{
foreach( array('updates', 'errors') as $type )
{
if( $this->options[$type] && ( self::DEBUG_MODE || $this->userMessageCount[$type] ) )
{
echo '<div id="message" class="'. ( $type == 'updates' ? 'updated' : 'error' ) .'">';
foreach($this->options[$type] as $message)
if( $message['mode'] == 'user' || self::DEBUG_MODE )
echo '<p>'. $message['message'] .'</p>';
echo '</div>';
$this->options[$type] = array();
$this->updatedOptions = true;
$this->userMessageCount[$type] = 0;
}
}
}
/**
* Queues up a message to be displayed to the user
* @author Ian Dunn <[email protected]>
* @param string $message The text to show the user
* @param string $type 'update' for a success or notification message, or 'error' for an error message
* @param string $mode 'user' if it's intended for the user, or 'debug' if it's intended for the developer
*/
protected function enqueueMessage($message, $type = 'update', $mode = 'user')
{
array_Push($this->options[$type .'s'], array(
'message' => $message,
'type' => $type,
'mode' => $mode
) );
if($mode == 'user')
$this->userMessageCount[$type . 's']++;
$this->updatedOptions = true;
}
/**
* Destructor
* Writes options to the database
* @author Ian Dunn <[email protected]>
*/
public function __destruct()
{
if($this->updatedOptions)
update_option(self::PREFIX . 'options', $this->options);
}
Update:Le code mis à jour avec la réponse acceptée a été validé dans core.php dans le fichier trunk du plugin, au cas où quelqu'un voudrait voir une copie de travail complète. La prochaine version stable qui l’aura est la 1.2.
Update 2:J'ai résumé cette fonctionnalité dans une bibliothèque autonome que vous pouvez inclure dans votre plugin. Core discute de l’inclusion de fonctionnalités similaires dans # 11515 .
Il y a peu de choses que j'ai mentionnées dans le code ci-dessous aussi:
get_option
en utilisant array_merge
__destruct
ne fonctionnent tout simplement pas. (Je n'ai pas encore la moindre idée, peut-être que des experts vont nous éclairer.J'ai marqué toutes les sections où j'ai apporté les modifications avecHKFIX, avec un peu de description:
/**
* Constructor
* @author Ian Dunn <[email protected]>
*/
public function __construct()
{
// Initialize variables
$defaultOptions = array( 'updates' => array(), 'errors' => array() );
/* HKFIX: array_merge was overwriting the values read from get_option,
* moved $defaultOptions as first argument to array_merge */
$this->options = array_merge( $defaultOptions, get_option( self::PREFIX . 'options', array() ) );
$this->updatedOptions = false;
/* HKFIX: the count for update and error messages was hardcoded,
* which was ignoring the messages already in the options table read above
* later in print the MessageCounts is used in loop
* So I updated to set the count based on the options read from get_option */
$this->userMessageCount = array();
foreach ( $this->options as $msg_type => $msgs ) {
$this->userMessageCount[$msg_type] = count( $msgs );
}
// more
add_action( 'admin_notices', array($this, 'printMessages') );
add_action( 'post_updated', array($this, 'saveCustomFields') );
// does other stuff
}
/**
* Saves values of the the custom post type's extra fields
* @author Ian Dunn <[email protected]>
*/
public function saveCustomFields()
{
// does stuff
/* HKFIX: this was false, so changed it to true, may be not a fix but thought I should mention ;) */
if( true )
$this->enqueueMessage( 'foo', 'error' );
}
/**
* Displays updates and errors
* @author Ian Dunn <[email protected]>
*/
public function printMessages()
{
foreach( array('updates', 'errors') as $type )
{
if( $this->options[$type] && ( self::DEBUG_MODE || $this->userMessageCount[$type] ) )
{
echo '<div id="message" class="'. ( $type == 'updates' ? 'updated' : 'error' ) .'">';
foreach($this->options[$type] as $message)
if( $message['mode'] == 'user' || self::DEBUG_MODE )
echo '<p>'. $message['message'] .'</p>';
echo '</div>';
$this->options[$type] = array();
$this->updatedOptions = true;
$this->userMessageCount[$type] = 0;
}
}
/* HKFIX: Save the messages, can't wait for destruct */
if ( $this->updatedOptions ) {
$this->saveMessages();
}
}
/**
* Queues up a message to be displayed to the user
* @author Ian Dunn <[email protected]>
* @param string $message The text to show the user
* @param string $type 'update' for a success or notification message, or 'error' for an error message
* @param string $mode 'user' if it's intended for the user, or 'debug' if it's intended for the developer
*/
protected function enqueueMessage($message, $type = 'update', $mode = 'user')
{
array_Push($this->options[$type .'s'], array(
'message' => $message,
'type' => $type,
'mode' => $mode
) );
if($mode == 'user')
$this->userMessageCount[$type . 's']++;
/* HKFIX: save the messages, can't wait for destruct */
$this->saveMessages();
}
/* HKFIX: Dedicated funciton to save messages
* Can also be called from destruct if that is really required */
public function saveMessages()
{
update_option(self::PREFIX . 'options', $this->options);
}
/**
* Destructor
* Writes options to the database
* @author Ian Dunn <[email protected]>
*/
public function __destruct()
{
/* HKFIX: Can't rely on saving options in destruct, this just does not work */
// its very late to call update_options in destruct
//update_option(self::PREFIX . 'options', $this->options);
}
Je n'ai actuellement aucune idée de ce qui se passe avec votre plugin. Je vous signale donc deux choses:
wp_parse_args()
est un bon moyen de fusionner les valeurs par défaut avec d'autres arguments.
private $defaults;
function wpse20130_parse_us( $args );
{
$new_args = wp_parse_args( $this->defaults, $args );
return $new_args;
}
Et ce plugin est un peu plus proche de la façon dont le noyau traite les erreurs (directement de ma tête - peut contenir des erreurs lui-même):
EDIT: Test Plugin
<?php
/**
Plugin Name: WPSE Show Error on post
Plugin URI: https://github.com/franz-josef-kaiser/
Description: Example for the useage of the WP Error class in a plugin
Author: Franz Josef Kaiser
Author URI: https://github.com/franz-josef-kaiser
Version: 0.1
License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/
// Secure: doesn't allow to load this file directly
if( ! class_exists('WP') )
{
header( 'Status: 403 Forbidden' );
header( 'HTTP/1.1 403 Forbidden' );
exit;
}
if ( ! class_exists('wpse20130Error') )
{
class wpse20130Error
{
private $args = array();
private $error_msg;
const TEXTDOMAIN = 'textdomain';
function __construct()
{
$this->wpse20130_input( $this->args );
add_action( 'admin_notices', array($this, 'wpse20130_trigger_error') );
}
function wpse20130_input( $args )
{
if ( ! isset( $args['some_important_value'] ) )
$this->error_msg = sprintf(
__(
'You have to specify the some_important_value inside the %2$s function.'.'<br />'.
'Error triggered inside: file name %1$s (line number %3$s)'
,self::TEXTDOMAIN
)
,__FILE__
,__FUNCTION__
,__LINE__
);
}
function wpse20130_trigger_error()
{
// Trigger Errors if we got some
if ( isset( $this->error_msg ) )
{
$error = new WP_Error( 'input_data', $this->error_msg );
if ( is_wp_error( $error ) )
{
$output =
'<div id="error-'.$error->get_error_code().'" class="error error-notice">'.
$error->get_error_message().
'</div>';
// die & print error message
echo $output;
}
}
}
} // END Class wpse20130Error
new wpse20130Error();
} // endif;
?>
Essaie. :)