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