3
votes

I create a module for PrestaShop 1.6 where I create a table as following in mymodule/mymodule.php:

class Mymodule extends Module {

    // Some code

    public function installDb() {
        return Db::getInstance()->execute("
        CREATE TABLE IF NOT EXISTS `" . _DB_PREFIX_ . "mytable`(
        `id_mdm` INT NOT NULL AUTO_INCREMENT,
        `id_category` INT NOT NULL,
        `service` INT NOT NULL,
        `title` VARCHAR(300) NOT NULL default '',
        `title_font_size` VARCHAR(128) NOT NULL default '',
        `title_color` VARCHAR(128) NOT NULL default '',
        `background_color` VARCHAR(128) NOT NULL default '',
        `border_style` VARCHAR(128) NOT NULL default '',
        `position` INT NOT NULL,
        `count` INT NOT NULL,
        PRIMARY KEY (`id_mdm`), UNIQUE (`id_category`)) ENGINE = InnoDB;");
    }

    // Some code

}

It works fine, my table is created. Then I override webservice in mymodule/override/classes/webservice/WebserviceRequest.php:

class WebserviceRequest extends WebserviceRequestCore {
    public static function getResources() {
        $resources = parent::getResources();
        $resources['myresource'] = array(
            'description' => '',
            'class' => 'myresource'
        );
        ksort($resources);
        return $resources;
    }
}

I create a new class called myresource in mymodule/override/classes/Myresource.php:

class MyresourceCore extends ObjectModel {
    public $id;
    public $id_mdm;
    public $id_category;
    public $service;
    public $title;
    public $title_font_size;
    public $title_color;
    public $background_color;
    public $border_style;
    public $position;
    public $count;

    public static $definition = array(
        'table' => 'mytable',
        'primary' => 'id_mdm',
        'fields' => array(
            'id_category' => array('type' => self::TYPE_INT),
            'service' => array('type' => self::TYPE_INT),
            'title' => array('type' => self::TYPE_STRING),
            'title_font_size' => array('type' => self::TYPE_STRING),
            'title_color' => array('type' => self::TYPE_STRING),
            'background_color' => array('type' => self::TYPE_STRING),
            'border_style' => array('type' => self::TYPE_STRING),
            'position' => array('type' => self::TYPE_INT),
            'count' => array('type' => self::TYPE_INT)
        )
    );

    protected $webserviceParameters = array();
}

In the Back office I generate a key for myresource, but when I test in my browser http://mydomain/api/myresource?ws_key=mykey, there is the following error:

Fatal error: Class 'myresource' not found in /path/mydomain/classes/webservice/WebserviceRequest.php on line 502

I don't know why PrestaShop doesn't detect it. Thank you in advance for your assistance.

3
Have you tried reinstalling the module after you created the override so the override is copied to the override/classes/webservice/WebserviceRequest.php? Also check the if your override is the path for the class in cache/class_index.php. The WebserviceRequest should have the path as override/classes/webservice/WebserviceRequest.php. You can also delete this file to recreate it. - sadlyblue
Yes I tried reinstalling it, but nothing changes. WebserviceRequest.php is effectively copied to override/classes/webservice/. I also delete cache/class_index.php to trigger the regeneration but it doesn't detect override/classes/Myresource.php - B. Mike
try changing MyresourceCore to Myresource. then recrete the class_index.php. - sadlyblue
I tried it, reinstalled and then delete class_index.php, but there is no change... - B. Mike
Custom classes are not autoloaded. You need to include your Myresource.php file. - TheDrot

3 Answers

2
votes

In Prestashop 1.7, you can use this hook: addWebserviceResources

Example:

include_once dirname(__FILE__) . '/classes/Sample.php';

class myAPISample extends Module {

    // ...

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

    // ...

    public function hookAddWebserviceResources($params) {
         return [ 'samples' => ['description' => 'My sample', 'class' => 'Sample' ] ];
    }

    //...
}

See also (in french) : https://www.h-hennes.fr/blog/2018/06/25/prestashop-ajouter-un-objet-dans-lapi/

1
votes

Finally I found an alternative solution without using the native PrestaShop webservice. I created a directory called webservice in mymodule/webservice/mymodule.php. This file will be used to post data to PrestaShop's website. Here is how I did it:

<?php
$currentDirectory = str_replace('modules/mymodule/webservice/', '', 
dirname($_SERVER['SCRIPT_FILENAME']) . "/");
$sep = DIRECTORY_SEPARATOR;
require_once $currentDirectory . 'config' . $sep . 'config.inc.php';
require_once $currentDirectory . 'init.php';

$hostnameIp = $_SERVER['REMOTE_ADDR'];

if ($hostnameIp == 'AUTHORIZED_IP') {
    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        // Some code
        http_response_code(200);
    } else {
        http_response_code(405);
    }
} else {
    http_response_code(403);
}

Then I just need to execute a POST request to myresource at the following url: http://mydomain/modules/mymodule/webservice/mymodule.php. Be careful to do some validation for security, like IP address. If the validation is successful, then your do some treatment to insert or update data to mysql tables.

1
votes

If you check the PHP error logs, you will notice an error of the type Class not found. In this case it's class "MyResource" not found.

In order to solve this, you need to include your Model class in the constructor of the override method like this

class WebserviceRequest extends WebserviceRequestCore {
    public function __construct()
    {
         include_once(_PS_MODULE_DIR_ . 'myresource' . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . 'MyResource.php');
    }

    public static function getResources()
    {
        $resources = parent::getResources();
        $resources['myresource'] = array(
            'description' => '',
            'class' => 'myresource'
        );
        ksort($resources);
        return $resources;
    }
}

And you need to place the Model Class in /mymodule/classes/MyResource.php

Placing the Model Class in mymodule/override/classes/Myresource.php is not correct cause there is no Myresource class to override. This will give you an error when uninstalling the module - you will not be able to uninstall it