MorphOne.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <?php
  2. namespace Illuminate\Database\Eloquent\Relations;
  3. use Illuminate\Contracts\Database\Eloquent\SupportsPartialRelations;
  4. use Illuminate\Database\Eloquent\Builder;
  5. use Illuminate\Database\Eloquent\Collection;
  6. use Illuminate\Database\Eloquent\Model;
  7. use Illuminate\Database\Eloquent\Relations\Concerns\CanBeOneOfMany;
  8. use Illuminate\Database\Eloquent\Relations\Concerns\ComparesRelatedModels;
  9. use Illuminate\Database\Eloquent\Relations\Concerns\SupportsDefaultModels;
  10. use Illuminate\Database\Query\JoinClause;
  11. class MorphOne extends MorphOneOrMany implements SupportsPartialRelations
  12. {
  13. use CanBeOneOfMany, ComparesRelatedModels, SupportsDefaultModels;
  14. /**
  15. * Get the results of the relationship.
  16. *
  17. * @return mixed
  18. */
  19. public function getResults()
  20. {
  21. if (is_null($this->getParentKey())) {
  22. return $this->getDefaultFor($this->parent);
  23. }
  24. return $this->query->first() ?: $this->getDefaultFor($this->parent);
  25. }
  26. /**
  27. * Initialize the relation on a set of models.
  28. *
  29. * @param array $models
  30. * @param string $relation
  31. * @return array
  32. */
  33. public function initRelation(array $models, $relation)
  34. {
  35. foreach ($models as $model) {
  36. $model->setRelation($relation, $this->getDefaultFor($model));
  37. }
  38. return $models;
  39. }
  40. /**
  41. * Match the eagerly loaded results to their parents.
  42. *
  43. * @param array $models
  44. * @param \Illuminate\Database\Eloquent\Collection $results
  45. * @param string $relation
  46. * @return array
  47. */
  48. public function match(array $models, Collection $results, $relation)
  49. {
  50. return $this->matchOne($models, $results, $relation);
  51. }
  52. /**
  53. * Get the relationship query.
  54. *
  55. * @param \Illuminate\Database\Eloquent\Builder $query
  56. * @param \Illuminate\Database\Eloquent\Builder $parentQuery
  57. * @param array|mixed $columns
  58. * @return \Illuminate\Database\Eloquent\Builder
  59. */
  60. public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])
  61. {
  62. if ($this->isOneOfMany()) {
  63. $this->mergeOneOfManyJoinsTo($query);
  64. }
  65. return parent::getRelationExistenceQuery($query, $parentQuery, $columns);
  66. }
  67. /**
  68. * Add constraints for inner join subselect for one of many relationships.
  69. *
  70. * @param \Illuminate\Database\Eloquent\Builder $query
  71. * @param string|null $column
  72. * @param string|null $aggregate
  73. * @return void
  74. */
  75. public function addOneOfManySubQueryConstraints(Builder $query, $column = null, $aggregate = null)
  76. {
  77. $query->addSelect($this->foreignKey, $this->morphType);
  78. }
  79. /**
  80. * Get the columns that should be selected by the one of many subquery.
  81. *
  82. * @return array|string
  83. */
  84. public function getOneOfManySubQuerySelectColumns()
  85. {
  86. return [$this->foreignKey, $this->morphType];
  87. }
  88. /**
  89. * Add join query constraints for one of many relationships.
  90. *
  91. * @param \Illuminate\Database\Query\JoinClause $join
  92. * @return void
  93. */
  94. public function addOneOfManyJoinSubQueryConstraints(JoinClause $join)
  95. {
  96. $join
  97. ->on($this->qualifySubSelectColumn($this->morphType), '=', $this->qualifyRelatedColumn($this->morphType))
  98. ->on($this->qualifySubSelectColumn($this->foreignKey), '=', $this->qualifyRelatedColumn($this->foreignKey));
  99. }
  100. /**
  101. * Make a new related instance for the given model.
  102. *
  103. * @param \Illuminate\Database\Eloquent\Model $parent
  104. * @return \Illuminate\Database\Eloquent\Model
  105. */
  106. public function newRelatedInstanceFor(Model $parent)
  107. {
  108. return $this->related->newInstance()
  109. ->setAttribute($this->getForeignKeyName(), $parent->{$this->localKey})
  110. ->setAttribute($this->getMorphType(), $this->morphClass);
  111. }
  112. /**
  113. * Get the value of the model's foreign key.
  114. *
  115. * @param \Illuminate\Database\Eloquent\Model $model
  116. * @return mixed
  117. */
  118. protected function getRelatedKeyFrom(Model $model)
  119. {
  120. return $model->getAttribute($this->getForeignKeyName());
  121. }
  122. }