Collection.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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()
  23. {
  24. return (function () {
  25. while (list($key, $val) = each($this->items)) {
  26. yield $key => $val;
  27. }
  28. })();
  29. }
  30. // https://www.php.net/manual/en/class.arrayaccess.php
  31. public function offsetSet($offset, $value)
  32. {
  33. if (is_null($offset)) {
  34. $this->items[] = $value;
  35. } else {
  36. $this->items[$offset] = $value;
  37. }
  38. }
  39. public function offsetExists($offset)
  40. {
  41. return isset($this->items[$offset]);
  42. }
  43. public function offsetUnset($offset)
  44. {
  45. unset($this->items[$offset]);
  46. }
  47. public function offsetGet($offset)
  48. {
  49. return isset($this->items[$offset]) ? $this->items[$offset] : null;
  50. }
  51. //
  52. // -----------------------------------
  53. // Magic methods
  54. //
  55. public function __call($name, $arguments)
  56. {
  57. if (sizeof($this->items) == 1) {
  58. return $this->items[0]->$name();
  59. } else {
  60. throw new \Exception('Undefined method or Multiple values on set');
  61. }
  62. }
  63. //
  64. // -----------------------------------
  65. // Collection specific methods
  66. //
  67. function get($forceCollection = false)
  68. {
  69. if (sizeof($this->items) == 1 && !$forceCollection) {
  70. return $this->items[0];
  71. } else {
  72. return $this->items;
  73. }
  74. }
  75. function with(array $connections = array())
  76. {
  77. $searchs = array();
  78. foreach ($this->items as $key => $item) {
  79. foreach ($connections as $connection) {
  80. $relation = $item->$connection();
  81. switch (get_class($relation)) {
  82. case 'ORM\HasMany':
  83. $this->items[$key]->$connection = $this->items[$key]->$connection()->get();
  84. break;
  85. case 'ORM\HasOne':
  86. $this->items[$key]->$connection = $this->items[$key]->$connection()->get();
  87. break;
  88. case 'ORM\BelongsTo':
  89. $this->items[$key]->$connection = $this->items[$key]->$connection()->get();
  90. break;
  91. case 'ORM\BelongsToMany':
  92. $this->items[$key]->$connection = $this->items[$key]->$connection()->get();
  93. break;
  94. case 'ORM\BelongsToManyExtended':
  95. $this->items[$key]->$connection = $this->items[$key]->$connection()->get();
  96. break;
  97. default:
  98. $this->items[$key]->$connection = $this->items[$key]->$connection()->get();
  99. break;
  100. }
  101. }
  102. }
  103. return $this->items;
  104. }
  105. function first()
  106. {
  107. if (isset($this->items[0])) {
  108. return $this->items[0];
  109. }
  110. }
  111. /**
  112. * Iterate over the colletion
  113. *
  114. * @param mixed $function
  115. * @return void
  116. */
  117. function each($function)
  118. {
  119. foreach($this->items as $item){
  120. $function($item);
  121. }
  122. }
  123. }