Skip to content

Instantly share code, notes, and snippets.

@fprochazka
Forked from jsmitka/ChangeTracker.php
Created September 5, 2010 10:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fprochazka/565923 to your computer and use it in GitHub Desktop.
Save fprochazka/565923 to your computer and use it in GitHub Desktop.
<?php
namespace NetteExtras\Forms;
class ChangeTracker extends \Nette\Forms\HiddenField
{
private $session;
private $modifiedValues;
public function __construct($forcedValue = NULL)
{
parent::__construct($forcedValue);
$this->monitor('Nette\Application\Presenter');
}
protected function attached($object)
{
parent::attached($object);
if ($object instanceof \Nette\Forms\Form) {
if ($this->value == NULL) {
$this->value = base_convert(md5(uniqid(mt_rand(), TRUE)), 16, 36);
}
}
if ($object instanceof \Nette\Application\Presenter) {
if (!$this->isDisabled() && $this->form->isAnchored() && $this->form->isSubmitted()) {
$this->loadHttpData();
}
if ($this->value === NULL) {
throw new \InvalidStateException('At this point, this component should always have a value, but there is a design flaw hidden somewhere deep in the logic...');
}
$this->session = \Nette\Environment::getSession('NetteExtras.ChangeTracker');
}
}
public function getControl()
{
$control = parent::getControl();
if (!isset($this->session[$this->value])) {
$this->session[$this->value] = $this->form->getValues();
}
return $control;
}
public function getModifiedValues()
{
if ($this->modifiedValues === NULL) {
if ($this->value === NULL) {
throw new \InvalidStateException('Component has to be attached to an anchored form.');
}
$this->modifiedValues = array();
$this->buildModifiedValues($this->form->getValues(), $this->session[$this->value]);
}
return $this->modifiedValues;
}
private function buildModifiedValues($values, $original, $path = array())
{
foreach ($values as $key => $value) {
if (!isset($original[$key])) {
$this->pushModifiedValue($key, $value, $path);
} else {
if (is_array($value)) {
$this->buildModifiedValues($value, $original[$key], array_merge($path, array($key)));
} else {
if ($original[$key] != $value) {
$this->pushModifiedValue($key, $value, $path);
}
}
}
}
}
private function pushModifiedValue($key, $value, array $path)
{
$branch = &$this->modifiedValues;
foreach ($path as $k) {
if (!isset($branch[$k])) {
$branch[$k] = array();
}
$branch = &$branch[$k];
}
$branch[$key] = $value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment