Collection.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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 string $scene 场景名称
  108. * @return $this
  109. */
  110. public function scene(string $scene)
  111. {
  112. $this->each(function (Model $model) use ($scene) {
  113. $model->scene($scene);
  114. });
  115. return $this;
  116. }
  117. /**
  118. * 设置父模型
  119. * @access public
  120. * @param Model $parent 父模型
  121. * @return $this
  122. */
  123. public function setParent(Model $parent)
  124. {
  125. $this->each(function (Model $model) use ($parent) {
  126. $model->setParent($parent);
  127. });
  128. return $this;
  129. }
  130. /**
  131. * 设置数据字段获取器
  132. * @access public
  133. * @param string|array $name 字段名
  134. * @param callable $callback 闭包获取器
  135. * @return $this
  136. */
  137. public function withAttr($name, $callback = null)
  138. {
  139. $this->each(function (Model $model) use ($name, $callback) {
  140. $model->withAttribute($name, $callback);
  141. });
  142. return $this;
  143. }
  144. /**
  145. * 绑定(一对一)关联属性到当前模型
  146. * @access protected
  147. * @param string $relation 关联名称
  148. * @param array $attrs 绑定属性
  149. * @return $this
  150. * @throws Exception
  151. */
  152. public function bindAttr(string $relation, array $attrs = [])
  153. {
  154. $this->each(function (Model $model) use ($relation, $attrs) {
  155. $model->bindAttr($relation, $attrs);
  156. });
  157. return $this;
  158. }
  159. /**
  160. * 按指定键整理数据
  161. *
  162. * @access public
  163. * @param mixed $items 数据
  164. * @param string $indexKey 键名
  165. * @return array
  166. */
  167. public function dictionary($items = null, string &$indexKey = null)
  168. {
  169. if ($items instanceof self || $items instanceof Paginator) {
  170. $items = $items->all();
  171. }
  172. $items = is_null($items) ? $this->items : $items;
  173. if ($items && empty($indexKey)) {
  174. $indexKey = $items[0]->getPk();
  175. }
  176. if (isset($indexKey) && is_string($indexKey)) {
  177. return array_column($items, null, $indexKey);
  178. }
  179. return $items;
  180. }
  181. /**
  182. * 比较数据集,返回差集
  183. *
  184. * @access public
  185. * @param mixed $items 数据
  186. * @param string $indexKey 指定比较的键名
  187. * @return static
  188. */
  189. public function diff($items, string $indexKey = null)
  190. {
  191. if ($this->isEmpty()) {
  192. return new static($items);
  193. }
  194. $diff = [];
  195. $dictionary = $this->dictionary($items, $indexKey);
  196. if (is_string($indexKey)) {
  197. foreach ($this->items as $item) {
  198. if (!isset($dictionary[$item[$indexKey]])) {
  199. $diff[] = $item;
  200. }
  201. }
  202. }
  203. return new static($diff);
  204. }
  205. /**
  206. * 比较数据集,返回交集
  207. *
  208. * @access public
  209. * @param mixed $items 数据
  210. * @param string $indexKey 指定比较的键名
  211. * @return static
  212. */
  213. public function intersect($items, string $indexKey = null)
  214. {
  215. if ($this->isEmpty()) {
  216. return new static([]);
  217. }
  218. $intersect = [];
  219. $dictionary = $this->dictionary($items, $indexKey);
  220. if (is_string($indexKey)) {
  221. foreach ($this->items as $item) {
  222. if (isset($dictionary[$item[$indexKey]])) {
  223. $intersect[] = $item;
  224. }
  225. }
  226. }
  227. return new static($intersect);
  228. }
  229. }