Donc, j'ai un plugin qui utilise Ajax pour construire dynamiquement le contenu de la publication pièce par pièce pour un type de publication personnalisé. Une fois que l'utilisateur a créé sa page, il clique sur Mettre à jour/Publier et Ajax envoie l'intégralité de la page construite au fichier plugin principal PHP où j'essaie d'appeler wp_insert_post()
.
Voici mon code pertinent (et oui, le var new_content
est défini et correct):
jQuery.ajax({
url: ajaxurl,
method: 'POST',
data : {
update_or_create: '1',
post_content: new_content,
post_title: jQuery('#title').val(),
pid: jQuery('#post_ID').val(),
action : "update_or_save_zen_page"
} ,
success : function(data, textStatus, XMLHttpRequest) {
//alert(data);
console.log(data); // the data sent to the php file is correct
console.log(textStatus); // reads 'success'
console.log(XMLHttpRequest); // normal from what I can tell, "readyState: 4"
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
alert("An unknown error has occurred"); // this does not fire
//console.log(data);
//console.log(textStatus);
//console.log(errorThrown);
//console.log(XMLHttpRequest);
}
});
Voici le code php sur lequel ce message est posté:
function pbfcz_save_zen_page() {
$pid = ( is_numeric($_POST['pid']) ? $_POST['pid'] : 0);
$the_content = sanitize_post_field ('post_content', $_POST['post_content'], $pid);
$the_title = sanitize_text_field ( $_POST['post_title'] );
$post_array = array (
'ID' => $pid,
'post_title' => $the_title,
'post_content' => $the_content, // at this point, $the_content is correct
'post_status' => 'publish',
'post_type' => 'zen_page'
);
$insert = wp_insert_post( $post_array, true ); // this returns the ID every time, meaning successful update, but it is not always successful
//echo $insert; // this is always the post ID, meaning success
echo $the_content; // this is still correc
wp_die();}
Lorsque l'utilisateur sélectionne enregistrer, j'ai suivi les données jusqu'à l'argument de wp_insert_post()
. C'est toujours correct. La fonction renvoie TOUJOURS l'identifiant de publication, ce qui signifie qu'elle a réussi. Je ne reçois pas un WP_Error
retourné ni des erreurs de code HTML telles que 404 ou 500 ou quelque chose du genre.
Je ne reçois pas non plus d'erreur dans la console des outils de développement de chrome. Mais il met à jour PARFOIS avec succès - peut-être que tous les essais sur 10 fonctionnent.
J'ai essayé d'utiliser GET au lieu de POST
J'ai essayé de supprimer le 'post_status' => 'publish'
des arguments.
J'ai essayé de convertir le post_content
en UTF8 en utilisant utf8_encode()
.
J'ai essayé d'utiliser post_content_filtered
plutôt que post_content
.
Rien ne semble fonctionner, et cela fonctionne de manière aléatoire, et je ne peux pas trouver de motif.
Le seul autre élément d’information dont je dispose est peut-être lié au fait que les images ont du mal à se charger sur cette même page. S'il y a une image dans le contenu de la page, des erreurs telles que
"net :: ERR_SPDY_PING_FAILED" ou "net :: ERR_CONNECTION_RESET"
ou:
"net :: ERR_CONNECTION_CLOSED"
parfois lors du chargement de la page. Le serveur essaie de charger l'image pendant plus d'une minute, puis expire (mais l'image est déjà affichée sur la page pendant toute cette minute, puis lorsqu'il disparaît, l'image disparaît).
Quelqu'un peut-il suggérer pourquoi cela ne fonctionne pas (avec zéro erreur), mais fonctionne-t-il parfois? Merci à tous d'avance et laissez-moi savoir si vous avez besoin de plus de code ou de fond.
Ne cherchez plus à rappeler votre rappel AJAX, il existe déjà un endpoint API REST qui est bien testé et qui effectue tout cela immédiatement:
example.com/wp-json/wp/v2/zen_page
Mettons donc en file d'attente un script d'assistance pour nous donner l'URL et un jeton de sécurité/nonce:
wp_enqueue_script( 'wp-api' );
Vous devrez must activer l'API REST pour votre type d'article personnalisé en ajoutant cette option lors de l'enregistrement de votre type d'article. Si vous ne le faites pas, les noeuds finaux zen_page
rest ne seront pas créés par core:
'show_in_rest' => true
Puis ajustez le JS:
var post_id = 1;
jQuery.ajax({
url: wpApiSettings.root + 'wp/v2/zen_page/'+post_id,
method: 'POST',
beforeSend: function ( xhr ) {
xhr.setRequestHeader( 'X-WP-Nonce', wpApiSettings.nonce );
},
data : {
content: 'post content goes here',
title: 'test post',
status: 'publish'
}
}).fail( function( response ) {
// failure
console.log( 'failure' );
console.log( response );
}).done( function( response ) {
// success!
console.log( 'success' );
console.log( response );
}).;
WP inclut automatiquement l'objet wpApiSettings
lorsque vous mettez en file d'attente wp-api
et data
prend ces valeurs . Pour ce faire, vous aurez besoin d'un cookie de connexion actif. Si ce n'est pas une option, vous pouvez créer de nouveaux terminaux
Si vous souhaitez en créer une nouvelle, envoyez une demande POST ici:
example.com/wp-json/wp/v2/zen_page
Si vous souhaitez en mettre à jour une, envoyez une demande POST ici:
example.com/wp-json/wp/v2/zen_page/2
Où 2 est l'ID de publication que vous souhaitez mettre à jour. Envoyez une demande DELETE pour le supprimer. Dans une API REST, vous ne transmettez pas d'ID de publication ni d'actions, mais vous utilisez des URL, de la même manière que des URL différentes chargent des pages différentes, des points de terminaison différents effectuent des opérations différentes. Vous pouvez GET
/POST
/DELETE
/PUT
, et ce sont tous les types de requête HTTP standard, pas un paramètre transmis dans la demande.
rest_base
Cela vous permettra de modifier le noyau utilisé pour créer le noeud final, par exemple.
'rest_base' => 'bananas'
changera l'URL de vos points de terminaison en wp/v2/bananas
. Notez que vous ne souhaitez pas nommer cette pages
car il existe déjà un noeud final pages
fourni par core.
zen_page
Cela pourrait en fait être mieux si vous utilisiez simplement le type de message page
et une taxonomie personnalisée pour différencier les pages zen_page des pages normales.
L'API REST est conçue pour indiquer pourquoi cela n'a pas fonctionné, par exemple. si j'essaie de visiter wp-json/wp/v2/skjlfnvlkdjfv
j'aurai:
{"code":"rest_no_route","message":"No route was found matching the URL and request method","data":{"status":404}}
et si j'essaie d'utiliser le noeud final wp-json/wp/v2/settings
en mode navigation privée:
{"code":"rest_forbidden","message":"Sorry, you are not allowed to do that.","data":{"status":403}}
L'administrateur AJAX renverra 0
dans tous ces scénarios. Soyez donc reconnaissant, mais faites attention aux messages d'échec ou d'erreur. Ici, nous avons vu que j’essayais de faire une demande à un noeud final qui n’existait pas, puis de nouveau à un noeud final pour lequel je n’avais pas d’autorisation, car j’étais déconnecté.
Grâce à @TomJNowell, j'ai pu utiliser wp_insert_post (), ce qui ne fonctionnerait pas, et mettre à jour mes publications avec la version php de l'API REST.
J'ai dû:
1) Inclure 'show_in_rest' => true
dans l'enregistrement de mon type de message personnalisé.
2) Mettre en file d'attente le script d'assistance: wp_enqueue_script( 'wp-api' );
3) Utilisez ce php pour gérer la demande de publication jQuery
add_action('wp_ajax_update_or_save_zen_page', 'pbfcz_save_zen_page', 99999);
function pbfcz_save_zen_page() {
$pid = $_POST['pid'];
$the_content = sanitize_post_field ('post_content', $_POST['post_content'], $pid);
$the_title = sanitize_text_field ( $_POST['post_title'] );
$the_content = str_replace('\"', '"', $the_content);
$_rest = new WP_REST_Request('PUT', '/wp/v2/zen_page/' . $pid);
$_rest->set_param( 'title', $the_title);
$_rest->set_param( 'status', 'publish');
$_rest->set_param( 'content', $the_content);
$response = rest_do_request($_rest);
echo 'done';
wp_die(); // do not remove
}
Mon jQuery n'a pas beaucoup changé par rapport à la question initiale, publiant ici pour plus de clarté:
jQuery.ajax({
url: ajaxurl,
method: 'POST',
data : {
post_content : new_content,
post_title : jQuery('#title').val(),
pid : post_id,
action : "update_or_save_zen_page"
} ,
success : function(data, textStatus, XMLHttpRequest) {
//console.log(data);
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
alert("An unknown error has occurred and the ajax request to create/update the post has failed.");
}
});