Created
September 24, 2015 15:16
-
-
Save Glifery/f08516a7aaed3ff4d43c to your computer and use it in GitHub Desktop.
Watch for changes in objects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Reddin\Bundle\MEPBundle\Service; | |
class ObjectChangedWatcher | |
{ | |
/** | |
* @var array | |
*/ | |
private $objects; | |
public function __construct() | |
{ | |
$this->objects = array(); | |
} | |
/** | |
* @param object $object | |
* @return $this | |
*/ | |
public function watch($object) | |
{ | |
if (!$this->isWatched($object)) { | |
$this->pushObjectToStorage($object); | |
} | |
return $this; | |
} | |
/** | |
* @param object|null $object | |
* @return $this | |
*/ | |
public function clear($object = null) | |
{ | |
$objectHash = $this->getObjectHash($object); | |
unset ($this->objects[$objectHash]); | |
return $this; | |
} | |
/** | |
* @param object|null $object | |
* @return $this | |
* @throws \Exception | |
*/ | |
public function reset($object = null) | |
{ | |
if ($object) { | |
if (!$this->isWatched($object)) { | |
throw new \Exception('Trying to reset non-watched object.'); | |
} | |
$this->pushObjectToStorage($object); | |
} else { | |
foreach ($this->objects as &$objectInfo) { | |
$objectInfo['stamp'] = $this->getObjectStamp($objectInfo['object']); | |
} | |
} | |
return $this; | |
} | |
/** | |
* @param object $object | |
* @return bool | |
*/ | |
public function isWatched($object) | |
{ | |
return ($this->findObjectInfo($object) === null) ? false : true; | |
} | |
/** | |
* @param object $object | |
* @return bool | |
* @throws \Exception | |
*/ | |
public function isChanged($object) | |
{ | |
if (!$this->isWatched($object)) { | |
throw new \Exception('Can\'t get state of non-watched object.'); | |
} | |
$objectInfo = $this->findObjectInfo($object); | |
$currentStamp = $this->getObjectStamp($object); | |
return ($currentStamp !== $objectInfo['stamp']); | |
} | |
/** | |
* @param string|null $className | |
* @return array | |
*/ | |
public function getChanged($className = null) | |
{ | |
$changedObjects = array(); | |
foreach ($this->objects as $objectInfo) { | |
$object = $objectInfo['object']; | |
$currentStamp = $this->getObjectStamp($object); | |
if ($className && (!is_a($object, $className))) continue; | |
if ($currentStamp !== $objectInfo['stamp']) { | |
$changedObjects[] = $object; | |
} | |
} | |
return $changedObjects; | |
} | |
/** | |
* @param object $object | |
* @return string | |
*/ | |
private function pushObjectToStorage($object) | |
{ | |
$objectHash = $this->getObjectHash($object); | |
$objectStamp = $this->getObjectStamp($object); | |
$this->objects[$objectHash] = array( | |
'object' => $object, | |
'stamp' => $objectStamp | |
); | |
return $objectHash; | |
} | |
/** | |
* @param object $object | |
* @return array|null | |
*/ | |
private function findObjectInfo($object) | |
{ | |
$objectHash = $this->getObjectHash($object); | |
return isset($this->objects[$objectHash]) ? $this->objects[$objectHash] : null; | |
} | |
/** | |
* @param object $object | |
* @return string | |
*/ | |
private function getObjectHash($object) | |
{ | |
return spl_object_hash($object); | |
} | |
/** | |
* @param object $object | |
* @return string | |
*/ | |
private function getObjectStamp($object) | |
{ | |
return md5(serialize($object)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment