Relation.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. namespace think\model;
  12. use think\db\Query;
  13. use think\Exception;
  14. use think\Model;
  15. /**
  16. * Class Relation
  17. * @package think\model
  18. *
  19. * @mixin Query
  20. */
  21. abstract class Relation
  22. {
  23. // 父模型对象
  24. protected $parent;
  25. /** @var Model 当前关联的模型类 */
  26. protected $model;
  27. /** @var Query 关联模型查询对象 */
  28. protected $query;
  29. // 关联表外键
  30. protected $foreignKey;
  31. // 关联表主键
  32. protected $localKey;
  33. // 基础查询
  34. protected $baseQuery;
  35. // 是否为自关联
  36. protected $selfRelation;
  37. /**
  38. * 获取关联的所属模型
  39. * @access public
  40. * @return Model
  41. */
  42. public function getParent()
  43. {
  44. return $this->parent;
  45. }
  46. /**
  47. * 获取当前的关联模型类的实例
  48. * @access public
  49. * @return Model
  50. */
  51. public function getModel()
  52. {
  53. return $this->query->getModel();
  54. }
  55. /**
  56. * 获取当前的关联模型类的实例
  57. * @access public
  58. * @return Query
  59. */
  60. public function getQuery()
  61. {
  62. return $this->query;
  63. }
  64. /**
  65. * 设置当前关联为自关联
  66. * @access public
  67. * @param bool $self 是否自关联
  68. * @return $this
  69. */
  70. public function selfRelation($self = true)
  71. {
  72. $this->selfRelation = $self;
  73. return $this;
  74. }
  75. /**
  76. * 当前关联是否为自关联
  77. * @access public
  78. * @return bool
  79. */
  80. public function isSelfRelation()
  81. {
  82. return $this->selfRelation;
  83. }
  84. /**
  85. * 封装关联数据集
  86. * @access public
  87. * @param array $resultSet 数据集
  88. * @return mixed
  89. */
  90. protected function resultSetBuild($resultSet)
  91. {
  92. return (new $this->model)->toCollection($resultSet);
  93. }
  94. protected function getQueryFields($model)
  95. {
  96. $fields = $this->query->getOptions('field');
  97. return $this->getRelationQueryFields($fields, $model);
  98. }
  99. protected function getRelationQueryFields($fields, $model)
  100. {
  101. if ($fields) {
  102. if (is_string($fields)) {
  103. $fields = explode(',', $fields);
  104. }
  105. foreach ($fields as &$field) {
  106. if (false === strpos($field, '.')) {
  107. $field = $model . '.' . $field;
  108. }
  109. }
  110. } else {
  111. $fields = $model . '.*';
  112. }
  113. return $fields;
  114. }
  115. protected function getQueryWhere(&$where, $relation)
  116. {
  117. foreach ($where as $key => &$val) {
  118. if (is_string($key)) {
  119. $where[] = [false === strpos($key, '.') ? $relation . '.' . $key : $key, '=', $val];
  120. unset($where[$key]);
  121. } elseif (isset($val[0]) && false === strpos($val[0], '.')) {
  122. $val[0] = $relation . '.' . $val[0];
  123. }
  124. }
  125. }
  126. /**
  127. * 更新数据
  128. * @access public
  129. * @param array $data 更新数据
  130. * @return integer|string
  131. */
  132. public function update(array $data = [])
  133. {
  134. return $this->query->update($data);
  135. }
  136. /**
  137. * 删除记录
  138. * @access public
  139. * @param mixed $data 表达式 true 表示强制删除
  140. * @return int
  141. * @throws Exception
  142. * @throws PDOException
  143. */
  144. public function delete($data = null)
  145. {
  146. return $this->query->delete($data);
  147. }
  148. /**
  149. * 执行基础查询(仅执行一次)
  150. * @access protected
  151. * @return void
  152. */
  153. protected function baseQuery()
  154. {}
  155. public function __call($method, $args)
  156. {
  157. if ($this->query) {
  158. // 执行基础查询
  159. $this->baseQuery();
  160. $result = call_user_func_array([$this->query->getModel(), $method], $args);
  161. return $result === $this->query && !in_array(strtolower($method), ['fetchsql', 'fetchpdo']) ? $this : $result;
  162. } else {
  163. throw new Exception('method not exists:' . __CLASS__ . '->' . $method);
  164. }
  165. }
  166. }