PageRenderTime 29ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/Relation.php

https://gitlab.com/Pasantias/pasantiasASLG
PHP | 349 lines | 130 code | 46 blank | 173 comment | 4 complexity | 7be5dfb03abc618147ff555d896d9bee MD5 | raw file
  1. <?php
  2. namespace Illuminate\Database\Eloquent\Relations;
  3. use Closure;
  4. use Illuminate\Support\Arr;
  5. use Illuminate\Database\Eloquent\Model;
  6. use Illuminate\Database\Eloquent\Builder;
  7. use Illuminate\Database\Query\Expression;
  8. use Illuminate\Database\Eloquent\Collection;
  9. abstract class Relation
  10. {
  11. /**
  12. * The Eloquent query builder instance.
  13. *
  14. * @var \Illuminate\Database\Eloquent\Builder
  15. */
  16. protected $query;
  17. /**
  18. * The parent model instance.
  19. *
  20. * @var \Illuminate\Database\Eloquent\Model
  21. */
  22. protected $parent;
  23. /**
  24. * The related model instance.
  25. *
  26. * @var \Illuminate\Database\Eloquent\Model
  27. */
  28. protected $related;
  29. /**
  30. * Indicates if the relation is adding constraints.
  31. *
  32. * @var bool
  33. */
  34. protected static $constraints = true;
  35. /**
  36. * An array to map class names to their morph names in database.
  37. *
  38. * @var array
  39. */
  40. protected static $morphMap = [];
  41. /**
  42. * Create a new relation instance.
  43. *
  44. * @param \Illuminate\Database\Eloquent\Builder $query
  45. * @param \Illuminate\Database\Eloquent\Model $parent
  46. * @return void
  47. */
  48. public function __construct(Builder $query, Model $parent)
  49. {
  50. $this->query = $query;
  51. $this->parent = $parent;
  52. $this->related = $query->getModel();
  53. $this->addConstraints();
  54. }
  55. /**
  56. * Set the base constraints on the relation query.
  57. *
  58. * @return void
  59. */
  60. abstract public function addConstraints();
  61. /**
  62. * Set the constraints for an eager load of the relation.
  63. *
  64. * @param array $models
  65. * @return void
  66. */
  67. abstract public function addEagerConstraints(array $models);
  68. /**
  69. * Initialize the relation on a set of models.
  70. *
  71. * @param array $models
  72. * @param string $relation
  73. * @return array
  74. */
  75. abstract public function initRelation(array $models, $relation);
  76. /**
  77. * Match the eagerly loaded results to their parents.
  78. *
  79. * @param array $models
  80. * @param \Illuminate\Database\Eloquent\Collection $results
  81. * @param string $relation
  82. * @return array
  83. */
  84. abstract public function match(array $models, Collection $results, $relation);
  85. /**
  86. * Get the results of the relationship.
  87. *
  88. * @return mixed
  89. */
  90. abstract public function getResults();
  91. /**
  92. * Get the relationship for eager loading.
  93. *
  94. * @return \Illuminate\Database\Eloquent\Collection
  95. */
  96. public function getEager()
  97. {
  98. return $this->get();
  99. }
  100. /**
  101. * Touch all of the related models for the relationship.
  102. *
  103. * @return void
  104. */
  105. public function touch()
  106. {
  107. $column = $this->getRelated()->getUpdatedAtColumn();
  108. $this->rawUpdate([$column => $this->getRelated()->freshTimestampString()]);
  109. }
  110. /**
  111. * Run a raw update against the base query.
  112. *
  113. * @param array $attributes
  114. * @return int
  115. */
  116. public function rawUpdate(array $attributes = [])
  117. {
  118. return $this->query->update($attributes);
  119. }
  120. /**
  121. * Add the constraints for a relationship count query.
  122. *
  123. * @param \Illuminate\Database\Eloquent\Builder $query
  124. * @param \Illuminate\Database\Eloquent\Builder $parent
  125. * @return \Illuminate\Database\Eloquent\Builder
  126. */
  127. public function getRelationCountQuery(Builder $query, Builder $parent)
  128. {
  129. $query->select(new Expression('count(*)'));
  130. $key = $this->wrap($this->getQualifiedParentKeyName());
  131. return $query->where($this->getHasCompareKey(), '=', new Expression($key));
  132. }
  133. /**
  134. * Run a callback with constraints disabled on the relation.
  135. *
  136. * @param \Closure $callback
  137. * @return mixed
  138. */
  139. public static function noConstraints(Closure $callback)
  140. {
  141. $previous = static::$constraints;
  142. static::$constraints = false;
  143. // When resetting the relation where clause, we want to shift the first element
  144. // off of the bindings, leaving only the constraints that the developers put
  145. // as "extra" on the relationships, and not original relation constraints.
  146. try {
  147. $results = call_user_func($callback);
  148. } finally {
  149. static::$constraints = $previous;
  150. }
  151. return $results;
  152. }
  153. /**
  154. * Get all of the primary keys for an array of models.
  155. *
  156. * @param array $models
  157. * @param string $key
  158. * @return array
  159. */
  160. protected function getKeys(array $models, $key = null)
  161. {
  162. return array_unique(array_values(array_map(function ($value) use ($key) {
  163. return $key ? $value->getAttribute($key) : $value->getKey();
  164. }, $models)));
  165. }
  166. /**
  167. * Get the underlying query for the relation.
  168. *
  169. * @return \Illuminate\Database\Eloquent\Builder
  170. */
  171. public function getQuery()
  172. {
  173. return $this->query;
  174. }
  175. /**
  176. * Get the base query builder driving the Eloquent builder.
  177. *
  178. * @return \Illuminate\Database\Query\Builder
  179. */
  180. public function getBaseQuery()
  181. {
  182. return $this->query->getQuery();
  183. }
  184. /**
  185. * Get the parent model of the relation.
  186. *
  187. * @return \Illuminate\Database\Eloquent\Model
  188. */
  189. public function getParent()
  190. {
  191. return $this->parent;
  192. }
  193. /**
  194. * Get the fully qualified parent key name.
  195. *
  196. * @return string
  197. */
  198. public function getQualifiedParentKeyName()
  199. {
  200. return $this->parent->getQualifiedKeyName();
  201. }
  202. /**
  203. * Get the related model of the relation.
  204. *
  205. * @return \Illuminate\Database\Eloquent\Model
  206. */
  207. public function getRelated()
  208. {
  209. return $this->related;
  210. }
  211. /**
  212. * Get the name of the "created at" column.
  213. *
  214. * @return string
  215. */
  216. public function createdAt()
  217. {
  218. return $this->parent->getCreatedAtColumn();
  219. }
  220. /**
  221. * Get the name of the "updated at" column.
  222. *
  223. * @return string
  224. */
  225. public function updatedAt()
  226. {
  227. return $this->parent->getUpdatedAtColumn();
  228. }
  229. /**
  230. * Get the name of the related model's "updated at" column.
  231. *
  232. * @return string
  233. */
  234. public function relatedUpdatedAt()
  235. {
  236. return $this->related->getUpdatedAtColumn();
  237. }
  238. /**
  239. * Wrap the given value with the parent query's grammar.
  240. *
  241. * @param string $value
  242. * @return string
  243. */
  244. public function wrap($value)
  245. {
  246. return $this->parent->newQueryWithoutScopes()->getQuery()->getGrammar()->wrap($value);
  247. }
  248. /**
  249. * Set or get the morph map for polymorphic relations.
  250. *
  251. * @param array|null $map
  252. * @param bool $merge
  253. * @return array
  254. */
  255. public static function morphMap(array $map = null, $merge = true)
  256. {
  257. $map = static::buildMorphMapFromModels($map);
  258. if (is_array($map)) {
  259. static::$morphMap = $merge ? array_merge(static::$morphMap, $map) : $map;
  260. }
  261. return static::$morphMap;
  262. }
  263. /**
  264. * Builds a table-keyed array from model class names.
  265. *
  266. * @param string[]|null $models
  267. * @return array|null
  268. */
  269. protected static function buildMorphMapFromModels(array $models = null)
  270. {
  271. if (is_null($models) || Arr::isAssoc($models)) {
  272. return $models;
  273. }
  274. $tables = array_map(function ($model) {
  275. return (new $model)->getTable();
  276. }, $models);
  277. return array_combine($tables, $models);
  278. }
  279. /**
  280. * Handle dynamic method calls to the relationship.
  281. *
  282. * @param string $method
  283. * @param array $parameters
  284. * @return mixed
  285. */
  286. public function __call($method, $parameters)
  287. {
  288. $result = call_user_func_array([$this->query, $method], $parameters);
  289. if ($result === $this->query) {
  290. return $this;
  291. }
  292. return $result;
  293. }
  294. /**
  295. * Force a clone of the underlying query builder when cloning.
  296. *
  297. * @return void
  298. */
  299. public function __clone()
  300. {
  301. $this->query = clone $this->query;
  302. }
  303. }