Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prestashop - REST endpoints for my module

I'm developing Prestashop module, it will export customer data and orders, it will contain hooks for customer synchronization, cart and order events - generally module which will be an integration with CRM-like service.

My module contains it's own views, made in vue.js - single page, async. There are register, login, settings, etc. pages. Communication with backend is made by GET/POST requests on {baseUrl}/mymodule/actionname routes and simple json responses which vue views depend on. Simply I need to create REST endpoints for my module, something like examples below.

Wordpress custom RestApi:

class RestApi
{
    public function __construct()
    {
        add_action('rest_api_init', array(get_class($this), 
        'register_endpoints'));
    }

    public static function register_endpoints()
    {
        register_rest_route('mymodule', '/login', array(
            'methods' => WP_REST_Server::CREATABLE,
            'callback' => array('RestApi', 'login' ),
        ));
    }
}

SugarCRM custom RestApi:

class ModuleRestApi extends SugarApi
{
    public function registerApiRest()
    {
        return [
            'moduleLogin' => [
                'reqType' => 'POST',
                'noLoginRequired' => true,
                'path' => [
                    'mymodule', 'login'
                ],
                'method' => 'login'
            ],
        ];
    }
}

I cannot find similar solution in PrestaShop, there is no word about custom endpoints in presta docs, I tried to use FrontModuleControllers with friendly url's but it doesn't seem to work for me, it throws a lot of stuff in response which is useless for me and when I try to override init() method it requires a lot of stuff too to actually initiate the controller. I need simple REST solution where I can put logic for recieving data from my views, pass it to my CRM service and return json responses to my views. I don't need any more templates or views rendering, just routing for cummunication.

like image 528
maciey_b Avatar asked Dec 23 '22 07:12

maciey_b


1 Answers

PrestaShop doesn't support this out of the box. You can however do it with a module and front controllers.

This is a basic example of doing it.

1. Module to register friendly URLs

class RestApiModule extends Module
{
    public function __construct() 
    {
        $this->name = 'restapimodule';
        $this->tab = 'front_office_features';
        $this->version = '1.0';

        parent::__construct();
    }

    public function install() 
    {
        return parent::install() && $this->registerHook('moduleRoutes');
    }

    public function hookModuleRoutes()
    {
        return [
            'module-restapimodule-login' => [
                'rule' => 'restapimodule/login',
                'keywords' => [],
                'controller' => 'login',
                'params' => [
                    'fc' => 'module',
                    'module' => 'restapimodule'
                ] 
            ]              
        ];
    }
}

2. Create an abstract REST controller

Create an abstract controller so that actual endpoints can extend from it. Create it in your module controllers folder lets name it AbstractRestController.php

abstract class AbstractRestController extends ModuleFrontController
{
    public function init() 
    {
        parent::init();
        switch ($_SERVER['REQUEST_METHOD']) {
            case 'GET':
                $this->processGetRequest();
                break;
            case 'POST':
                $this->processPostRequest();
                break;
            case 'PATCH': // you can also separate these into their own methods
            case 'PUT':
                $this->processPutRequest();
                break;
            case 'DELETE':
                $this->processDeleteRequest();
                break;
            default:
                // throw some error or whatever
        }
    }

    abstract protected function processGetRequest();
    abstract protected function processPostRequest();
    abstract protected function processPutRequest();
    abstract protected function processDeleteRequest();
}

3. Create an actual front controller

Create the front controller in your module controllers/front folder and name it login.php.

require_once __DIR__ . '/../AbstractRestController.php';

class RestApiModuleLoginModuleFrontController extends AbstractRestController
{
    protected function processGetRequest()
    {
        // do something then output the result
        $this->ajaxDie(json_encode([
            'success' => true,
            'operation' => 'get'
        ]));
    }

    protected function processPostRequest()
    {
        // do something then output the result
        $this->ajaxDie(json_encode([
            'success' => true,
            'operation' => 'post'
        ]));
    }

    protected function processPutRequest()
    {
        // do something then output the result
        $this->ajaxDie(json_encode([
            'success' => true,
            'operation' => 'put'
        ]));
    }

    protected function processDeleteRequest()
    {
        // do something then output the result
        $this->ajaxDie(json_encode([
            'success' => true,
            'operation' => 'delete'
        ]));
    }
}

Install the module and now you can hit http://example.com/restapimodule/login and depending on the request type it's going to do whatever you want and you get back JSON response.

To add more endpoints add another module-restapimodule-endpointname entry into hookModuleRoutes array and a front controller that extends from AbstractRestController.

If you also want proper response codes etc. you're going to have to set headers with native php functions as PrestaShop afaik doesn't have any utilities to do it for you or use some kind of library.

Same goes for any other headers you might want to set such as content-type (by default it is text/html).

like image 187
TheDrot Avatar answered Dec 31 '22 13:12

TheDrot