Jump to content

Prestashop 1.7.x module architecture done right, avoid overrides for hooks, ... how to?


Recommended Posts

I created 2 modules, both using an override on the same class ( Customer ) to add DB extra data representation. 
The second module gives me an error because the class is overridden already by the first module. 
Both modules have an "/override/classes/" path. I solved merging all the overrides on the first module and stripping it out form the second.

I noticed that in a modern structure I should avoid overrides for hooks, but how reply the same structure?

My module is pretty easy, it add a new column "mycustom" on costumer table then override the Costumer class to explain the new data to the controller:

/**
 * Override Class CustomerCore
 */
class Customer extends CustomerCore {

    public $mycustom;
     
    public function __construct($id = null){
     
        self::$definition['fields']['mycustom'] = [
            'type' => self::TYPE_STRING,
            'lang' => false,
            'required' => true, 
            'size' => 255,
            'validate' => 'isString'
        ];
        parent::__construct($id);
        
    }
}

I tried (following some tuts) to include the file in my module main class but it doesn't works as expected (err500).

I'm not able to use hooks instead of override and i'm in trouble to find documentation about.

I hope someone can share a code strip/example to let me to understand.

Thanks in advance
Daniele M

Link to comment
Share on other sites

You cannot overide classes from a module. That can only be accomplished in Themes. See: https://devdocs.prestashop.com/1.7/modules/concepts/overrides/

Upon installation of your module, you must copy the overrided class to the /override/... folder, programatically (not advised by the core team). But you cannot guarantee that this permitted for all installations, some Administrators might limit these capabilities.

If the changes are solely required for your module(s) and only used in your module(s) code, you can create an extended class (f.e. Class MyCustomer extends Customer) in your module structure and then use that class in your module.

Alternatively you can try to use hooks (https://devdocs.prestashop.com/1.7/modules/concepts/hooks/list-of-hooks/) and use the DB class to manipulate the database tables directly in relevant After... hooks.

Succes,

Leo

Edited by elburgl69 (see edit history)
Link to comment
Share on other sites

Hello elburgl69,

to use the Hooks paradigm could this be the right direction?

1 - instead override the custome class with its extension I'll include it defining a new class as extension of Customer, using it to manage the "admin side forms"

2 - I need to intercept "actionCustomerAccountAdd" 

3 - get the field value for my custom field (someting like  $mycustom = Tools::getValue('mycustom')

4 - I need to implement my own mysql setter for the mycostum column

could be?

Link to comment
Share on other sites

Implemention with a Hooks:

1. In your Install method, add the collumn to the database. Something like:

public function install()
    {
        if (!parent::install() || !$this->installDB()) {
            return false;
        }
        
        return $this->registerHook('actionCustomerAccountAdd');
    }
    public function installDB()
    {
        $res = (bool) Db::getInstance()->execute('
            UPDATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'customers` (
                ...
            );
        ');
        // any other db operations...
        return $res;
    }

2. Implement the add Hook method like:

public function hookActionCustomerAccountAdd($params)
    {
        // YOur code
    }

3. Think about if update customer  hooks are necessary and implement those if required

4. Implement the hooks used to display the information in the front / back-end and use / cast you MyCustomer class to get the customer. Get the field value for my custom field indeed with someting like  $mycustom = Tools::getValue('mycustom'. Remember to sanitize.

5. Implement an Uninstall method to remove the hook and undo the database changes.

 

An alternative approach would be create a new table for your extra collumn(s) with id_cusomer as key. You then have a one-to-one relation. Extend the customer model like above but now to include you table information. This approach does not change the core database tables.

Rg,

Leo

 

 

 

Edited by elburgl69 (see edit history)
Link to comment
Share on other sites

Thank you so much 😍

I'll try it your suggestion as soon as possible.

 

2 hours ago, elburgl69 said:

An alternative approach would be create a new table for your extra collumn(s) with id_cusomer as key. You then have a one-to-one relation. Extend the customer model like above but now to include you table information. This approach does not change the core database tables.

I evaluated this option. I think it is cleaner and more correct. Because I'm moving my first steps on Prestashop i choose (maybe wrongly) the short way ...

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...