Routing ajax requests the correct way in your Prestashop modules

While working on a client website recently, I ran into a strange issue concerning ajax requests in custom modules and Prestashop cookies. The problem was that any Prestashop urls in the store which did not contain the language as a path element in the url would generate a different default Prestashop cookie, in essence, disregarding language and currency selections made by the user.

While the issue was related to the way cookie’s were being set, it forced me to take a second look at the way I was routing my module ajax requests and consequently discovered a more sound way of doing so.

Originally, I simply created a standalone file called ajax.php in my module folder which would be requested by some jQuery code. Here’s the content of my ajax.php which would bootstrap Prestashop along with an instance of my module which would then become responsible for additional routing and processing:

include(dirname(__FILE__).'/../../config/config.inc.php');
include(dirname(__FILE__).'/../../init.php');
include_once(_PS_MODULE_DIR_.'/deliverydateswizardpro/lib/bootstrap.php');

$module = Module::getInstanceByName('deliverydateswizardpro');

$module->handleAjaxRequest();

The stand alone ajax file works well enough, however the Prestashop way to do this is to create a front end module controller and route your ajax requests through that. So let’s go ahead and build this.

The first thing we need to do is to create our front end ajax controller for our module. Create a file such as “ajax.php” in the folder:
/modules/your_module/controllers/front/

The above illustrates where you need to create the controller file. I have chosen ajax.php as the name of the controller. We make a note of this as we’ll need it in the nest step.

Open up the blank file you have just created and paste the following code:

<?php
class MycustommoduleAjaxModuleFrontController extends ModuleFrontController
{

	public function initContent()
	{
		$this->ajax = true;
		// your code here
		parent::initContent();
	}
}

So what does this do? We’ve declared a class here which extends the ModuleFrontController class which will inherit some ajax behaviour too for us to utilize. In the initContent() method, we added the following line:

$this->ajax = true;

This ensures Prestashop will return only the content you output in this controller. Without setting this property Prestashop would return a fully rendered page (with header, left / right columns etc) which is probably not what you’re looking for.

What about that long class name?

MycustommoduleAjaxModuleFrontController

The class name can be broken down in to 3 components:

Your module name, of which only the first character should be capitalized.
Your controller name, we chose “Ajax”, which comes next in the class name
And the final part is always the same and should be “ModuleFrontController”

You can do any processing for your module in the initContent method and echo out the content which will be returned to your front end javascript.

Another interesting point to note that is that you can declare a method called displayAjax() in your controller which Prestashop will automatically invoke to fetch your ajax content. If you wish to pursue this approach, our controller in ajax.php would now look like:

class MycustommoduleAjaxModuleFrontController extends ModuleFrontController
{

	public function initContent()
	{
		$this->ajax = true;
		parent::initContent();
	}

	public function displayAjax()
	{
		die(Tools::jsonEncode(array('result' => "test")));
	}
}

So far so good. The only obstacle facing us now is to ensure our javascript / jQuery is capable of routing to our new module controller via the correct url. You can add the following javascript in your module templates to connect to the module controller.

var url = "{$link->getModuleLink('mycustommodule', 'ajax', array())}";

$.ajax({
	type: 'POST',
	url: url,
	cache: false,
	data: {
		method : 'test',
		ajax: true
	},
	success: function (result) {
		console.log(result);
	}
});

We ask Prestashop to give us the module controller url in the following line of code:

{$link->getModuleLink('mycustommodule', 'ajax', array())}

The first parameter is the name of the module (mycustomodule) and the second is the controller name (ajax in our case)

The jQuery code above is now capable of routing to your module front controller from which you can build more complex logic and handle the request response appropriate to your project.

This concludes this tutorial on how to route Ajax requests in your module the Prestashop way. If you found this article helpful, share it or leave a comment.

Leave a Reply

Your email address will not be published. Required fields are marked *