Collection.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: zhangyajun <448901948@qq.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types = 1);
  12. namespace think\model;
  13. use think\Collection as BaseCollection;
  14. use think\Model;
  15. use think\Paginator;
  16. /**
  17. * 模型数据集类
  18. */
  19. class Collection extends BaseCollection
  20. {
  21. /**
  22. * 延迟预载入关联查询
  23. * @access public
  24. * @param array|string $relation 关联
  25. * @param mixed $cache 关联缓存
  26. * @return $this
  27. */
  28. public function load($relation, $cache = false)
  29. {
  30. if (!$this->isEmpty()) {
  31. $item = current($this->items);
  32. $item->eagerlyResultSet($this->items, (array) $relation, [], false, $cache);
  33. }
  34. return $this;
  35. }
  36. /**
  37. * 删除数据集的数据
  38. * @access public
  39. * @return bool
  40. */
  41. public function delete(): bool
  42. {
  43. $this->each(function (Model $model) {
  44. $model->delete();
  45. });
  46. return true;
  47. }
  48. /**
  49. * 更新数据
  50. * @access public
  51. * @param array $data 数据数组
  52. * @param array $allowField 允许字段
  53. * @return bool
  54. */
  55. public function update(array $data, array $allowField = []): bool
  56. {
  57. $this->each(function (Model $model) use ($data, $allowField) {
  58. if (!empty($allowField)) {
  59. $model->allowField($allowField);
  60. }
  61. $model->save($data);
  62. });
  63. return true;
  64. }
  65. /**
  66. * 设置需要隐藏的输出属性
  67. * @access public
  68. * @param array $hidden 属性列表
  69. * @return $this
  70. */
  71. public function hidden(array $hidden)
  72. {
  73. $this->each(function (Model $model) use ($hidden) {
  74. $model->hidden($hidden);
  75. });
  76. return $this;
  77. }
  78. /**
  79. * 设置需要输出的属性
  80. * @access public
  81. * @param array $visible
  82. * @return $this
  83. */
  84. public function visible(array $visible)
  85. {
  86. $this->each(function (Model $model) use ($visible) {
  87. $model->visible($visible);
  88. });
  89. return $this;
  90. }
  91. /**
  92. * 设置需要追加的输出属性
  93. * @access public
  94. * @param array $append 属性列表
  95. * @return $this
  96. */
  97. public function append(array $append)
  98. {
  99. $this->each(function (Model $model) use ($append) {
  100. $model->append($append);
  101. });
  102. return $this;
  103. }
  104. /**
  105. * 设置父模型
  106. * @access public
  107. * @param Model $parent 父模型
  108. * @return $this
  109. */
  110. public function setParent(Model $parent)
  111. {
  112. $this->each(function (Model $model) use ($parent) {
  113. $model->setParent($parent);
  114. });
  115. return $this;
  116. }
  117. /**
  118. * 设置数据字段获取器
  119. * @access public
  120. * @param string|array $name 字段名
  121. * @param callable $callback 闭包获取器
  122. * @return $this
  123. */
  124. public function withAttr($name, $callback = null)
  125. {
  126. $this->each(function (Model $model) use ($name, $callback) {
  127. $model->withAttribute($name, $callback);
  128. });
  129. return $this;
  130. }
  131. /**
  132. * 绑定(一对一)关联属性到当前模型
  133. * @access protected
  134. * @param string $relation 关联名称
  135. * @param array $attrs 绑定属性
  136. * @return $this
  137. * @throws Exception
  138. */
  139. public function bindAttr(string $relation, array $attrs = [])
  140. {
  141. $this->each(function (Model $model) use ($relation, $attrs) {
  142. $model->bindAttr($relation, $attrs);
  143. });
  144. return $this;
  145. }
  146. /**
  147. * 按指定键整理数据
  148. *
  149. * @access public
  150. * @param mixed $items 数据
  151. * @param string $indexKey 键名
  152. * @return array
  153. */
  154. public function dictionary($items = null, string &$indexKey = null)
  155. {
  156. if ($items instanceof self || $items instanceof Paginator) {
  157. $items = $items->all();
  158. }
  159. $items = is_null($items) ? $this->items : $items;
  160. if ($items && empty($indexKey)) {
  161. $indexKey = $items[0]->getPk();
  162. }
  163. if (isset($indexKey) && is_string($indexKey)) {
  164. return array_column($items, null, $indexKey);
  165. }
  166. return $items;
  167. }
  168. /**
  169. * 比较数据集,返回差集
  170. *
  171. * @access public
  172. * @param mixed $items 数据
  173. * @param string $indexKey 指定比较的键名
  174. * @return static
  175. */
  176. public function diff($items, string $indexKey = null)
  177. {
  178. if ($this->isEmpty()) {
  179. return new static($items);
  180. }
  181. $diff = [];
  182. $dictionary = $this->dictionary($items, $indexKey);
  183. if (is_string($indexKey)) {
  184. foreach ($this->items as $item) {
  185. if (!isset($dictionary[$item[$indexKey]])) {
  186. $diff[] = $item;
  187. }
  188. }
  189. }
  190. return new static($diff);
  191. }
  192. /**
  193. * 比较数据集,返回交集
  194. *
  195. * @access public
  196. * @param mixed $items 数据
  197. * @param string $indexKey 指定比较的键名
  198. * @return static
  199. */
  200. public function intersect($items, string $indexKey = null)
  201. {
  202. if ($this->isEmpty()) {
  203. return new static([]);
  204. }
  205. $intersect = [];
  206. $dictionary = $this->dictionary($items, $indexKey);
  207. if (is_string($indexKey)) {
  208. foreach ($this->items as $item) {
  209. if (isset($dictionary[$item[$indexKey]])) {
  210. $intersect[] = $item;
  211. }
  212. }
  213. }
  214. return new static($intersect);
  215. }
  216. }