Enumerator.php 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. <?php
  2. /*
  3. * This file is part of Object Enumerator.
  4. *
  5. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace SebastianBergmann\ObjectEnumerator;
  11. use SebastianBergmann\ObjectReflector\ObjectReflector;
  12. use SebastianBergmann\RecursionContext\Context;
  13. /**
  14. * Traverses array structures and object graphs
  15. * to enumerate all referenced objects.
  16. */
  17. class Enumerator
  18. {
  19. /**
  20. * Returns an array of all objects referenced either
  21. * directly or indirectly by a variable.
  22. *
  23. * @param array|object $variable
  24. *
  25. * @return object[]
  26. */
  27. public function enumerate($variable)
  28. {
  29. if (!is_array($variable) && !is_object($variable)) {
  30. throw new InvalidArgumentException;
  31. }
  32. if (isset(func_get_args()[1])) {
  33. if (!func_get_args()[1] instanceof Context) {
  34. throw new InvalidArgumentException;
  35. }
  36. $processed = func_get_args()[1];
  37. } else {
  38. $processed = new Context;
  39. }
  40. $objects = [];
  41. if ($processed->contains($variable)) {
  42. return $objects;
  43. }
  44. $array = $variable;
  45. $processed->add($variable);
  46. if (is_array($variable)) {
  47. foreach ($array as $element) {
  48. if (!is_array($element) && !is_object($element)) {
  49. continue;
  50. }
  51. $objects = array_merge(
  52. $objects,
  53. $this->enumerate($element, $processed)
  54. );
  55. }
  56. } else {
  57. $objects[] = $variable;
  58. $reflector = new ObjectReflector;
  59. foreach ($reflector->getAttributes($variable) as $value) {
  60. if (!is_array($value) && !is_object($value)) {
  61. continue;
  62. }
  63. $objects = array_merge(
  64. $objects,
  65. $this->enumerate($value, $processed)
  66. );
  67. }
  68. }
  69. return $objects;
  70. }
  71. }