Jump to content

Update field on save based on two other fields


webhoes
 Share

Recommended Posts

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

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);

 

  • Like 1
Link to comment
Share on other sites

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

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.

  • Like 1
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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 ?

  • Like 1
  • Thanks 2
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...