PendingHasThroughRelationship.php
TLDR
This file contains a class called PendingHasThroughRelationship
that is used to create pending has-many-through or has-one-through relationships in Laravel Eloquent ORM.
Methods
__construct($rootModel, $localRelationship)
This method is the constructor of the PendingHasThroughRelationship
class. It accepts two parameters: $rootModel
is the root model that the relationship exists on, and $localRelationship
is the local relationship.
has($callback)
This method is used to define the distant relationship that the model has. It accepts a $callback
parameter, which can be either a string or a callable. If the callback is a string, the method uses a closure to define the relationship using the local relationship's related model. The method then determines the type of relationship (has-many or has-one) and creates the appropriate relationship using the hasManyThrough
or hasOneThrough
methods of the root model.
__call($method, $parameters)
This method handles dynamic method calls into the model. If the method starts with has
, it calls the has
method passing the relationship name as a parameter. If the method does not exist, it throws a BadMethodCallException
with an error message.
Classes
No classes in this file.
<?php
namespace Illuminate\Database\Eloquent;
use BadMethodCallException;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Str;
class PendingHasThroughRelationship
{
/**
* The root model that the relationship exists on.
*
* @var \Illuminate\Database\Eloquent\Model
*/
protected $rootModel;
/**
* The local relationship.
*
* @var \Illuminate\Database\Eloquent\Relations\HasMany|\Illuminate\Database\Eloquent\Relations\HasOne
*/
protected $localRelationship;
/**
* Create a pending has-many-through or has-one-through relationship.
*
* @param \Illuminate\Database\Eloquent\Model $rootModel
* @param \Illuminate\Database\Eloquent\Relations\HasMany|\Illuminate\Database\Eloquent\Relations\HasOne $localRelationship
*/
public function __construct($rootModel, $localRelationship)
{
$this->rootModel = $rootModel;
$this->localRelationship = $localRelationship;
}
/**
* Define the distant relationship that this model has.
*
* @param string|(callable(\Illuminate\Database\Eloquent\Model): (\Illuminate\Database\Eloquent\Relations\HasOne|\Illuminate\Database\Eloquent\Relations\HasMany)) $callback
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough|\Illuminate\Database\Eloquent\Relations\HasOneThrough
*/
public function has($callback)
{
if (is_string($callback)) {
$callback = fn () => $this->localRelationship->getRelated()->{$callback}();
}
$distantRelation = $callback($this->localRelationship->getRelated());
if ($distantRelation instanceof HasMany) {
return $this->rootModel->hasManyThrough(
$distantRelation->getRelated()::class,
$this->localRelationship->getRelated()::class,
$this->localRelationship->getForeignKeyName(),
$distantRelation->getForeignKeyName(),
$this->localRelationship->getLocalKeyName(),
$distantRelation->getLocalKeyName(),
);
}
return $this->rootModel->hasOneThrough(
$distantRelation->getRelated()::class,
$this->localRelationship->getRelated()::class,
$this->localRelationship->getForeignKeyName(),
$distantRelation->getForeignKeyName(),
$this->localRelationship->getLocalKeyName(),
$distantRelation->getLocalKeyName(),
);
}
/**
* Handle dynamic method calls into the model.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
if (Str::startsWith($method, 'has')) {
return $this->has(Str::of($method)->after('has')->lcfirst()->toString());
}
throw new BadMethodCallException(sprintf(
'Call to undefined method %s::%s()', static::class, $method
));
}
}