Jump to content

Hook + Repeater field executes twice


MKel
 Share

Recommended Posts

I took over an existing project and have to adjust some parts of it. There is one problem with a repeater field.

The CMS has pages with some kind of like products (saved as repeaters) and there is a weekly cron that makes copies of those pages. As I can see there is a hook event before the pages are saved. The hook calculates the sum of those products (repeater fields) and saves it to another field the just copied page. Problem is the hook is executed twice and thus the sum doubled.

An example

Page A
- Repeater field product A1 and price 10 USD
- Sum field: 10 USD

Now cron makes copy of page A

Page A copy
- Repeater field product A1 and price 10 USD
- Sum field: 20 USD

This is from the cron task

// Create a new page
$p = new Page();
$p->of(false);
$p->template = 'cables';
$p->parent = $pages->get('/cables/top/');
$p->name = 'c_23B14__' . date('H:i:s') . uniqid();
$p->title = 'Preview ' . uniqid();
$p->body = $order->body;
$p->due = $today_midnight;
$p->history = 'Created: ' . date('Y-m-d H:i:s') . ' - ' . $order->title;
$p->removeStatus('published');
$p->addStatus('unpublished');
$p->save();

wire('log')->save('cron_1_friday', 'Page created (' . $p->id . ')');

// Copy items 
foreach ($pushToInvoice as $copy_item) {
	$new_item = $p->document_items->getNew();
	$new_item->repeater_matrix_type = 1;
	$new_item->of(false);

	$new_item->title          = $copy_item->title;
	$new_item->unit           = $copy_item->unit;
	$new_item->quantity       = $copy_item->quantity;
	$new_item->price_per_unit = $copy_item->price_per_unit;
	$new_item->discount       = $copy_item->discount;
	$new_item->tax            = $copy_item->tax;
	$new_item->options        = $copy_item->options;
	$new_item->due            = strtotime('+ ' . $copy_item->recurring->settings->value . ' months', $copy_item->due);
	$new_item->recurring      = $copy_item->recurring;
	$new_item->price          = $copy_item->price;
	$new_item->price_total    = $copy_item->price_total;

	$new_item->save();
	$p->document_items->add($new_item);
	$p->save();

	wire('log')->save('cron_1_friday', 'Item added (' . $new_item->id . ')');
}

$p->save();

and this is the hook event

wire()->addHookBefore('Pages::saveReady', function(HookEvent $event) {

	/** @var Page $page */
	$page = $event->arguments(0);

	if ($page->template == 'cables' || $page->template == 'tubes') {

		$total_net   = 0;
		$total_gross = 0;
		foreach ($page->document_items as $child) {
			if (!$child->options->optional) {
				$item_net = ($child->quantity * $child->price_per_unit)  *  (1 - ($child->discount / 100));
				$total_net += $item_net;
				bd($total_net);
				if ($child->tax->id) {
					$item_gross = $item_net * ( ( (int)$child->tax->settings->value / 100) + 1 );
					$total_gross += $item_gross;
				}
			}
		}

		// Set price
		$page->price       = $total_net;
		$page->price_total = $total_gross;
		$event->arguments(0, $page);

	}

});

I added the bd() and can see it is executed twice.

What's really confusing, even if it gets executed twice the hook event should always just find one item in it and it sums up to just 10 USD.

But I have now idea how this works. It worked with almost the same code before fine, but it was changed from another repeater field (guess it was Page table).

Link to comment
Share on other sites

Seems there is some kind of cache when creating new entries!? The hook runs multiple times and only the first (last?) run contains just the correct number of entries. Look at the screenshot. Somehow there are four items although the right number is just two. And at the end only two entries are saved.

Is this a bug or intended behaviour?

CMS is v 3.0.127 Repeater Matrix is 0.0.4 on PHP 7.3

debug.jpg

Link to comment
Share on other sites

It seems you are calling save() a few times on the page you are expecting in the hook? First when creating the page, and later when adding the repeater to the page, and then one last time (which might be unnecessary?)

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...