Collection.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <?php
  2. namespace ORM;
  3. // https://stitcher.io/blog/typed-properties-in-php-74
  4. // https://dev.to/chemaclass/typed-arrays-in-php-hoo
  5. class Collection implements \Countable, \IteratorAggregate, \ArrayAccess
  6. {
  7. private Array $items;
  8. function __construct(array $items = array())
  9. {
  10. $this->items = $items;
  11. }
  12. public function addItem(Entity $item)
  13. {
  14. $this->items[] = $item;
  15. }
  16. // https://www.php.net/manual/en/class.countable.php
  17. public function count()
  18. {
  19. return count($this->items);
  20. }
  21. // https://www.php.net/manual/en/class.iteratoraggregate.php
  22. public function getIterator(): \Generator
  23. {
  24. foreach ($this->items as $key => $val) {
  25. yield $key => $val;
  26. }
  27. }
  28. // https://www.php.net/manual/en/class.arrayaccess.php
  29. public function offsetSet($offset, $value)
  30. {
  31. if (is_null($offset)) {
  32. $this->items[] = $value;
  33. } else {
  34. $this->items[$offset] = $value;
  35. }
  36. }
  37. public function offsetExists($offset)
  38. {
  39. return isset($this->items[$offset]);
  40. }
  41. public function offsetUnset($offset)
  42. {
  43. unset($this->items[$offset]);
  44. }
  45. public function offsetGet($offset)
  46. {
  47. return isset($this->items[$offset]) ? $this->items[$offset] : null;
  48. }
  49. //
  50. // -----------------------------------
  51. // Magic methods
  52. //
  53. public function __call($name, $arguments)
  54. {
  55. if (sizeof($this->items) == 1) {
  56. return $this->items[0]->$name();
  57. } else {
  58. throw new \Exception('Undefined method or Multiple values on set');
  59. }
  60. }
  61. //
  62. // -----------------------------------
  63. // Collection specific methods
  64. //
  65. function get($forceCollection = false)
  66. {
  67. if (sizeof($this->items) == 1 && !$forceCollection) {
  68. return $this->items[0];
  69. } else {
  70. return $this->items;
  71. }
  72. }
  73. function with(array $connections = array())
  74. {
  75. $searchs = array();
  76. foreach ($this->items as $key => $item) {
  77. foreach ($connections as $connection) {
  78. $relation = $item->$connection();
  79. switch (get_class($relation)) {
  80. case 'ORM\HasMany':
  81. $this->items[$key]->$connection = $this->items[$key]->$connection()->get();
  82. break;
  83. case 'ORM\HasOne':
  84. $this->items[$key]->$connection = $this->items[$key]->$connection()->get();
  85. break;
  86. case 'ORM\BelongsTo':
  87. $this->items[$key]->$connection = $this->items[$key]->$connection()->get();
  88. break;
  89. case 'ORM\BelongsToMany':
  90. $this->items[$key]->$connection = $this->items[$key]->$connection()->get();
  91. break;
  92. case 'ORM\BelongsToManyExtended':
  93. $this->items[$key]->$connection = $this->items[$key]->$connection()->get();
  94. break;
  95. default:
  96. $this->items[$key]->$connection = $this->items[$key]->$connection()->get();
  97. break;
  98. }
  99. }
  100. }
  101. return $this;
  102. }
  103. function first()
  104. {
  105. if (isset($this->items[0])) {
  106. return $this->items[0];
  107. }
  108. }
  109. /**
  110. * Iterate over the colletion
  111. *
  112. * @param mixed $function
  113. * @return void
  114. */
  115. function each($function)
  116. {
  117. foreach($this->items as $item){
  118. $function($item);
  119. }
  120. }
  121. }