Skip to content

Instantly share code, notes, and snippets.

@dominikzogg
Last active August 29, 2015 13:56
Show Gist options
  • Save dominikzogg/9111279 to your computer and use it in GitHub Desktop.
Save dominikzogg/9111279 to your computer and use it in GitHub Desktop.
<?php
namespace Ibrows\GameBundle\Util;
class ObjectIterator implements \Iterator
{
protected $objects = array();
/**
* @param object $object
* @throws \InvalidArgumentException
*/
public function __construct($object)
{
if(!is_object($object)) {
throw new \InvalidArgumentException("Input is not an object");
}
$this->objects[] = $object;
}
/**
* @param object $object
*/
protected function addObjects($object)
{
$reflectionClass = new \ReflectionClass($object);
$this->addObjectsFromMethods($reflectionClass, $object);
$this->addObjectsFromProperty($reflectionClass, $object);
}
/**
* @param \ReflectionClass $reflectionClass
* @param object $object
*/
protected function addObjectsFromMethods(\ReflectionClass $reflectionClass, $object)
{
foreach($reflectionClass->getMethods(\ReflectionProperty::IS_PUBLIC) as $reflectionMethod) {
if(strtolower(substr($reflectionMethod->getName(), 0, 3)) == 'get' &&
$reflectionMethod->getNumberOfParameters() == 0
) {
$value = $reflectionMethod->invoke($object);
if(is_array($value) || $value instanceof \Traversable) {
foreach($value as $subValue) {
if(is_object($subValue) && !in_array($subValue, $this->objects)) {
$this->objects[] = $subValue;
}
}
} elseif(is_object($value)) {
if(!in_array($value, $this->objects)) {
$this->objects[] = $value;
}
}
}
}
}
/**
* @param \ReflectionClass $reflectionClass
* @param object $object
*/
protected function addObjectsFromProperty(\ReflectionClass $reflectionClass, $object)
{
foreach($reflectionClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $propertyReflection) {
$value = $propertyReflection->getValue($object);
if(is_array($value) || $value instanceof \Traversable) {
foreach($value as $subValue) {
if(is_object($subValue) && !in_array($subValue, $this->objects)) {
$this->objects[] = $subValue;
}
}
} elseif(is_object($value)) {
if(!in_array($value, $this->objects)) {
$this->objects[] = $value;
}
}
}
}
/**
* @return object
*/
public function current()
{
return current($this->objects);
}
public function next()
{
$this->addObjects(current($this->objects));
next($this->objects);
}
/**
* @return object
*/
public function key()
{
return key($this->objects);
}
/**
* @return bool
*/
public function valid()
{
return current($this->objects) === false ? false : true;
}
public function rewind()
{
reset($this->objects);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment