J'essaie de faire une validation côté serveur des champs de publication (champs personnalisés et/ou non personnalisés). La validation fonctionne très bien, mais je n'arrive pas à arrêter l'enregistrement de la publication si la validation échoue.
J'ai essayé des hooks comme save_post
, publish_post
, wp_insert_post_data
, etc. Tous ces hooks sont appelés, mais je ne peux pas empêcher la publication de sauvegarder sauf si j'utilise wp_die()
. Pour être clair, je ne veux pas changer le statut de la publication; Je veux juste revenir à la page de publication (non enregistrée) et afficher un message lorsque la validation d'un champ échoue.
Je pense que c'est assez basique, mais quoi que je fasse, le post est sauvegardé.
METTRE À JOUR:
OK, le hook pre_post_update
est une option. Cependant, en cas d'échec de la validation, je dois utiliser wp_redirect
pour revenir à la page d'édition sans enregistrer. Je stocke les msgs d'invalidation et les affiche sur la page, mais de cette façon, toutes les données $_POST
ont disparu ... ce qui, bien sûr, n'est pas acceptable. N'y a-t-il vraiment pas d'autre moyen de faire cela?
Voici mon code jusqu'à présent:
add_action('pre_post_update', 'validate_meta', 99, 2);
function validate_meta($post_id){
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;
if (!isset($_POST['post_type']) ) return $post_id;
if ( !current_user_can( 'edit_posts', $post_id ) ) return $post_id;
$errors = array();
if(trim($_POST['post_title']) == ''){
$errors[] = new WP_Error('cpt_validation_titke', 'Bitte einen Titel eintragen', 'error');
}
if (!empty($errors)) {
add_user_meta(get_current_user_id(), 'admin_notices', $errors, true);
$url = admin_url( 'post.php?post=' . $post_id ) . '&action=edit';
//exit;
wp_redirect( $url );
exit;
}
return $_POST;
}
// Display any errors
add_action( 'admin_notices', 'admin_notice_handler' );
function admin_notice_handler() {
$user_id = get_current_user_id();
$admin_notices = get_user_meta($user_id, 'admin_notices', true);
if(!empty($admin_notices)){
$html = '';
if(is_wp_error($admin_notices[0])){
delete_user_meta($user_id, 'admin_notices');
foreach($admin_notices AS $notice){
$msgs = $notice->get_error_messages();
if(!empty($msgs)){
$msg_type = $notice->get_error_data();
if(!empty($notice_type)){
$html .= '<div class="'.$msg_type.'">';
} else {
$html .= '<div class="error">';
$html .= '<p><strong>Validation errors</strong></p>';
}
foreach($msgs as $msg){
$html .= '<p>- '.$msg.'</p>';
}
$html .= '</div>';
}
}
}
echo $html;
}
}
Vous pouvez capturer la soumission du formulaire en créant un petit plugin/ou en modifiant votre fichier de fonctions de thème, et vous pouvez le faire en utilisant un hook ajax. Dans le plug-in, vous devriez charger ceci sur la page d'édition du post:
jQuery(document).ready(function(){
jQuery('#post').submit(function(){
var request = jQuery(this).serializeArray();
request.Push({name: 'action', value: 'check_some_stuff'});
jQuery.post(ajaxurl, request, function(response){
if(response.error){
response = jQuery.parseJSON(response);
jQuery('#local-storage-notice').after('<div class="error">'+response.error+'</div>');
});
return false;
} else {
return true;
}
});
});
Lorsque vous renvoyez false, le formulaire ne sera plus soumis.
Le ajax appellera une fonction check_some_stuff . La request
est envoyée sous la forme $ _POST. Vous pouvez ensuite valider tout ce que vous voulez côté serveur:
add_action( 'wp_ajax_check_some_stuff', 'check_some_stuff' );
public function check_some_stuff()
{
//validate some stuff here
$valid = false;
if($valid){
$results = array('msg'=>'You win');
print json_encode($results);
} else {
$results = array('error'=>'<pre>'+print_r($_POST, true)+'</pre>');
print json_encode($results);
}
die();
}
Je peux aller plus en détail sur la façon d'ajouter le javascript si vous avez besoin.
Le moyen le plus simple - à mon avis - d'y parvenir est d'utiliser PHP: Sessions, donc le $_SESSION
global ou quelque chose comme "WP Session Manager" . Lorsque vous utilisez des sessions, vous pouvez simplement ajouter vos données de publication à la variable de session avant la redirection et disposer des données après la redirection.
Cela ressemble à quelque chose que vous pourriez résoudre avec l'aide d'AJAX. Consultez la section "JavaScript, AJAX & jQuery" du manuel du plugin WordPress:
https://developer.wordpress.org/plugins/javascript/jquery/
Ne laissez pas le fait que ce soit un manuel de plug-ins vous irriter. Il peut être utile de créer un petit plugin pour cette tâche, sinon vous pouvez utiliser les instructions de votre functions.php.
Voici comment je procéderais après avoir lu les instructions du manuel:
Oui, cela nécessite quelques petites connaissances de jQuery, mais il n'y a pas d'enregistrement ni d'actualisation de page. Le manuel fournit de très bonnes explications, espérons que cela aide!
Cela faisait un moment, mais je pensais qu'utiliser wp_die () puis appuyer sur le bouton Précédent afficherait de nouveau la page avec les données du formulaire.
Si tel est le cas, vous pouvez envoyer un message à l'aide de wp_die pour indiquer le problème, éventuellement comment le résoudre, et pour sélectionner le bouton Précédent dans leur navigateur, corrigez le problème, puis réessayez.
Une meilleure façon pourrait être de:
Utilisez le hook pre_post_update, faites votre validation, et ...
La cinquième partie pourrait être un peu pénible, mais devrait être faisable en utilisant un filtre ou javascript.
Votre méta utilisateur enregistré pourrait ressembler à ceci:
$meta_value = array(
'field_name' => array(
'bad_value' => $users_bad_value,
'problem' => 'Your data had this problem with it'
)
);
update_user_meta( $user_id, "_edit_post_problems_{$post_id}", $meta_value );
N'oubliez pas de supprimer les métadonnées après l'avoir lue pendant le chargement de la page.
L'enregistrement automatique est sur votre chemin.
(J'aurais simplement laissé un commentaire mais le crédit me manque.)