Jump to content

Update repeater fields in hook


dragan
 Share

Recommended Posts

I'm trying to update certain repeater fields with a hook. This almost works, but is somehow buggy.

Each repeater is supposed to represent a row: service, remarks, number of days, day-rate, row total.

The last repeater should then show the grand total.

I've tried this:

    $this->addHookAfter("Pages::saveReady", function (HookEvent $event) {
        $page = $event->object->getPage();
        if ($page->template->id == 89 && $page->parent->parent->id == 11180) {
            $repeater  = $page->offer_calc_repeater;
            $itemCount = $repeater->count();
            $c = 0;
            $grandTotal = 0;
            foreach ($repeater as $rep) {
                if($c < ($itemCount - 1) ) {
                    if (!empty($rep->days) && !empty($rep->daily_rate)) {
                        $num_days  = $rep->days;
                        $day_rate  = $rep->daily_rate;
                        $row_total = $num_days * $day_rate;
                        $rep->row_total = $row_total;
                        $grandTotal = $grandTotal + $row_total;
                        $page->save();
                        unset($num_days);
                        unset($day_rate);
                        unset($row_total);
                        $c++;
                    }
                }
                if ($c == $itemCount) {
                    $rep->row_total = $grandTotal;
                }
            }
        }
    });

Most calculations are correct, but:

The first one is empty.

The second one is calculated wrong.

I've tried typecasting (float), or checking with strlen instead of !empty, but that doesn't make any difference.

Is the Pages::saveReady the ideal hook for such stuff? (placed in site/ready.php).

Also, I get an error message: Session: Method Pages::getPage does not exist or is not callable in this context.

Any ideas? Would you perhaps rather do stuff like this via JS?

Link to comment
Share on other sites

$page = $event->object->getPage();

in a Pages::saveReady $event->object would be Pages not the page getting saved.

You'd use $event->arguments("page") to get the argument variable "$page" from the ___saveReady() hook in Pages.

or $event->arguments(0) to get the first argument variable which would also be the "$page", but I prefer the named version.

  • Like 1
Link to comment
Share on other sites

    $this->addHookAfter("ProcessPageEdit::buildForm", function (HookEvent $event) {
        $page = $event->object->getPage();
        if ($page->template->id == 89 && $page->parent->parent->id == 11180) {
            $repeater  = $page->pro_table;
            $itemCount = $repeater->count();
            $c = 1;
            $grandTotal = 0;
            foreach ($repeater as $rep) {
                if($c < $itemCount ) {
                        $num_days  = (float) $rep->days;
                        $day_rate  = (float) $rep->day_rate;
                        $row_total = $num_days * $day_rate;
                        $rep->row_total = $row_total;
                        $grandTotal = $grandTotal + $row_total;
                        $page->save();
                        unset($num_days);
                        unset($day_rate);
                        unset($row_total);
                }
                if ($c === ($itemCount)) {
                    $rep->row_total = $grandTotal;
                    $page->save();
                }
	            $c++;
            }
        }
    });

OK, got it now. Used another hook. Works like a charm.

  • Like 1
Link to comment
Share on other sites

Why have code that executes on every request and saves everything? This works just fine

$this->addHookAfter("Pages::saveReady", function (HookEvent $event) {
    $page = $event->arguments("page");
    if(!($page->template->id == 89 && $page->parent->parent->id == 11180)) return;
    $repeaters  = $page->pro_table;
    if(!$repeaters->count) return;
    $total = 0;
    foreach($repeaters as $rep) {
    	$rep->row_total = $rep->days * $rep->day_rate;
        $total += $rep->row_total;
        if($repeaters->last === $rep || $repeaters->count == 1){
        	$rep->row_total = $total;
        }
    }
});

 

  • Like 1
Link to comment
Share on other sites

  • 1 year later...

I had a similar problem.
The following didn't work in my case:

If there are already incorrect values in a repeater field (e.g. from previous entries), the hook Pages :: saveReady doesn't seem to work. Pages :: saveReady changes the repeater field only if the input is changed via backend and then saved.

In other words: existing field values are apparently not checked or changed changed with Pages :: saveReady, unless the filed value is also changed in the backend.

ProcessPageEdit :: buildForm also works with existing field values (contaminated areas ?)

See this entry:

Maybe I could be of some help here.
Or maybe I'm completely wrong.

Robert

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

×
×
  • Create New...