PageRenderTime 41ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/SafeForKids/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/BelongsTo.php

https://gitlab.com/rocs/Streaming-Safe-for-Kids
PHP | 328 lines | 132 code | 48 blank | 148 comment | 7 complexity | 3160f8b8e8c241a40b5fc09c14f49381 MD5 | raw file
  1. <?php
  2. namespace Illuminate\Database\Eloquent\Relations;
  3. use Illuminate\Database\Eloquent\Model;
  4. use Illuminate\Database\Eloquent\Builder;
  5. use Illuminate\Database\Query\Expression;
  6. use Illuminate\Database\Eloquent\Collection;
  7. class BelongsTo extends Relation
  8. {
  9. /**
  10. * The foreign key of the parent model.
  11. *
  12. * @var string
  13. */
  14. protected $foreignKey;
  15. /**
  16. * The associated key on the parent model.
  17. *
  18. * @var string
  19. */
  20. protected $otherKey;
  21. /**
  22. * The name of the relationship.
  23. *
  24. * @var string
  25. */
  26. protected $relation;
  27. /**
  28. * The count of self joins.
  29. *
  30. * @var int
  31. */
  32. protected static $selfJoinCount = 0;
  33. /**
  34. * Create a new belongs to relationship instance.
  35. *
  36. * @param \Illuminate\Database\Eloquent\Builder $query
  37. * @param \Illuminate\Database\Eloquent\Model $parent
  38. * @param string $foreignKey
  39. * @param string $otherKey
  40. * @param string $relation
  41. * @return void
  42. */
  43. public function __construct(Builder $query, Model $parent, $foreignKey, $otherKey, $relation)
  44. {
  45. $this->otherKey = $otherKey;
  46. $this->relation = $relation;
  47. $this->foreignKey = $foreignKey;
  48. parent::__construct($query, $parent);
  49. }
  50. /**
  51. * Get the results of the relationship.
  52. *
  53. * @return mixed
  54. */
  55. public function getResults()
  56. {
  57. return $this->query->first();
  58. }
  59. /**
  60. * Set the base constraints on the relation query.
  61. *
  62. * @return void
  63. */
  64. public function addConstraints()
  65. {
  66. if (static::$constraints) {
  67. // For belongs to relationships, which are essentially the inverse of has one
  68. // or has many relationships, we need to actually query on the primary key
  69. // of the related models matching on the foreign key that's on a parent.
  70. $table = $this->related->getTable();
  71. $this->query->where($table.'.'.$this->otherKey, '=', $this->parent->{$this->foreignKey});
  72. }
  73. }
  74. /**
  75. * Add the constraints for a relationship query.
  76. *
  77. * @param \Illuminate\Database\Eloquent\Builder $query
  78. * @param \Illuminate\Database\Eloquent\Builder $parent
  79. * @param array|mixed $columns
  80. * @return \Illuminate\Database\Eloquent\Builder
  81. */
  82. public function getRelationQuery(Builder $query, Builder $parent, $columns = ['*'])
  83. {
  84. if ($parent->getQuery()->from == $query->getQuery()->from) {
  85. return $this->getRelationQueryForSelfRelation($query, $parent, $columns);
  86. }
  87. $query->select($columns);
  88. $otherKey = $this->wrap($query->getModel()->getTable().'.'.$this->otherKey);
  89. return $query->where($this->getQualifiedForeignKey(), '=', new Expression($otherKey));
  90. }
  91. /**
  92. * Add the constraints for a relationship query on the same table.
  93. *
  94. * @param \Illuminate\Database\Eloquent\Builder $query
  95. * @param \Illuminate\Database\Eloquent\Builder $parent
  96. * @param array|mixed $columns
  97. * @return \Illuminate\Database\Eloquent\Builder
  98. */
  99. public function getRelationQueryForSelfRelation(Builder $query, Builder $parent, $columns = ['*'])
  100. {
  101. $query->select($columns);
  102. $query->from($query->getModel()->getTable().' as '.$hash = $this->getRelationCountHash());
  103. $query->getModel()->setTable($hash);
  104. $key = $this->wrap($this->getQualifiedForeignKey());
  105. return $query->where($hash.'.'.$query->getModel()->getKeyName(), '=', new Expression($key));
  106. }
  107. /**
  108. * Get a relationship join table hash.
  109. *
  110. * @return string
  111. */
  112. public function getRelationCountHash()
  113. {
  114. return 'laravel_reserved_'.static::$selfJoinCount++;
  115. }
  116. /**
  117. * Set the constraints for an eager load of the relation.
  118. *
  119. * @param array $models
  120. * @return void
  121. */
  122. public function addEagerConstraints(array $models)
  123. {
  124. // We'll grab the primary key name of the related models since it could be set to
  125. // a non-standard name and not "id". We will then construct the constraint for
  126. // our eagerly loading query so it returns the proper models from execution.
  127. $key = $this->related->getTable().'.'.$this->otherKey;
  128. $this->query->whereIn($key, $this->getEagerModelKeys($models));
  129. }
  130. /**
  131. * Gather the keys from an array of related models.
  132. *
  133. * @param array $models
  134. * @return array
  135. */
  136. protected function getEagerModelKeys(array $models)
  137. {
  138. $keys = [];
  139. // First we need to gather all of the keys from the parent models so we know what
  140. // to query for via the eager loading query. We will add them to an array then
  141. // execute a "where in" statement to gather up all of those related records.
  142. foreach ($models as $model) {
  143. if (! is_null($value = $model->{$this->foreignKey})) {
  144. $keys[] = $value;
  145. }
  146. }
  147. // If there are no keys that were not null we will just return an array with either
  148. // null or 0 in (depending on if incrementing keys are in use) so the query wont
  149. // fail plus returns zero results, which should be what the developer expects.
  150. if (count($keys) === 0) {
  151. return [$this->related->getIncrementing() &&
  152. $this->related->getKeyType() === 'int' ? 0 : null, ];
  153. }
  154. return array_values(array_unique($keys));
  155. }
  156. /**
  157. * Initialize the relation on a set of models.
  158. *
  159. * @param array $models
  160. * @param string $relation
  161. * @return array
  162. */
  163. public function initRelation(array $models, $relation)
  164. {
  165. foreach ($models as $model) {
  166. $model->setRelation($relation, null);
  167. }
  168. return $models;
  169. }
  170. /**
  171. * Match the eagerly loaded results to their parents.
  172. *
  173. * @param array $models
  174. * @param \Illuminate\Database\Eloquent\Collection $results
  175. * @param string $relation
  176. * @return array
  177. */
  178. public function match(array $models, Collection $results, $relation)
  179. {
  180. $foreign = $this->foreignKey;
  181. $other = $this->otherKey;
  182. // First we will get to build a dictionary of the child models by their primary
  183. // key of the relationship, then we can easily match the children back onto
  184. // the parents using that dictionary and the primary key of the children.
  185. $dictionary = [];
  186. foreach ($results as $result) {
  187. $dictionary[$result->getAttribute($other)] = $result;
  188. }
  189. // Once we have the dictionary constructed, we can loop through all the parents
  190. // and match back onto their children using these keys of the dictionary and
  191. // the primary key of the children to map them onto the correct instances.
  192. foreach ($models as $model) {
  193. if (isset($dictionary[$model->$foreign])) {
  194. $model->setRelation($relation, $dictionary[$model->$foreign]);
  195. }
  196. }
  197. return $models;
  198. }
  199. /**
  200. * Associate the model instance to the given parent.
  201. *
  202. * @param \Illuminate\Database\Eloquent\Model|int $model
  203. * @return \Illuminate\Database\Eloquent\Model
  204. */
  205. public function associate($model)
  206. {
  207. $otherKey = ($model instanceof Model ? $model->getAttribute($this->otherKey) : $model);
  208. $this->parent->setAttribute($this->foreignKey, $otherKey);
  209. if ($model instanceof Model) {
  210. $this->parent->setRelation($this->relation, $model);
  211. }
  212. return $this->parent;
  213. }
  214. /**
  215. * Dissociate previously associated model from the given parent.
  216. *
  217. * @return \Illuminate\Database\Eloquent\Model
  218. */
  219. public function dissociate()
  220. {
  221. $this->parent->setAttribute($this->foreignKey, null);
  222. return $this->parent->setRelation($this->relation, null);
  223. }
  224. /**
  225. * Update the parent model on the relationship.
  226. *
  227. * @param array $attributes
  228. * @return mixed
  229. */
  230. public function update(array $attributes)
  231. {
  232. $instance = $this->getResults();
  233. return $instance->fill($attributes)->save();
  234. }
  235. /**
  236. * Get the foreign key of the relationship.
  237. *
  238. * @return string
  239. */
  240. public function getForeignKey()
  241. {
  242. return $this->foreignKey;
  243. }
  244. /**
  245. * Get the fully qualified foreign key of the relationship.
  246. *
  247. * @return string
  248. */
  249. public function getQualifiedForeignKey()
  250. {
  251. return $this->parent->getTable().'.'.$this->foreignKey;
  252. }
  253. /**
  254. * Get the associated key of the relationship.
  255. *
  256. * @return string
  257. */
  258. public function getOtherKey()
  259. {
  260. return $this->otherKey;
  261. }
  262. /**
  263. * Get the name of the relationship.
  264. *
  265. * @return string
  266. */
  267. public function getRelation()
  268. {
  269. return $this->relation;
  270. }
  271. /**
  272. * Get the fully qualified associated key of the relationship.
  273. *
  274. * @return string
  275. */
  276. public function getQualifiedOtherKeyName()
  277. {
  278. return $this->related->getTable().'.'.$this->otherKey;
  279. }
  280. }