Cómo crear petición Ajax en un módulo de Prestashop

Cómo crear petición Ajax en un módulo de Prestashop

5/5 (3)

Aprende a crear de forma fácil una petición en ajax desde el Backoffice de tu Prestashop a través de un módulo.

Para hacer una petición ajax desde tu módulo vamos a necesitar 4 archivos básicos:

  • La base del módulo (nombremodulo.php)
  • El archivo .js dónde habrá la función ajax
  • El archivo ajax.php
  • Una plantilla .tpl para asignar la variable de la url del ajax

Vídeo explicativo

Añadir el archivo JS

Empecemos a programar nuestro módulo. Para ello vamos a instalar el módulo en el hook “backOfficeHeader”. El cuál vamos a utilizar para añadir el archivo .js

public function install()
{
    if (!parent::install() | !$this->registerHook('backOfficeHeader')) {
        return false;
    }
    return true;
}

En el hook displayBackOfficeHeader vamos a hacer uso de la herramienta addJS() para añadir el .js pero lo limitaremos a que sólo se use en nuestro módulo con un if() muy sencillo que mirará si se está editando nuestro módulo. De esta forma nos ahorramos posibles problemas de compatibilidad en otras partes de nuestro backoffice.

public function HookBackOfficeHeader($params)
{
    if (Tools::getValue('configure') == $this->name) {
        $this->context->controller->addJquery();
        $this->context->controller->addJS($this->local_path.'/views/js/admin.js');
    }
}

Asignar la url del ajax

En este caso, como es un módulo muy sencillo, sólo vamos a utilizar la función getContent() para asignar la plantilla .tpl que queremos usar y dónde vamos a poner la variable url_ajax para poder usarla en el .js

Para crear la url del ajax vamos a utilizar la función getBaseURL de la clase shop para encontrar la url de la tienda y poder localizar el archivo sin problemas.

Añadiremos seguridad al ajax mediante un token. Para hacer el token usamos la función encrypt de la clase Tools. Tools::encrypt(‘texto_a_encriptar’). Luego, en el ajax compararemos si el token que pasamos es el mismo que el encriptado para poder proceder a ejecutarlo sin problemas.

public function getContent()
{
    $shop = new Shop((int)$this->context->shop->id);
    $base_url = $shop->getBaseURL();
    $ajax = $base_url.'modules/'.$this->name.'/ajax.php?token='.Tools::encrypt($this->name.'/ajax.php');
    $this->context->smarty->assign(array(
        'url_ajax' => $ajax
    ));
    return $this->context->smarty->fetch($this->local_path.'views/templates/admin/admin.tpl');
}

Ahora, cuando vayamos a configurar el módulo se abrirá la plantilla admin.tpl con dónde podremos usar la variable ‘url_ajax’.

Como en este caso vamos a usarla dentro de un script de .js vamos a escribir la $url_ajax dentro de un script para que pueda utilizarlo más adelante el .js

<script>
    const url_ajax = "{$url_ajax|escape:'html':'UTF-8'}";
</script>

Cuando ejecutemos el ajax ya podremos usar la variable url_ajax desde el .js porque ya tendremos definida la constante url_ajax previamente.

Para completar el archivo admin.tpl vamos a crear la entrada de texto #search y el campo de resultado #result para interactuar con ellos a través del ajax más adelante.

<div class="panel container">
    <div class="panel-heading"><i class="icon-search"></i> {l s='Busca un producto' mod='uritestmodule'}</div>
    <div class="row">
        <input type="text" id="search" class="form-control" placeholder="{l s='Search' mod='uritestmodule'}"/>
        <table class="table">
            <thead>
                <tr>
                    <th>{l s='ID Producto' mod='uritestmodule'}</th>
                    <th>{l s='Nombre' mod='uritestmodule'}</th>
                </tr>
            </thead>
            <tbody id="result"></tbody>
        </table>
    </div>
</div>

Crear el script de Ajax

Para crear el script, lo que haremos será hacer un trigger de keyup en la entrada, en este caso, #search. Que será el campo de búsqueda de nuestro archivo.

Así, cada vez que se levante la tecla del teclado dentro del campo #search vamos a ejecutar la función searchProduct() de nuestro .js

$(document).ready(function(){
    $('#search').on('keyup', function(){
        searchProduct();
    })
})

En la función searchProduct() lo que haremos será coger el contenido del campo #search y se lo pasaremos como data a través de un $.ajax(). Este ajax será tipo POST, los datos serán json y la url será la constante antes creada llamada url_ajax.

function searchProduct(){
    var res = '';
    var buscar = $('#search').val();
    if (buscar.length > 0) {
        $.ajax({
            type: "POST",
            url: url_ajax,
            data: {'search' : buscar},
            dataType: "json",
            success: function(response){
                $.each(response, function(i, v) {
                    res += ''+v.id_product+''+v.name+'';
                })
                $('#result').html(res);
            },
        });
    } else {
        $('#result').html('');        
    }
}

Com ves, una vez tengamos respuesta, vamos a coger el id_product y name de la respuesta y lo añadiremos a la tabla #result.

La petición ajax

Desde el .js ya se abre el archivo ajax.php. Pero… ¿Qué hace el archivo?

Primero de todo, como es un archivo .php que no tiene nada que ver con el módulo ni con ningún controlador o clase de prestashop vamos a tener que vincular las funciones de Prestashop al archivo a través de estas dos líneas:

include(dirname(__FILE__).'/../../config/config.inc.php');
include(dirname(__FILE__).'/../../init.php');

Ahora ya podemos hacer uso de las funciones de Prestashop y sus controladores, objetos y clases.

Lo primero será comprobar si el token que recibimos es el mismo que el que hemos definido anteriormente. Además, comprobaremos si el módulo está instalado. En caso que esto no se cumpla, que devuelva un die() para que no siga ejecutando nada más.

$module_name = 'uritestmodule';

$token = pSQL(Tools::encrypt($module_name.'/ajax.php'));
$token_url = pSQL(Tools::getValue('token'));

if ($token != $token_url || !Module::isInstalled($module_name)) {
    die('Error al ejecutar el ajax');
}

Desde el ajax no es demasiado bueno, por temas de seguridad, tener funciones. Ya que puedes tener el módulo desactivado y aún así seguir ejecutándose de igual manera.

Lo que haremos será llamar al módulo a través de la función Module::getInstanceByName(‘nombredelmodulo’) para recibir el objeto módulo y poder hacer uso de sus características y funciones.

En este caso querremos escribir en la página el resultado en formato json de la función searchProducts($search) definida en nuestro archivo principal del módulo.

$module = Module::getInstanceByName($module_name);
if ($module->active) {
	$search = pSQL(Tools::getValue('search'));
    if ($search != '') {
        echo json_encode($module->searchProducts($search));
    }
}

La función del ajax en nuestro módulo

Vamos a crear la función searchProducts($search) dentro de nuestro módulo para poder usarla en el ajax antes creado.

public function searchProducts($search)
{
    $search = str_replace(' ', '%', $search);
    return Db::getInstance()->executeS('SELECT id_product, `name`
        FROM '._DB_PREFIX_.'product_lang
        WHERE id_lang = '.(int)$this->context->language->id.'
        AND `name` LIKE "%'.$search.'%"');
}

Com ves, lo que hace es seleccionar el id_product y el name de la tabla ps_product_lang dónde el id_lang sea el actual del contexto y donde el nombre sea LIKE (parecido) a lo que le hemos pasado desde el ajax.

Resultado final

Si quieres descargar el módulo de ejemplo puedes hacerlo desde este enlace.

Valoración de la Información

8 comentarios

  1. Hmm is anyone else having problems with the pictures on this blog loading?

    I’m trying to figure out if its a problem on my end or if it’s
    the blog. Any suggestions would be greatly appreciated.

  2. I was curious if you ever considered changing the layout of your blog?
    Its very well written; I love what youve got to say. But maybe you could a
    little more in the way of content so people
    could connect with it better. Youve got an awful
    lot of text for only having one or two pictures. Maybe you could space it out better?

  3. We are a bunch of volunteers and starting a new scheme in our community.
    Your site offered us with helpful information to work on. You’ve performed a formidable job and our whole group can be thankful
    to you.

  4. Do you have a spam issue on this site; I also am a blogger, and I was wondering your situation; many
    of us have developed some nice practices and we are looking to trade solutions with others, please shoot me an email if interested.

  5. What i don’t understood is in truth how you’re now not really much
    more smartly-favored than you might be right now. You are so intelligent.
    You recognize thus considerably with regards
    to this topic, made me individually believe it from a lot of numerous angles.
    Its like men and women are not interested until it is one
    thing to do with Girl gaga! Your personal stuffs
    nice. Always care for it up!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *