Chris@14: Chris@14: * Chris@14: * For the full copyright and license information, please view the LICENSE Chris@14: * file that was distributed with this source code. Chris@14: */ Chris@14: Chris@14: namespace SebastianBergmann\ObjectEnumerator; Chris@14: Chris@14: use SebastianBergmann\ObjectReflector\ObjectReflector; Chris@14: use SebastianBergmann\RecursionContext\Context; Chris@14: Chris@14: /** Chris@14: * Traverses array structures and object graphs Chris@14: * to enumerate all referenced objects. Chris@14: */ Chris@14: class Enumerator Chris@14: { Chris@14: /** Chris@14: * Returns an array of all objects referenced either Chris@14: * directly or indirectly by a variable. Chris@14: * Chris@14: * @param array|object $variable Chris@14: * Chris@14: * @return object[] Chris@14: */ Chris@14: public function enumerate($variable) Chris@14: { Chris@14: if (!is_array($variable) && !is_object($variable)) { Chris@14: throw new InvalidArgumentException; Chris@14: } Chris@14: Chris@14: if (isset(func_get_args()[1])) { Chris@14: if (!func_get_args()[1] instanceof Context) { Chris@14: throw new InvalidArgumentException; Chris@14: } Chris@14: Chris@14: $processed = func_get_args()[1]; Chris@14: } else { Chris@14: $processed = new Context; Chris@14: } Chris@14: Chris@14: $objects = []; Chris@14: Chris@14: if ($processed->contains($variable)) { Chris@14: return $objects; Chris@14: } Chris@14: Chris@14: $array = $variable; Chris@14: $processed->add($variable); Chris@14: Chris@14: if (is_array($variable)) { Chris@14: foreach ($array as $element) { Chris@14: if (!is_array($element) && !is_object($element)) { Chris@14: continue; Chris@14: } Chris@14: Chris@14: $objects = array_merge( Chris@14: $objects, Chris@14: $this->enumerate($element, $processed) Chris@14: ); Chris@14: } Chris@14: } else { Chris@14: $objects[] = $variable; Chris@14: Chris@14: $reflector = new ObjectReflector; Chris@14: Chris@14: foreach ($reflector->getAttributes($variable) as $value) { Chris@14: if (!is_array($value) && !is_object($value)) { Chris@14: continue; Chris@14: } Chris@14: Chris@14: $objects = array_merge( Chris@14: $objects, Chris@14: $this->enumerate($value, $processed) Chris@14: ); Chris@14: } Chris@14: } Chris@14: Chris@14: return $objects; Chris@14: } Chris@14: }