Jump to content

Extending OrderCore additional field, not inserting to database


contentengineer
 Share

Recommended Posts

Following "best practice" to use overrides on classes, we are extending the OrderCore and the CartCore with an additional field that gets transferred when a new order is created during PaymentModule::validateOrder() using Order::add(). We are unable to use the hookValidateOrder as we are also modifying the order confirmation email with this additional field.

 

Debugging, it appears that Order::add() is not inserting data for the additional field; even thought we have:

(i) Extended the core in the prescribed manner (the same method we use for other class overrides)

(ii) We have cleared  cache/class_index.php after loading the override

 

We have checked the MySQL binary logs and it is not including the additional field in the field list when executing INSERT INTO ps_orders (<field list>) VALUES (<values>).

 

Is there any restriction on extending OrderCore...?

 

Can anybody spot anything strange with this simplest of modifications?

<?php

class Order extends OrderCore
{
  public $addnfield;

  public function __construct($id = null, $id_lang = null)
  {
        self::$definition['fields']['addnfield'] = array('type' => self::TYPE_STRING, 'validate' => 'isString', 'required' => true);

        parent::__construct($id, $id_lang);
  }
}

   

Prestashop 1.6.0.6 

 

Share this post


Link to post
Share on other sites

I had the same situation and this is the solution:

 

Change override of OrderCore to:

 

<?php

Order::$definition['fields']['addnfield'] = array('type' => self::TYPE_STRING, 'validate' => 'isString', 'required' => true);

class Order extends OrderCore
{

public $addnfield;

public function __construct($id = null, $id_lang = null)
 {
    parent::__construct($id, $id_lang);

//place any other initialization here, like $this->addnfield = 'Something';
 }
}
Edited by cristic (see edit history)

Share this post


Link to post
Share on other sites

Thanks for the quick response/hint to a solution.  This is an interesting workaround, and only appears to happen with the override of OrderCore. I'm presuming it's because OrderCore overrides getFields() and add() in ObjectModel.

 

Our final fix was:

<?php

Order::$definition['fields']['addnfield'] = array('type' => ObjectModel::TYPE_STRING, 'validate' => 'isString', 'required' => true);

class Order extends OrderCore
{

public $addnfield;

public function __construct($id = null, $id_lang = null)
 {
    parent::__construct($id, $id_lang);

 }
}

Many thanks.

Share this post


Link to post
Share on other sites

Yes, I should have changed that too (copy/paste habit). self::TYPE_STRING is not valid outside class and ObjectModel::TYPE_STRING should be used instead.

 

If you don't have any code in __construct function (except calling parent::__construct), you can remove the function from the overriding class.

Share this post


Link to post
Share on other sites

  • 2 weeks later...

As an observation we have been running with the Order::$definition{'fields']..... prefix to the extension of the Core class OrderCore.php  but today hit on a problem.

PHP Fatal error: Class 'Order' not found in /var/www/html/override/classes/order/O 
rder.php on line

One thought was to try:   OrderCore::$definition...

OR

Another thought was to try overriding the function   getFields() as well as __construct

 

There seem to be three schools of thought on overriding OrderCore (all require an additional property to be defined)

 

(1) Override __construct(), adding the newfield/validation to $definition, then calling parent::__construct()

 

(2) Override  getFields(), adding the newfield definition loosely and mapping to pSQL($newfield), then calling parent::getFields()

 

OR

 

(3) Add a prefix  Order::$definition['fields']['newfield'] = array('type' => ObjectModel::TYPE_STRING, 'validate' => 'isString', 'size' => 30);

 

Any thoughts on why #1 fails/is unreliable or #3 has Class not found errors?

Share this post


Link to post
Share on other sites

 

As an observation we have been running with the Order::$definition{'fields']..... prefix to the extension of the Core class OrderCore.php  but today hit on a problem.

PHP Fatal error: Class 'Order' not found in /var/www/html/override/classes/order/O

rder

.php on line

 

You are saying this problem appeared today. But until now it worked? 

I am asking this because I am using 3rd option myself and works very well.

 

Check the call stack and see from where the override Order.php file is called...

Share this post


Link to post
Share on other sites

This production system has not had any changes recently. Possible coincidence, but the problem appeared today immediately after a particular user insisted on making multiple searches in quick succession, each returning 1000's of products. I'm thinking that (perhaps) a cache was invalidated - and this caused a problem with the autoloader?

Share this post


Link to post
Share on other sites

  • 5 months later...

Hi, sorry to post in a 5-months old thread, but i have exactly the same issue after upgrading a perfectly working module from 1.5 to 1.6 : the field added is not always updated in the database, only sometimes (the field is updated in 2 different hooks by the same function, but only one of the $order->save() actually saves it to the database...

 

Implementing the 3rd of the three solutions you give seems to work (the 1st is the one I had that doesn't work every time), did you experience any other class not found issue with it? Finally fixed it by overriding getFields() maybe? If fixed, could you please explain how briefly?

 

Hoping you have mail alerts on forum threads: Thank you !

Share this post


Link to post
Share on other sites

  • 6 months later...
  • 1 year later...

 

I had the same situation and this is the solution:

 

Change override of OrderCore to:

 

<?php

Order::$definition['fields']['addnfield'] = array('type' => self::TYPE_STRING, 'validate' => 'isString', 'required' => true);

class Order extends OrderCore
{

public $addnfield;

public function __construct($id = null, $id_lang = null)
 {
    parent::__construct($id, $id_lang);

//place any other initialization here, like $this->addnfield = 'Something';
 }
}

 

This thread was very, very helpful, but cristic's solution (although highly enlightening) was incorrect. If you place the initialization of the added variable after the parent construct, you overwrite loaded values. Also, it's doesn't compile.

contentengineer's solution worked from me, with the addition of variable initialization during declaration.

 

I still don't understand WHY there was a problem (I was as confused as contentengineer), but cristic and contentengineer solved the problem for me. Thanks!

Share this post


Link to post
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
 Share

×
×
  • Create New...

Important Information

Cookies ensure the smooth running of our services. Using these, you accept the use of cookies. Learn More