Skip to content

Instantly share code, notes, and snippets.

@Glifery
Created September 24, 2015 15:16
Show Gist options
  • Save Glifery/f08516a7aaed3ff4d43c to your computer and use it in GitHub Desktop.
Save Glifery/f08516a7aaed3ff4d43c to your computer and use it in GitHub Desktop.
Watch for changes in objects
<?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