webhoes Posted December 5, 2018 Share Posted December 5, 2018 Hello, I have made a module, but I can't get it to work. I have 2 fields with price (price and rrp). On save I want to calculate the difference in percentage and save it to the discount field. It does not update the field. What am I doing wrong? class UpdateDiscount extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Custom discount updater', 'version' => 1, 'summary' => 'Auto update percentage based on prices.', 'singular' => true, 'autoload' => true, 'icon' => 'money', ); } public function init() { // add a hook after the $pages->save, to issue a notice every time a page is saved $this->pages->addHookAfter('save', $this, 'updateProduct'); } /** * Example1 hooks into the pages->save method and displays a notice every time a page is saved * * @param HookEvent $event * */ public function updateProduct($event) { /** @var Page $page*/ $page = $event->arguments[0]; if($page->template != 'product') return; $price = $page->pad_price; $rrp = $page->pad_rrp; $discount = $rrp - $price; $percentage = $discount/$rrp * 100; $page->setAndSave('pad_discount', $percentage); } } Link to comment Share on other sites More sharing options...
elabx Posted December 5, 2018 Share Posted December 5, 2018 I think $event->arguments is a method not an Array/WireArray. EDIT: Also I think you might just want to set your hook before save not after and or you might get into a recursive loop with setAndSave, and just reassign the $page as an argument. $page->pad_discount = $discount; $event->arguments(0, $page); 1 Link to comment Share on other sites More sharing options...
webhoes Posted December 5, 2018 Author Share Posted December 5, 2018 Could not get something working with those changes. After some more searches I came up with this, close to the examples but also still not working. public function init() { // add a hook after the $pages->save, to issue a notice every time a page is saved $this->pages->addHookBefore('save', $this, 'updateProduct'); } /** * Example1 hooks into the pages->save method and displays a notice every time a page is saved * * @param HookEvent $event * */ public function updateProduct($event) { /** @var Page $page */ $page = $event->object; //$page = $event->arguments('page'); if($page->template != 'product') return; $fields = $page->fields; $price = $fields->get('pad_price'); $rrp = $fields->get('pad_rrp'); $discount = $rrp - $price; $percentage = $discount/$rrp * 100; $page->of(false); $page->set('pad_discount', $percentage); $this->message('test'); } Link to comment Share on other sites More sharing options...
webhoes Posted December 5, 2018 Author Share Posted December 5, 2018 Damnnn... Or you name your module properly instead of having .php as extension. I could not find it among the modules, but I was confused with some other hooks that are not modules (like in ready.php) that just do their thing. Luckily, it works now. 1 Link to comment Share on other sites More sharing options...
dotnetic Posted December 6, 2018 Share Posted December 6, 2018 You can use a shorter form of the API to get the field values: // instead of $price = $fields->get('pad_price'); $rrp = $fields->get('pad_rrp'); // use $price = $page->pad_price; $rrp = $page->pad_rrp; you also want to use the hookEvent saveReady instead of save, because Quote These hooks provide more certainty and less need for error checking than hooking before or after Pages::save See http://processwire.com/api/hooks/#before_or_after for details. 1 Link to comment Share on other sites More sharing options...
dotnetic Posted December 6, 2018 Share Posted December 6, 2018 You should extend your if clause to ignore pages that are in trash (which can also be saved) if ($page->template != "product" || $page->isTrash()) return; 1 Link to comment Share on other sites More sharing options...
bernhard Posted December 6, 2018 Share Posted December 6, 2018 23 hours ago, webhoes said: It does not update the field. Are you sure your hook gets triggered? Always proceed step by step. I usually start with a hook that only outputs "triggered" via tracy: bd("triggered!"); If you don't see the dump in the tracy bar, your hook does not fire and you have something else wrong (and that's the case here). Try this one and then update the inner code: $wire->addHookAfter('Pages::saveReady(template=product)', function($event) { $page = $event->arguments(0); // your logic here bd("hook fired!"); }); To update your field you don't need "setAndSave", just set your field's value like this: $page->yourfield = 'yourvalue'; That's it ? 1 2 Link to comment Share on other sites More sharing options...
webhoes Posted December 6, 2018 Author Share Posted December 6, 2018 Thanks @jmartsch and @bernhard I have updated the module with your improvements. Works very smooth... 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