J'implémente un système de modération des commentaires AJAX frontal pour un site que je gère, mais j'ai du mal à le faire fonctionner. En ce moment, en cliquant sur le lien qui approuve le commentaire, le script php approprié est exécuté, mais la page entière est rechargée. Cela fonctionne donc, mais je voudrais approuver le commentaire en utilisant ajax sans recharger toute la page, mais mon manque de connaissances en javascript m'empêche de le faire fonctionner. Voici le code (situé dans un plugin):
add_filter( 'comment_text', 'p3_comment_moderation_buttons' );
function p3_comment_moderation_buttons ( ) {
if ( is_author() || current_user_can( 'moderate_comment' ) ) {
// Adds moderation buttons under every comment
$comment_id = get_comment_ID();
$text = get_comment_text();
$nonce = wp_create_nonce( 'p3_comment_moderation' );
$p3_approve_link = admin_url('admin-ajax.php?action=p3_comment_approve&comment_id='. $comment_id.'&nonce='.$nonce);
$p3_edit_links = '<div class="p3-edit-links"><a class="p3-comment-moderation" href="' . $p3_approve_link . '" data-comment_id="' . $comment_id . '" data-nonce="' . $nonce . '">Approve</a></div>';
return $text . $p3_edit_links;
}
else{
return get_comment_text();
}
}
add_action("wp_ajax_p3_comment_approve", "p3_comment_approve");
function p3_comment_approve() {
if ( ! wp_verify_nonce( $_REQUEST['nonce'], 'p3_comment_moderation' ) ) {
exit("Go away!"); //If nonce check fails stop everything
}
$comment_id = $_REQUEST["comment_id"];
$success = wp_set_comment_status( $comment_id, 'approve' );
$success = update_comment_meta( $comment_id, 'p3_comment_status', '' );
if ( $success = true ) {
$result['type'] = 'success';
$result['comment_id'] = $_REQUEST["comment_id"];
}
else {
$result['type'] = 'error';
$result['comment_id'] = $_REQUEST["comment_id"];
echo "Something didn't work";
}
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
$result = json_encode($result);
echo $result;
}
else {
header("Location: ".$_SERVER["HTTP_REFERER"]);
}
die(); // this is required to return a proper result
}
add_action( 'init', 'p3_comment_meta_script_enqueuer' );
function p3_comment_meta_script_enqueuer() {
wp_register_script( "p3_comment_meta", plugins_url().'/p3wp-comments/js/p3_comment_meta.js', array('jquery') );
wp_localize_script( "p3_comment_meta", 'p3cmetaAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' )));
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'p3_comment_meta' );
}
Et le javascript correspondant:
jQuery(document).ready( function() {
jQuery(".p3-comment-moderation").click( function() {
comment_id = jQuery(this).attr("data-comment_id")
nonce = jQuery(this).attr("data-nonce")
jQuery.ajax({
type : "post",
dataType : "json",
url : p3cmetaAjax.ajaxurl,
data : {action: "p3_comment_meta", comment_id : comment_id, nonce: nonce},
success: function(response) {
if(response.type == "success") {
alert("Success!")
}
else {
alert("Something went wrong.")
}
}
})
})
})
Quelqu'un peut-il repérer le problème?
En passant, j'ai déjà modifié le modèle de commentaire pour afficher les commentaires non approuvés afin qu'ils puissent être approuvés au début. Je prévois également de développer cela pour utiliser des méta de commentaires personnalisés, et de développer le javascript pour qu'il soit plus utile que l'affichage d'une alerte gênante.
Merci
Il me semble que le seul problème est que vous mettez l'URL d'approbation complète dans le lien. Ainsi, lorsque vous cliquez sur le lien, vous déclenchez l'ajax et ouvrez l'URL de la page dans lien.
Pour être plus clair, votre lien ressemble à quelque chose comme:
<a class="p3-comment-moderation" href="admin-ajax.php?action=p3_comment_approve&comment_id=123&nonce=xxxxx" data-comment_id="123" data-nonce="xxxxx">Approve</a>
grâce au javascript, lorsque vous cliquez sur le lien, vous lancez une requête ajax mais rien n'empêche le comportement du lien par défaut d'être déclenché. Le admin-ajax.php
est donc requis du navigateur et, grâce à l'instruction header
de votre code. , puis la page revient à la page actuelle.
Donc, en fait, voici ce qui se passe:
admin-ajax.php
est ouvert par l'URL dans la balise a
header("Location: ".$_SERVER["HTTP_REFERER"])
dans votre codeJe sais que l'insertion de l'URL complète dans le lien est la bonne façon de le faire fonctionner même si l'utilisateur a javascript désactivé, mais lorsque javascript est activé, vous devez empêcher le comportement du lien par défaut, vous pouvez le faire via la fonction preventDefault()
js.
Donc, dans votre javascript, remplacez
jQuery(".p3-comment-moderation").click( function() {
avec
jQuery(".p3-comment-moderation").click( function(e) {
e.preventDefault();
Après cela, tout devrait fonctionner comme prévu .
Si, comme je suppose, c'est le seul problème, cette question est purement javascript, donc hors sujet ici. Cependant, pour que ma réponse soit plus pertinente pour WordPress, je souhaite ajouter quelques astuces (rien ne permet au script de fonctionner ou non, juste des pratiques recommandées et des améliorations).
Lorsque, dans WordPress, vous exportez quelque chose dans la sortie html en tant que propriété de balise, il est recommandé de l’échapper avec esc_attr
. En général, utilisez la fonction all esc_*
lorsque vous le souhaitez
$p3_edit_links = '<a class="p3-comment-moderation" href="' . $p3_approve_link . '" data-comment_id="' . $comment_id . '" data-nonce="' . $nonce . '">Approve</a>';
est mieux écrit:
$p3_edit_links_f = '<a class="p3-comment-moderation" href="%s" data-comment_id="%d" data-nonce="%s">';
$p3_edit_links = sprintf($p3_edit_links_f, esc_url($p3_approve_link), esc_attr($comment_id), esc_attr($nonce) );
Je sais que vous obtenez les URL et les attributs de WP fonctions principales. Cependant, une fois que presque tous les résultats de base peuvent être filtrés, il est bon d'appliquer la validation des données (bien que les fonctions de validation des données puissent également être filtrées ...).
Dans votre code il y a
if( ! empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
pour vérifier si la requête actuelle provient de ajax. Dans WordPress, lorsque vous utilisez correctement admin-ajax.php
(comme vous le faites), vous pouvez vérifier la demande ajax à la recherche de la constante DOING_AJAX
, de sorte que l'instruction conditionnelle précédente devienne:
if ( defined('DOING_AJAX') && DOING_AJAX ) {
Votre code
$result = json_encode($result);
echo $result;
...
die();
peut être écrit sur une ligne, en utilisant la fonction de base wp_send_json
wp_send_json( $result );
lorsque vous devez manipuler des superglobales ($_REQUEST
, $_GET
, $_POST
...) afin d'éviter les notifications, vous devez toujours vérifier que la clé que vous recherchez est définie.
if ( ! wp_verify_nonce( $_REQUEST['nonce'], 'p3_comment_moderation' ) ) {
est mieux écrit:
if ( ! isset($_REQUEST['nonce']) || ! wp_verify_nonce( $_REQUEST['nonce'], 'p3_comment_moderation' ) ) {
Cependant, il est préférable d'utiliser filter_var
plutôt que d'accéder directement aux superglobales
$nonce = filter_var( INPUT_GET, 'nonce', FILTER_VALIDATE_STRING);
if ( empty($nonce) ) $nonce = filter_var( INPUT_POST, 'nonce', FILTER_VALIDATE_STRING);
if ( ! wp_verify_nonce( $nonce, 'p3_comment_moderation' ) ) {