Endpoint PHP personalizado para llamadas AJAX en un plugin

27 jul 2016, 11:57:39
Vistas: 13.6K
Votos: 4

Estoy escribiendo un plugin por primera vez y tengo un problema.

Estoy usando AJAX en mi plugin. Mi archivo JavaScript está en la carpeta ../wp-content/plugins/myplugin/js/, y en él estoy intentando llamar a un archivo PHP que está en la carpeta ../wp-content/plugins/myplugin/

jQuery.ajax({
    url: "/wp-content/plugins/myplugin/myfile.php?myparam=" + myparam,
    context: document.body
});

Mi pregunta es: ¿Cómo puedo hacer que esta referencia URL funcione independientemente de dónde el usuario haya instalado el plugin? Porque cuando, por ejemplo, un usuario instala este plugin en http://localhost/subdir/, la referencia no es correcta. ¿Puedo crear de alguna manera un enlace relativo?

0
Todas las respuestas a la pregunta 3
5

En primer lugar, no deberías llamar a tu propio archivo PHP. Debes usar el endpoint admin-ajax. Documentación

En el lado del administrador, podrías usar ajaxurl para obtener la URL para llamadas AJAX. En el frontend debes declarar tú mismo la variable con la URL. Esto está escrito en la documentación:

Nota: A diferencia del lado del administrador, la variable global javascript ajaxurl no se define automáticamente para ti, a menos que tengas BuddyPress o otro plugin que dependa de Ajax instalado. Así que en lugar de depender de una variable global javascript, declara un objeto namespace javascript con su propia propiedad, ajaxurl. También podrías usar wp_localize_script() para hacer que la URL esté disponible para tu script, y generarla usando esta expresión: admin_url( 'admin-ajax.php' )

Esto debería resolver el problema:

add_action( 'wp_head', 'front_ajaxurl' );
function front_ajaxurl() {
    wp_register_script( 'admin_ajax_front', plugin_dir_url(__FILE__) . 'script.js' );
    $translation_array = array(
        'ajaxurl' => admin_url( 'admin-ajax.php' )
    );
    wp_localize_script( 'admin_ajax_front', 'front', $translation_array );
    wp_enqueue_script( 'admin_ajax_font', false, array(), false, true ); // el último parámetro en true hará que el script se encole en el footer
}

Y luego en tu archivo JS:

$.ajax({
    url: front.ajaxurl,
    ...
})
27 jul 2016 12:03:51
Comentarios

Mezclar código JavaScript y PHP no es una buena práctica. Como dice la cita de la documentación, yo optaría por wp_localize_script(). Esto asegura que la variable estará definida antes de que se cargue el script que depende de ella.

David David
27 jul 2016 12:16:36

Incluso mejor que wp_localize_script(), puedes usar wp_add_inline_script() desde WordPress 4.5. Esta función permite imprimir scripts en línea dentro del gran sistema de administración de dependencias de WordPress, y no está limitado solo a un objeto JavaScript como wp_add_inline_script().

cybmeta cybmeta
27 jul 2016 12:25:37

Todavía no lo entiendo... todavía no sé cómo referenciar a myfile.php y dónde ¿Tengo que convertirlo en una función o cómo? Por favor dame una pista, estoy perdido.

user3199063 user3199063
27 jul 2016 14:02:41

Si realmente necesitas llamar un archivo desde tu plugin, podrías hacerlo con plugin_dir_url(__FILE__)

Krzysztof Grabania Krzysztof Grabania
27 jul 2016 14:28:44

Necesito llamar a myfile.php en mi JS como mostré en mi pregunta, por supuesto, para eso necesito AJAX. Tampoco me queda claro si debería poner admin-ajax.php en ajaxurl, o si en su lugar debería poner myfile.php ahí.

user3199063 user3199063
27 jul 2016 15:03:02
0

Soy principiante, pero esto me funcionó

Añade lo siguiente en functions.php. Ten en cuenta que 'wp_ajax' es un prefijo por convención y 'do_something' es el nombre de acción que elegí arbitrariamente:

add_action( 'wp_ajax_do_something', 'do_something' );

function do_something() {
    //en serio, adelante, haz algo
    die("devuelve algo");
}

Para hacer la llamada AJAX desde el navegador (lado del cliente), pude encontrar mi endpoint usando wp.ajax.settings.url. La variable global wp está definida en el objeto window.

//do_something aquí debe coincidir con lo anterior, puedes añadir otros parámetros a este objeto
var data = { action: 'do_something' };
jQuery.post(wp.ajax.settings.url, data, function(response) {
    console.log('Resultado: ' + response);
});

Tengo WordPress 4.6.1 (la última versión al momento de escribir esto) y algunos plugins instalados. Me referí a esta referencia que dice incorrectamente que ajaxurl está definido, pero no es el caso para mí: https://codex.wordpress.org/AJAX_in_Plugins

4 dic 2016 17:38:55
0

Me enfrenté al mismo problema.

Quería usar mi propio endpoint en lugar del endpoint admin-ajax porque tengo reglas de reescritura que proporcionan todas las variables que necesito para ejecutar las acciones ajax.

Por lo tanto, usar (como se menciona en el codex)

jQuery(document).ready(function($) {
    var data = {
        'action': 'mi_accion',
        'whatever': ajax_object.we_value      // ¡Pasamos los valores de PHP de manera diferente!
    };
    jQuery.post(ajax_object.ajax_url, data, function(response) {
        alert('Recibí esto del servidor: ' + response);
    });
});

y

add_action( 'wp_ajax_mi_accion', 'mi_accion' );
add_action( 'wp_ajax_nopriv_mi_accion', 'mi_accion' );

solo hace que mi código sea más complicado.

Terminé haciendo esto y parece funcionar:

    jQuery.ajax({
        type: "post",
        url: MIENDPOINTPERSONALIZADO?ajax_action,
        dataType: 'json',
        ...

combinado con:

    add_action( 'init', 'reglas_de_reescritura');
    add_filter( 'template_include','manejar_accion_ajax');

function reglas_de_reescritura(){
    add_rewrite_tag(
        '%ajax_action%',
        '([^&]+)'
    );
}

function manejar_accion_ajax($plantilla){

    $exito = null;

    // como la variable de consulta "ajax" no requiere un valor, necesitamos verificar su existencia
    if ( !$accion = get_query_var( 'ajax_action' ) ) return $plantilla; //la acción ajax no existe

    $resultado = array(
        'input' =>  $_REQUEST,
        'mensaje'=> null,
        'exito'=> null,
    );

    $exito = ...

    if ( is_wp_error($exito) ){
        $resultado['exito'] = false;
        $resultado['mensaje'] = $exito->get_error_message();

    }else{
        $resultado['exito'] = $exito;
    }

    header('Content-type: application/json');
    send_nosniff_header();
    header('Cache-Control: no-cache');
    header('Pragma: no-cache');

    wp_send_json( $resultado );  

}
10 dic 2018 11:48:09