contentengineer Posted October 2, 2014 Share Posted October 2, 2014 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 Link to comment Share on other sites More sharing options...
cristic Posted October 2, 2014 Share Posted October 2, 2014 (edited) 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 October 2, 2014 by cristic (see edit history) Link to comment Share on other sites More sharing options...
contentengineer Posted October 3, 2014 Author Share Posted October 3, 2014 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. Link to comment Share on other sites More sharing options...
cristic Posted October 3, 2014 Share Posted October 3, 2014 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. Link to comment Share on other sites More sharing options...
contentengineer Posted October 14, 2014 Author Share Posted October 14, 2014 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? Link to comment Share on other sites More sharing options...
cristic Posted October 14, 2014 Share Posted October 14, 2014 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/Order .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... Link to comment Share on other sites More sharing options...
contentengineer Posted October 14, 2014 Author Share Posted October 14, 2014 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? Link to comment Share on other sites More sharing options...
adastier Posted March 19, 2015 Share Posted March 19, 2015 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 ! Link to comment Share on other sites More sharing options...
LouAdrien Posted October 15, 2015 Share Posted October 15, 2015 Hey guys, your solution worked indeed if I copy it directly into the final override file, but If i put it in my original module override file, these lines don't get copied to the final override file, any idea why?? Link to comment Share on other sites More sharing options...
EdEichman Posted September 27, 2017 Share Posted September 27, 2017 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! Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now