Jump to content

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


Recommended Posts

Posted

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.

Posted

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 
Posted

Yeah I just realized I should just make it what it is plus the new one as I was reloading this page just now... Leave it to me to think after I ask... Thanks for the delimiter tip too.

Posted

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

Posted

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.");
		}

	}

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
×
×
  • Create New...