Usando Ajax en WordPress para enviar correo

6 minutos de lectura

avatar de usuario
majo0od

Estoy tratando de usar Ajax para enviar un correo electrónico a través de un formulario web que creé, pero estoy perdido. No tengo idea de cómo funciona Ajax en WordPress.

Primero creé una acción

add_action( 'wp_ajax_siteWideMessage', 'wpse_sendmail' );

La función que se supone que recupera los datos y envía el correo es:

function wpse_sendmail()
{
    $for = like_escape($_POST['forwhat']);
    $email = like_escape($_POST['email']);
    $headers="From: ".$email ."\r\n".'Reply-To: '.$email;
    $message = like_escape($_POST['message_message']);
    $respond = like_escape($_POST['message_email']);

    wp_mail( "support@ontrgt.net", "(OTN) Support: ".$support, $message, $headers); 
}

Finalmente, el js es así:

$("#contact-send").click(function(){
    var forwhat = $("#contact-for").val();
    var name = $("#contact-name").val();
    var email = $("#contact-email").val();

    $.post( "<?php echo esc_js( site_url() ) ?>", { siteWideMessage:"null", forwhat: forwhat, name: name, email:email }, function(){
            console.log("success");
    });
});

No estoy muy seguro de lo que me estoy perdiendo aquí. ¿Alguien puede ayudarme a entender el proceso Ajax de WordPress?


ACTUALIZAR

Actualicé mi código a esto hasta ahora:

PHP

add_action( 'wp_ajax_siteWideMessage', 'wpse_sendmail' );
add_action( 'wp_ajax_nopriv_siteWideMessage', 'wpse_sendmail' );

function wpse_sendmail()
{
    $for = $_POST['forwhat'];
    $email = $_POST['email'];
    $headers="From: ".$email ."\r\n".'Reply-To: '.$email;
    $message = $_POST['message_message'];
    $respond = $_POST['message_email'];

    /*if(wp_mail( "support@ontrgt.net", "(OTN) Support: ".$for, $message, $headers))
    {
        echo "WOOHOO";
    }*/

    if($for)
    {
        //Just to see if there is any response.
        echo "Whoohoo";
    }

    die();
}

js

$("#contact-send").click(function(){
    var forwhat = $("#contact-for").val();
    var name = $("#contact-name").val();
    var email = $("#contact-email").val();

    var data = { action:'siteWideMessage', forwhat:forwhat, name:name, email:email };
    $.post('<?php echo admin_url("admin-ajax.php"); ?>', data, function(response) {
        alert(response);
    });
});

WordPress todavía no responde con mi comando AJAX. Estoy usando el elemento de inspección y no veo que se transmitan datos.

  • Debería ser action: 'siteWideMessage' y el url necesita ser para /wp-admin/admin-ajax.php

    – Oh Dios por qué

    4 de octubre de 2014 a las 1:57

  • y donde lo hizo $support vino de todos modos

    –Kevin

    4 oct 2014 a las 2:00

  • que pasa like_escape ? Eso fue usado para escapar de sql

    – buen culo

    4 de octubre de 2014 a las 2:29

avatar de usuario
el alfa

Al principio, debe agregar dos acciones, una para el usuario que no ha iniciado sesión y que se requiere explícitamente para que funcione, por ejemplo, algo como esto (básicamente en su functions.php expediente):

add_action( 'wp_ajax_siteWideMessage', 'wpse_sendmail' );
add_action( 'wp_ajax_nopriv_siteWideMessage', 'wpse_sendmail' );

Luego, debe realizar la solicitud al admin-ajax.php así que en el jQuery función, puede usar algo como esto:

$("#contact-send").click(function(e){

    e.preventDefault(); // if the clicked element is a link

    //...

    var data = { 'action':'siteWideMessage', 'more':'values' };

    $.post('<?php echo admin_url('admin-ajax.php'); ?>', data, function(response) {
        console.log(response);
    });

});

Asegúrate de poner exit/die al final de tu handler en el lado del servidor, por ejemplo:

function wpse_sendmail()
{
    // Process the post data...
    
    if(wp_mail(...)) {
        echo 'success';
    }
    else {
        echo 'failed';
    }

    die();
}

En tus success devolución de llamada, el response variable obtendrá la respuesta enviada desde el lado del servidor, es decir success/failed. Hay mejores maneras de hacer esto (usando wp_localize_script etc). Leer este artículo detallado. Además, si desea devolver un json respuesta entonces puede usar $.json('url', data, func).

Si está confundido, déjeme decirle que debe hacer la solicitud a admin-ajax.php y pasar el action con la solicitud y en este caso es siteWideMessageasi que WordPress llamará al handler eso está registrado usando add_action gancho y en tu caso es wpse_sendmail.Eid Mubarak 🙂

  • ¿Puso el código dentro $("#contact-send").click(function(){...});

    – El Alfa

    06/10/2014 a las 17:28

  • Poner console.log('clicked') dentro del controlador de clic antes e.preventDefault() para asegurarse de que está activando el controlador y también verifique la consola en busca de otros errores.

    – El Alfa

    7 de octubre de 2014 a las 1:15

  • Creo que sé cuál es el problema. No puede acceder al enlace admin-ajax.php. Mi JS está en un archivo JS, no en el mismo archivo que mis funciones php.

    – Majood

    7 oct 2014 a las 12:16

  • Así que hice un poco más de prueba. El sitio está respondiendo con el HTML de la página con el console.log(response); No estoy muy seguro de lo que eso significa.

    – Majood

    7 oct 2014 a las 12:40

  • lo que obtienes como HTML ? los echo debe ser la respuesta.

    – El Alfa

    7 oct 2014 a las 13:53

Tuve que hacer algo ligeramente diferente para que esto funcionara.

Primero agregué una entrada oculta en mi página de plantilla y le di el valor de la URL de ajax de esta manera:

<input type="hidden" id="ajax_url" value="<?php echo admin_url('admin-ajax.php'); ?>"/>

Luego tuve esto en mi functions.php

add_action( 'wp_ajax_siteWideMessage', 'wpse_sendmail' );
add_action( 'wp_ajax_nopriv_siteWideMessage', 'wpse_sendmail' );

function wpse_sendmail() {
  echo "hewwo world";

  die();
}

Y mi js en un archivo js separado como tal:

$("#submit-form").click(function(e){

  e.preventDefault(); // if the clicked element is a link

  $.post($("#ajax_url").val(), {
      action: 'siteWideMessage',
      // and the rest
  }, function(response) {
      // handle a successful response
      console.log(response)
  });

});

Esto funciona para mí.

  • Revisando esto ya que esta solución aún funciona. Deberia ser mas alto. Pasos que tomé para que funcione: coloqué jquery en mi jQuery en la página, el campo Oculto en la página, y lo agregué a Funciones, y funcionó, a diferencia de muchos otros métodos AJAX más largos. Esto funciona para devolver su mensaje de “eco”, lo que significa que ESTÁ activado. 10000% recomendable.

    – Ivandude

    21/09/2021 a las 15:15

Mirando la documentación de wp_ajax_(acción)parece que simplemente necesita configurar el action parámetro a “mensaje de todo el sitio”. Por ejemplo…

$.post(<?= json_encode(admin_url('admin-ajax.php')) ?>, {
    action: 'siteWideMessage',
    // and the rest
}, function(response) {
    // handle a successful response
});

  • Esto realmente no me está haciendo entender la estructura AJAX de WordPress.

    – Majood

    06/10/2014 a las 19:25

Puede hacerlo de la manera wordpress, o puede hacerlo de la manera fácil. Haría un complemento para contener el código de manejo de AJAX.

<?php
/*
Plugin Name: AJAX Receiver
*/


add_action('admin_menu', 'ajax_receiver_menu');
function ajax_receiver_menu() {
    $parent_slug = null; // Child of null, so this menu item has no link to it in the dashboard.
    $menu_title  = "AJAX Receiver menu"; // This menu title will not be visible.
    $page_title  = "AJAX_Receiver"; // No one will visit this page.
    $menu_slug   = 'ajax_receiver'; // This is the last part of the URL you post to.
    $callback    = 'ajax_receiver_menu_content';
    add_submenu_page($parent_slug, $page_title, $menu_title, $capability, $menu_slug, $callback);
}



function ajax_receiver_menu_content() {
    // check request variables, do other logic.
    echo "This is the response to your AJAX request.";
}

Luego, puede enviar una solicitud de publicación normal.

$.post( "/wp-admin/admin.php?page=ajax_receiver", { siteWideMessage:"null", forwhat: forwhat, name: name, email:email }, function(data){
        console.log(data); // You should see "This is the response to your AJAX request." in your console.
});

Definitivamente no es así como “se supone” que debes hacerlo, pero he descubierto que es mucho más fácil trabajar con esto. La parte crítica es que el submenú no sabe si está repitiendo “Esta es la respuesta a su solicitud AJAX” en respuesta a una solicitud AJAX o una solicitud de página normal. De hecho, podría apuntar su navegador a "/wp-admin/admin.php?page=ajax_receiver" y solo vería “Esta es la respuesta a su solicitud AJAX” en texto sin estilo en la parte superior de su pantalla.

¿Ha sido útil esta solución?