J'utilise la fonction $http
d'AngularJS pour envoyer ma charge utile au sous-système admin-ajax.php
de WordPress, mais il semble que ce dernier accepte uniquement les données x-www-form-urlencoded
, au lieu du application/json
fourni par Angular.
Je sais il y a moyen de rendre la fonction $ http plus semblable à $.post()
, mais cela n'a aucun sens - pourquoi transformer un tas de données JSON en un formulaire alors que c'est déjà JSON?
À cette fin - est-il possible d'indiquer à admin-ajax
de saisir le type en tant que application/JSON
au lieu de x-www-form-urlencoded
?
il semble que ce dernier accepte uniquement x-www-form-urlencoded
Ce n'est pas complètement vrai.
WordPress admin-ajax.php
prend l'action à partir de $_REQUEST['action']
et $_REQUEST
est égal à:
array_merge($_POST, $_GET);
Mais ce que beaucoup de gens ne réalisent pas, c’est que $_GET
dans PHP est not les données ont été envoyées à la page à l’aide de la méthode HTTP GET. En fait, vous pouvez utiliser n’importe quelle méthode HTTP (POST, PUT, DELETE ...) et quel que soit le type de contenu, et $_GET
contiendra toujours les données que vous transmettez à la chaîne de requête url.
Cela signifie que si vous envoyez une demande à wp-admin/admin-ajax.php?action=awesome_action
"awesome_action" est toujours atteinte, quelle que soit la méthode HTTP utilisée et le type de contenu HTTP utilisé.
En bref, si vous pouvez envoyer l'argument action avec l'URL, vous pouvez utiliser admin-ajax.php
pour envoyer toutes les données JSON et toute méthode HTTP, alors votre problème les traite.
Cependant, c'est assez facile d'utiliser php://input
stream.
Tout d'abord, je vais écrire une fonction qui utilise curl pour envoyer une requête HTTP avec un type de contenu JSON (car je ne veux pas écrire du code Angular ici):
/**
* @param string $url Url for for the request
* @param string $data JSON-encoded data to send
*/
function mySendJson($url, $data)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT"); // PUT HTTP method
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json', // JSON content type
'Content-Length: ' . strlen($data))
);
return curl_exec($ch);
}
Plutôt facile.
Maintenant, juste à des fins de test, je vais mettre une fonction dans le pied de page frontal qui envoie une requête HTTP avec un type de contenu JSON en utilisant la fonction ci-dessus, et attend un retour de JSON:
add_action('wp_footer', function() {
$ajax_url = admin_url('admin-ajax.php?action=json-test');
// some dummy json data
$data = array("name" => "Giuseppe", "country" => "Italy");
$json = json_encode($data);
// Using curl we simulate send HTTP request with json content type
// in your case is Angular that perform the request
$json_response = mySendJson($ajax_url, $json);
echo '<pre>';
print_r(json_decode($json_response, true));
echo '</pre>';
});
Désormais, lorsque admin-ajax.php
sera demandé, il recherchera tout rappel associé à 'wp_ajax_json-test'
hook (ou 'wp_ajax_nopriv_json-test'
) pour les utilisateurs non connectés.
Ajoutons une fonction personnalisée à ces points:
add_action('wp_ajax_json-test', 'myWpAjaxTest');
add_action('wp_ajax_nopriv_json-test', 'myWpAjaxTest');
La fonction myWpAjaxTest()
sera appelée par WordPress lorsque la requête HTTP avec le type de contenu JSON sera envoyée à admin-ajax.php
.
Ecrivons le:
function myWpAjaxTest() {
// Retrieve HTTP method
$method = filter_input(INPUT_SERVER, 'REQUEST_METHOD', FILTER_SANITIZE_STRING);
// Retrieve JSON payload
$data = json_decode(file_get_contents('php://input'));
// do something intersting with data,
// maybe something different depending on HTTP method
wp_send_json(array( // send JSON back
'method' => $method,
'data_received' => $data
));
}
Merci à php://input
( docs ) dernière fonction
admin-ajax.php
wp_send_json
utilise le type de contenu json )Comme résultat final, si vous regardez le pied de page du thème, vous trouverez quelque chose comme:
Array
(
[method] => PUT
[data_received] => Array
(
[name] => Giuseppe
[country] => Italy
)
)
admin-ajax.php
a été conçu pour fonctionner avec jQuery. Si vous ne convertissez pas le site JS, vous devrez le faire côté serveur pour que cela fonctionne. Au lieu de cela, vous pouvez ajouter votre propre "point final" pouvant traiter json. Le plus gros problème de cette approche est la requête selon laquelle WP s'exécute sur des URL "front-end".