Jump to content

How to append to an existing [textarea] field value? (not just re-set it)


hellomoto
 Share

Recommended Posts

My vessel template has a price field (actually field group: with price_currency, price_amount). But when the price is lowered, the listing should qualify to appear on a "Price Cuts" page automatically... so here's what I'm doing (or skip to the bottom):

So I was thinking I could add another couple of read-only fields, price_amount_was (since it's unlikely that the currency would change) and price_cut_date.

price_amount_was would default to the set price once one is set on save (starts empty, stays empty until a price is set and the page saved). price_cut_date would be null by default.

Then another hook after page save would check if the price_amount is lower than price_amount_was, and if so, change the price_cut_date to the current day. 

Then my Price Cuts page could just show "template=vessel, limit=10, price_cut_date!='', sort=-price_cut_date".

But if I wanted to keep a history of price cuts for each listing, that wouldn't work. I could use a repeater field but I don't think that's all that necessary, since only the current and last price (or I guess that'd be second-to-last, last is current) need be queryable. 

I could add another read-only textarea field, price_history, and on every save that the price is changed, append the price and date (comma-separated, followed by a newline). 

So that's what I'm trying to do now, but I don't know how to append to price_history. 

In my module init I hook after page save, this function:


	protected function setPriceHistory($event) {

		$page = $event->arguments('page'); 
		if($page->template != 'vessel') return;

		if($page->price_amount) {
			//$this->message("Price exists");
			if(!$page->price_amount_hold) {
				$page->set("price_amount_hold", $page->price_amount)->save();
				// append price_amount, date(), newline to price_history
				$this->message("Updated hold price to current price.");
			}
			if($page->price_amount < $page->price_amount_hold) {
				$page->set("price_amount_was", $page->price_amount_hold)->set("price_amount_hold", $page->price_amount)->set("price_cut_date", wireDate('Y-m-d'))->save();
				$this->message("Price Cut set on {$page->price_cut_date}.");
			}
		}

	}

So you see that commented out line in if(!$page->price_amount_was){}... I could set the value, but I don't want to reset it, just add to it.

Thanks.

Link to comment
Share on other sites

Am I right, that you're just battling with adding a string to a textfield instead of replacing it? This adds a new line to the top.

$page->price_history = "13.95 2015/01/01\n".$page->price_history;
// Another syntax, but the same
$page->set("price_history", "13.95 2015/01/01\n".$page->price_history);

But you should include a limiter which removes the lines after a set amount of them. Something like this.

$newhistory = "13.95 2015/01/01\n".$page->price_history; 
$pos = strpos($newhistroy, "\n", 1600); // Search for linebreaks after 1600 chars
if($pos) $newhistroy = substr($newhistroy, 0, $pos); // Limit the string 
Link to comment
Share on other sites

Okay so this was working, but now it seems to time out since I added changed the second condition to != and put the < within that:

	protected function setPriceHistory($event) {

		$page = $event->arguments('page'); 
		if($page->template != 'vessel') return;

		if($page->price_amount) {
			//$this->message("Price exists");
			if(!$page->price_amount_hold) {
				$page->set("price_amount_hold", $page->price_amount)->set("price_history", $page->price_history . $page->price_amount . ", " . wireDate('Y-m-d') . "\n")->save();
				// append price_amount, date(), newline to price_history
				$this->message("Updated hold price to current price.");
			}
			if($page->price_amount != $page->price_amount_hold && !$page->is('unpublished')) {
				if($page->price_amount < $page->price_amount_hold) {
					$page->set("price_amount_was", $page->price_amount_hold)->save();
					$this->message("Price Cut set on {$page->price_cut_date}.");
				}
				$page->set("price_history", $page->price_history . $page->price_amount . ", " . wireDate('Y-m-d') . "\n")->save();
				$this->message("Updated price history.");
			}
			//$page->save();
		}

	}

See it was working up until I tried adding price history for any change in price, as opposed to only when it's cut. I thought it might be too many page->saves at once, so I removed the last save() from each of the changes, and just put it at the bottom... Still doesn't work, I get no data received, or a timeout:


Notice: Trying to get property of non-object in /wire/core/Page.php on line 333

Warning: Invalid argument supplied for foreach() in /wire/core/Page.php on line 333

Notice: Trying to get property of non-object in /wire/core/Page.php on line 333

Warning: Invalid argument supplied for foreach() in /wire/core/Page.php on line 333

Notice: Trying to get property of non-object in /wire/core/Page.php on line 333

Warning: Invalid argument supplied for foreach() in /wire/core/Page.php on line 333

Error: Maximum execution time of 30 seconds exceeded (line 87 of /wire/core/DatabaseQuery.php) 
This error message was shown because site is in debug mode ($config->debug = true; in /site/config.php). Error has been logged.


Oh. and it added about a million of the same line from the same save, that's why it timed out... Why might that be..?

Link to comment
Share on other sites

Well this seems to work ok:


	protected function setPriceHistory($event) {

		$page = $event->arguments('page'); 
		if($page->template != 'vessel') return;

		if($page->price_amount) {

			if(!$page->price_amount_hold) {
				$page->set("price_amount_hold", $page->price_amount)->set("price_history", $page->price_history . $page->price_amount . ", " . wireDate('Y-m-d') . "\n")->save();
				$this->message("Updated hold price to current price.");
			}

			elseif($page->price_amount_hold && $page->price_amount != $page->price_amount_hold && !$page->is('unpublished')) {
				if($page->price_amount < $page->price_amount_hold) {
					$page->set("price_amount_was", $page->price_amount_hold)->set("price_cut_date", wireDate('Y-m-d'));
					$this->message("Price Cut set on " . wireDate('Y-m-d', $page->price_cut_date) . ".");
				}

				$page->set("price_amount_hold", $page->price_amount)->set("price_history", $page->price_history . $page->price_amount . ", " . wireDate('Y-m-d') . "\n");

				$pos = strpos($page->price_history, "\n", 1600); // Search for linebreaks after 1600 chars
				if($pos) $page->price_history = substr($page->price_history, 0, $pos); // Limit the string 

				$page->save();
				$this->message("Updated price history.");
			}
		}

		if($page->price_cut_clear) {
			$page->set("price_cut_date", "")->set("price_cut_clear", false)->save();
			$this->message("Price cut cleared.");
		}

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