138 lines
4.2 KiB
PHP
138 lines
4.2 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace Illuminate\Database\Eloquent\Relations;
|
||
|
|
||
|
use Illuminate\Contracts\Database\Eloquent\SupportsPartialRelations;
|
||
|
use Illuminate\Database\Eloquent\Builder;
|
||
|
use Illuminate\Database\Eloquent\Collection;
|
||
|
use Illuminate\Database\Eloquent\Model;
|
||
|
use Illuminate\Database\Eloquent\Relations\Concerns\CanBeOneOfMany;
|
||
|
use Illuminate\Database\Eloquent\Relations\Concerns\ComparesRelatedModels;
|
||
|
use Illuminate\Database\Eloquent\Relations\Concerns\SupportsDefaultModels;
|
||
|
use Illuminate\Database\Query\JoinClause;
|
||
|
|
||
|
class MorphOne extends MorphOneOrMany implements SupportsPartialRelations
|
||
|
{
|
||
|
use CanBeOneOfMany, ComparesRelatedModels, SupportsDefaultModels;
|
||
|
|
||
|
/**
|
||
|
* Get the results of the relationship.
|
||
|
*
|
||
|
* @return mixed
|
||
|
*/
|
||
|
public function getResults()
|
||
|
{
|
||
|
if (is_null($this->getParentKey())) {
|
||
|
return $this->getDefaultFor($this->parent);
|
||
|
}
|
||
|
|
||
|
return $this->query->first() ?: $this->getDefaultFor($this->parent);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Initialize the relation on a set of models.
|
||
|
*
|
||
|
* @param array $models
|
||
|
* @param string $relation
|
||
|
* @return array
|
||
|
*/
|
||
|
public function initRelation(array $models, $relation)
|
||
|
{
|
||
|
foreach ($models as $model) {
|
||
|
$model->setRelation($relation, $this->getDefaultFor($model));
|
||
|
}
|
||
|
|
||
|
return $models;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Match the eagerly loaded results to their parents.
|
||
|
*
|
||
|
* @param array $models
|
||
|
* @param \Illuminate\Database\Eloquent\Collection $results
|
||
|
* @param string $relation
|
||
|
* @return array
|
||
|
*/
|
||
|
public function match(array $models, Collection $results, $relation)
|
||
|
{
|
||
|
return $this->matchOne($models, $results, $relation);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the relationship query.
|
||
|
*
|
||
|
* @param \Illuminate\Database\Eloquent\Builder $query
|
||
|
* @param \Illuminate\Database\Eloquent\Builder $parentQuery
|
||
|
* @param array|mixed $columns
|
||
|
* @return \Illuminate\Database\Eloquent\Builder
|
||
|
*/
|
||
|
public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])
|
||
|
{
|
||
|
if ($this->isOneOfMany()) {
|
||
|
$this->mergeOneOfManyJoinsTo($query);
|
||
|
}
|
||
|
|
||
|
return parent::getRelationExistenceQuery($query, $parentQuery, $columns);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add constraints for inner join subselect for one of many relationships.
|
||
|
*
|
||
|
* @param \Illuminate\Database\Eloquent\Builder $query
|
||
|
* @param string|null $column
|
||
|
* @param string|null $aggregate
|
||
|
* @return void
|
||
|
*/
|
||
|
public function addOneOfManySubQueryConstraints(Builder $query, $column = null, $aggregate = null)
|
||
|
{
|
||
|
$query->addSelect($this->foreignKey, $this->morphType);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the columns that should be selected by the one of many subquery.
|
||
|
*
|
||
|
* @return array|string
|
||
|
*/
|
||
|
public function getOneOfManySubQuerySelectColumns()
|
||
|
{
|
||
|
return [$this->foreignKey, $this->morphType];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add join query constraints for one of many relationships.
|
||
|
*
|
||
|
* @param \Illuminate\Database\Query\JoinClause $join
|
||
|
* @return void
|
||
|
*/
|
||
|
public function addOneOfManyJoinSubQueryConstraints(JoinClause $join)
|
||
|
{
|
||
|
$join
|
||
|
->on($this->qualifySubSelectColumn($this->morphType), '=', $this->qualifyRelatedColumn($this->morphType))
|
||
|
->on($this->qualifySubSelectColumn($this->foreignKey), '=', $this->qualifyRelatedColumn($this->foreignKey));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Make a new related instance for the given model.
|
||
|
*
|
||
|
* @param \Illuminate\Database\Eloquent\Model $parent
|
||
|
* @return \Illuminate\Database\Eloquent\Model
|
||
|
*/
|
||
|
public function newRelatedInstanceFor(Model $parent)
|
||
|
{
|
||
|
return $this->related->newInstance()
|
||
|
->setAttribute($this->getForeignKeyName(), $parent->{$this->localKey})
|
||
|
->setAttribute($this->getMorphType(), $this->morphClass);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the value of the model's foreign key.
|
||
|
*
|
||
|
* @param \Illuminate\Database\Eloquent\Model $model
|
||
|
* @return mixed
|
||
|
*/
|
||
|
protected function getRelatedKeyFrom(Model $model)
|
||
|
{
|
||
|
return $model->getAttribute($this->getForeignKeyName());
|
||
|
}
|
||
|
}
|