Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.5] Allow developers to extend Relationship Classes #22617

Merged
merged 15 commits into from
Jan 3, 2018
170 changes: 160 additions & 10 deletions src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
Expand Down Expand Up @@ -59,7 +60,21 @@ public function hasOne($related, $foreignKey = null, $localKey = null)

$localKey = $localKey ?: $this->getKeyName();

return new HasOne($instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey);
return $this->newHasOne($instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey);
}

/**
* Instantiate a new HasOne relationship.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $parent
* @param string $foreignKey
* @param string $localKey
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
protected function newHasOne(Builder $query, Model $parent, $foreignKey, $localKey)
{
return new HasOne($query, $parent, $foreignKey, $localKey);
}

/**
Expand All @@ -82,7 +97,22 @@ public function morphOne($related, $name, $type = null, $id = null, $localKey =

$localKey = $localKey ?: $this->getKeyName();

return new MorphOne($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id, $localKey);
return $this->newMorphOne($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id, $localKey);
}

/**
* Instantiate a new MorphOne relationship.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $parent
* @param string $type
* @param string $id
* @param string $localKey
* @return \Illuminate\Database\Eloquent\Relations\MorphOne
*/
protected function newMorphOne(Builder $query, Model $parent, $type, $id, $localKey)
{
return new MorphOne($query, $parent, $type, $id, $localKey);
}

/**
Expand Down Expand Up @@ -117,11 +147,28 @@ public function belongsTo($related, $foreignKey = null, $ownerKey = null, $relat
// actually be responsible for retrieving and hydrating every relations.
$ownerKey = $ownerKey ?: $instance->getKeyName();

return new BelongsTo(
return $this->newBelongsTo(
$instance->newQuery(), $this, $foreignKey, $ownerKey, $relation
);
}

/**
* Instantiate a new BelongsTo relationship.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $child
* @param string $foreignKey
* @param string $ownerKey
* @param string $relation
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
protected function newBelongsTo(Builder $query, Model $child, $foreignKey, $ownerKey, $relation)
{
return new BelongsTo(
$query, $child, $foreignKey, $ownerKey, $relation
);
}

/**
* Define a polymorphic, inverse one-to-one or many relationship.
*
Expand Down Expand Up @@ -159,7 +206,7 @@ public function morphTo($name = null, $type = null, $id = null)
*/
protected function morphEagerTo($name, $type, $id)
{
return new MorphTo(
return $this->newMorphTo(
$this->newQuery()->setEagerLoads([]), $this, $id, null, $type, $name
);
}
Expand All @@ -179,11 +226,27 @@ protected function morphInstanceTo($target, $name, $type, $id)
static::getActualClassNameForMorph($target)
);

return new MorphTo(
return $this->newMorphTo(
$instance->newQuery(), $this, $id, $instance->getKeyName(), $type, $name
);
}

/**
* Instantiate a new MorphTo relationship.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $parent
* @param string $foreignKey
* @param string $ownerKey
* @param string $type
* @param string $relation
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
*/
protected function newMorphTo(Builder $query, Model $parent, $foreignKey, $ownerKey, $type, $relation)
{
return new MorphTo($query, $parent, $foreignKey, $ownerKey, $type, $relation);
}

/**
* Retrieve the actual class name for a given morph class.
*
Expand Down Expand Up @@ -223,11 +286,25 @@ public function hasMany($related, $foreignKey = null, $localKey = null)

$localKey = $localKey ?: $this->getKeyName();

return new HasMany(
return $this->newHasMany(
$instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey
);
}

/**
* Instantiate a new HasMany relationship.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $parent
* @param string $foreignKey
* @param string $localKey
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
protected function newHasMany(Builder $query, Model $parent, $foreignKey, $localKey)
{
return new HasMany($query, $parent, $foreignKey, $localKey);
}

/**
* Define a has-many-through relationship.
*
Expand All @@ -253,7 +330,24 @@ public function hasManyThrough($related, $through, $firstKey = null, $secondKey

$instance = $this->newRelatedInstance($related);

return new HasManyThrough($instance->newQuery(), $this, $through, $firstKey, $secondKey, $localKey, $secondLocalKey);
return $this->newHasManyThrough($instance->newQuery(), $this, $through, $firstKey, $secondKey, $localKey, $secondLocalKey);
}

/**
* Instantiate a new HasManyThrough relationship.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $farParent
* @param \Illuminate\Database\Eloquent\Model $throughParent
* @param string $firstKey
* @param string $secondKey
* @param string $localKey
* @param string $secondLocalKey
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
*/
protected function newHasManyThrough(Builder $query, Model $farParent, Model $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey)
{
return new HasManyThrough($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);
}

/**
Expand All @@ -279,7 +373,22 @@ public function morphMany($related, $name, $type = null, $id = null, $localKey =

$localKey = $localKey ?: $this->getKeyName();

return new MorphMany($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id, $localKey);
return $this->newMorphMany($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id, $localKey);
}

/**
* Instantiate a new MorphMany relationship.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $parent
* @param string $type
* @param string $id
* @param string $localKey
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
*/
protected function newMorphMany(Builder $query, Model $parent, $type, $id, $localKey)
{
return new MorphMany($query, $parent, $type, $id, $localKey);
}

/**
Expand Down Expand Up @@ -320,13 +429,32 @@ public function belongsToMany($related, $table = null, $foreignPivotKey = null,
$table = $this->joiningTable($related);
}

return new BelongsToMany(
return $this->newBelongsToMany(
$instance->newQuery(), $this, $table, $foreignPivotKey,
$relatedPivotKey, $parentKey ?: $this->getKeyName(),
$relatedKey ?: $instance->getKeyName(), $relation
);
}

/**
* Instantiate a new BelongsToMany relationship.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $parent
* @param string $table
* @param string $foreignPivotKey
* @param string $relatedPivotKey
* @param string $parentKey
* @param string $relatedKey
* @param string $relationName
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
protected function newBelongsToMany(Builder $query, Model $parent, $table, $foreignPivotKey,
$relatedPivotKey, $parentKey, $relatedKey, $relationName = null)
{
return new BelongsToMany($query, $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName);
}

/**
* Define a polymorphic many-to-many relationship.
*
Expand Down Expand Up @@ -360,13 +488,35 @@ public function morphToMany($related, $name, $table = null, $foreignPivotKey = n
// appropriate query constraints then entirely manages the hydrations.
$table = $table ?: Str::plural($name);

return new MorphToMany(
return $this->newMorphToMany(
$instance->newQuery(), $this, $name, $table,
$foreignPivotKey, $relatedPivotKey, $parentKey ?: $this->getKeyName(),
$relatedKey ?: $instance->getKeyName(), $caller, $inverse
);
}

/**
* Instantiate a new HasManyThrough relationship.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $parent
* @param string $name
* @param string $table
* @param string $foreignPivotKey
* @param string $relatedPivotKey
* @param string $parentKey
* @param string $relatedKey
* @param string $relationName
* @param bool $inverse
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany
*/
protected function newMorphToMany(Builder $query, Model $parent, $name, $table, $foreignPivotKey,
$relatedPivotKey, $parentKey, $relatedKey, $relationName = null, $inverse = false)
{
return new MorphToMany($query, $parent, $name, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey,
$relationName, $inverse);
}

/**
* Define a polymorphic, inverse many-to-many relationship.
*
Expand Down
Loading