Added vendor/ directory for Composer's installed files
This commit is contained in:
310
vendor/illuminate/database/Eloquent/Relations/BelongsTo.php
vendored
Executable file
310
vendor/illuminate/database/Eloquent/Relations/BelongsTo.php
vendored
Executable file
@ -0,0 +1,310 @@
|
||||
<?php namespace Illuminate\Database\Eloquent\Relations;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Query\Expression;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class BelongsTo extends Relation {
|
||||
|
||||
/**
|
||||
* The foreign key of the parent model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $foreignKey;
|
||||
|
||||
/**
|
||||
* The associated key on the parent model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $otherKey;
|
||||
|
||||
/**
|
||||
* The name of the relationship.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $relation;
|
||||
|
||||
/**
|
||||
* Create a new belongs to relationship instance.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Illuminate\Database\Eloquent\Model $parent
|
||||
* @param string $foreignKey
|
||||
* @param string $otherKey
|
||||
* @param string $relation
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Builder $query, Model $parent, $foreignKey, $otherKey, $relation)
|
||||
{
|
||||
$this->otherKey = $otherKey;
|
||||
$this->relation = $relation;
|
||||
$this->foreignKey = $foreignKey;
|
||||
|
||||
parent::__construct($query, $parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the results of the relationship.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResults()
|
||||
{
|
||||
return $this->query->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the base constraints on the relation query.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addConstraints()
|
||||
{
|
||||
if (static::$constraints)
|
||||
{
|
||||
// For belongs to relationships, which are essentially the inverse of has one
|
||||
// or has many relationships, we need to actually query on the primary key
|
||||
// of the related models matching on the foreign key that's on a parent.
|
||||
$table = $this->related->getTable();
|
||||
|
||||
$this->query->where($table.'.'.$this->otherKey, '=', $this->parent->{$this->foreignKey});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the constraints for a relationship count query.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Illuminate\Database\Eloquent\Builder $parent
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function getRelationCountQuery(Builder $query, Builder $parent)
|
||||
{
|
||||
if ($parent->getQuery()->from == $query->getQuery()->from)
|
||||
{
|
||||
return $this->getRelationCountQueryForSelfRelation($query, $parent);
|
||||
}
|
||||
|
||||
$query->select(new Expression('count(*)'));
|
||||
|
||||
$otherKey = $this->wrap($query->getModel()->getTable().'.'.$this->otherKey);
|
||||
|
||||
return $query->where($this->getQualifiedForeignKey(), '=', new Expression($otherKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the constraints for a relationship count query on the same table.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Illuminate\Database\Eloquent\Builder $parent
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function getRelationCountQueryForSelfRelation(Builder $query, Builder $parent)
|
||||
{
|
||||
$query->select(new Expression('count(*)'));
|
||||
|
||||
$tablePrefix = $this->query->getQuery()->getConnection()->getTablePrefix();
|
||||
|
||||
$query->from($query->getModel()->getTable().' as '.$tablePrefix.$hash = $this->getRelationCountHash());
|
||||
|
||||
$key = $this->wrap($this->getQualifiedForeignKey());
|
||||
|
||||
return $query->where($hash.'.'.$query->getModel()->getKeyName(), '=', new Expression($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a relationship join table hash.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRelationCountHash()
|
||||
{
|
||||
return 'self_'.md5(microtime(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the constraints for an eager load of the relation.
|
||||
*
|
||||
* @param array $models
|
||||
* @return void
|
||||
*/
|
||||
public function addEagerConstraints(array $models)
|
||||
{
|
||||
// We'll grab the primary key name of the related models since it could be set to
|
||||
// a non-standard name and not "id". We will then construct the constraint for
|
||||
// our eagerly loading query so it returns the proper models from execution.
|
||||
$key = $this->related->getTable().'.'.$this->otherKey;
|
||||
|
||||
$this->query->whereIn($key, $this->getEagerModelKeys($models));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather the keys from an array of related models.
|
||||
*
|
||||
* @param array $models
|
||||
* @return array
|
||||
*/
|
||||
protected function getEagerModelKeys(array $models)
|
||||
{
|
||||
$keys = array();
|
||||
|
||||
// First we need to gather all of the keys from the parent models so we know what
|
||||
// to query for via the eager loading query. We will add them to an array then
|
||||
// execute a "where in" statement to gather up all of those related records.
|
||||
foreach ($models as $model)
|
||||
{
|
||||
if ( ! is_null($value = $model->{$this->foreignKey}))
|
||||
{
|
||||
$keys[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no keys that were not null we will just return an array with 0 in
|
||||
// it so the query doesn't fail, but will not return any results, which should
|
||||
// be what this developer is expecting in a case where this happens to them.
|
||||
if (count($keys) == 0)
|
||||
{
|
||||
return array(0);
|
||||
}
|
||||
|
||||
return array_values(array_unique($keys));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, null);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
$foreign = $this->foreignKey;
|
||||
|
||||
$other = $this->otherKey;
|
||||
|
||||
// First we will get to build a dictionary of the child models by their primary
|
||||
// key of the relationship, then we can easily match the children back onto
|
||||
// the parents using that dictionary and the primary key of the children.
|
||||
$dictionary = array();
|
||||
|
||||
foreach ($results as $result)
|
||||
{
|
||||
$dictionary[$result->getAttribute($other)] = $result;
|
||||
}
|
||||
|
||||
// Once we have the dictionary constructed, we can loop through all the parents
|
||||
// and match back onto their children using these keys of the dictionary and
|
||||
// the primary key of the children to map them onto the correct instances.
|
||||
foreach ($models as $model)
|
||||
{
|
||||
if (isset($dictionary[$model->$foreign]))
|
||||
{
|
||||
$model->setRelation($relation, $dictionary[$model->$foreign]);
|
||||
}
|
||||
}
|
||||
|
||||
return $models;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate the model instance to the given parent.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function associate(Model $model)
|
||||
{
|
||||
$this->parent->setAttribute($this->foreignKey, $model->getAttribute($this->otherKey));
|
||||
|
||||
return $this->parent->setRelation($this->relation, $model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dissociate previously associated model from the given parent.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function dissociate()
|
||||
{
|
||||
$this->parent->setAttribute($this->foreignKey, null);
|
||||
|
||||
return $this->parent->setRelation($this->relation, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the parent model on the relationship.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return mixed
|
||||
*/
|
||||
public function update(array $attributes)
|
||||
{
|
||||
$instance = $this->getResults();
|
||||
|
||||
return $instance->fill($attributes)->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the foreign key of the relationship.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getForeignKey()
|
||||
{
|
||||
return $this->foreignKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fully qualified foreign key of the relationship.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQualifiedForeignKey()
|
||||
{
|
||||
return $this->parent->getTable().'.'.$this->foreignKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the associated key of the relationship.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOtherKey()
|
||||
{
|
||||
return $this->otherKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fully qualified associated key of the relationship.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQualifiedOtherKeyName()
|
||||
{
|
||||
return $this->related->getTable().'.'.$this->otherKey;
|
||||
}
|
||||
|
||||
}
|
1195
vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php
vendored
Executable file
1195
vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php
vendored
Executable file
File diff suppressed because it is too large
Load Diff
47
vendor/illuminate/database/Eloquent/Relations/HasMany.php
vendored
Executable file
47
vendor/illuminate/database/Eloquent/Relations/HasMany.php
vendored
Executable file
@ -0,0 +1,47 @@
|
||||
<?php namespace Illuminate\Database\Eloquent\Relations;
|
||||
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class HasMany extends HasOneOrMany {
|
||||
|
||||
/**
|
||||
* Get the results of the relationship.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResults()
|
||||
{
|
||||
return $this->query->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->related->newCollection());
|
||||
}
|
||||
|
||||
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->matchMany($models, $results, $relation);
|
||||
}
|
||||
|
||||
}
|
340
vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php
vendored
Executable file
340
vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php
vendored
Executable file
@ -0,0 +1,340 @@
|
||||
<?php namespace Illuminate\Database\Eloquent\Relations;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Query\Expression;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class HasManyThrough extends Relation {
|
||||
|
||||
/**
|
||||
* The distance parent model instance.
|
||||
*
|
||||
* @var \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
protected $farParent;
|
||||
|
||||
/**
|
||||
* The near key on the relationship.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $firstKey;
|
||||
|
||||
/**
|
||||
* The far key on the relationship.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $secondKey;
|
||||
|
||||
/**
|
||||
* Create a new has many through relationship instance.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Illuminate\Database\Eloquent\Model $farParent
|
||||
* @param \Illuminate\Database\Eloquent\Model $parent
|
||||
* @param string $firstKey
|
||||
* @param string $secondKey
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Builder $query, Model $farParent, Model $parent, $firstKey, $secondKey)
|
||||
{
|
||||
$this->firstKey = $firstKey;
|
||||
$this->secondKey = $secondKey;
|
||||
$this->farParent = $farParent;
|
||||
|
||||
parent::__construct($query, $parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the base constraints on the relation query.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addConstraints()
|
||||
{
|
||||
$parentTable = $this->parent->getTable();
|
||||
|
||||
$this->setJoin();
|
||||
|
||||
if (static::$constraints)
|
||||
{
|
||||
$this->query->where($parentTable.'.'.$this->firstKey, '=', $this->farParent->getKey());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the constraints for a relationship count query.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Illuminate\Database\Eloquent\Builder $parent
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function getRelationCountQuery(Builder $query, Builder $parent)
|
||||
{
|
||||
$parentTable = $this->parent->getTable();
|
||||
|
||||
$this->setJoin($query);
|
||||
|
||||
$query->select(new Expression('count(*)'));
|
||||
|
||||
$key = $this->wrap($parentTable.'.'.$this->firstKey);
|
||||
|
||||
return $query->where($this->getHasCompareKey(), '=', new Expression($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the join clause on the query.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder|null $query
|
||||
* @return void
|
||||
*/
|
||||
protected function setJoin(Builder $query = null)
|
||||
{
|
||||
$query = $query ?: $this->query;
|
||||
|
||||
$foreignKey = $this->related->getTable().'.'.$this->secondKey;
|
||||
|
||||
$query->join($this->parent->getTable(), $this->getQualifiedParentKeyName(), '=', $foreignKey);
|
||||
|
||||
if ($this->parentSoftDeletes())
|
||||
{
|
||||
$query->whereNull($this->parent->getQualifiedDeletedAtColumn());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether close parent of the relation uses Soft Deletes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function parentSoftDeletes()
|
||||
{
|
||||
return in_array('Illuminate\Database\Eloquent\SoftDeletes', class_uses_recursive(get_class($this->parent)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the constraints for an eager load of the relation.
|
||||
*
|
||||
* @param array $models
|
||||
* @return void
|
||||
*/
|
||||
public function addEagerConstraints(array $models)
|
||||
{
|
||||
$table = $this->parent->getTable();
|
||||
|
||||
$this->query->whereIn($table.'.'.$this->firstKey, $this->getKeys($models));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->related->newCollection());
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
$dictionary = $this->buildDictionary($results);
|
||||
|
||||
// Once we have the dictionary we can simply spin through the parent models to
|
||||
// link them up with their children using the keyed dictionary to make the
|
||||
// matching very convenient and easy work. Then we'll just return them.
|
||||
foreach ($models as $model)
|
||||
{
|
||||
$key = $model->getKey();
|
||||
|
||||
if (isset($dictionary[$key]))
|
||||
{
|
||||
$value = $this->related->newCollection($dictionary[$key]);
|
||||
|
||||
$model->setRelation($relation, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $models;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build model dictionary keyed by the relation's foreign key.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Collection $results
|
||||
* @return array
|
||||
*/
|
||||
protected function buildDictionary(Collection $results)
|
||||
{
|
||||
$dictionary = [];
|
||||
|
||||
$foreign = $this->firstKey;
|
||||
|
||||
// First we will create a dictionary of models keyed by the foreign key of the
|
||||
// relationship as this will allow us to quickly access all of the related
|
||||
// models without having to do nested looping which will be quite slow.
|
||||
foreach ($results as $result)
|
||||
{
|
||||
$dictionary[$result->{$foreign}][] = $result;
|
||||
}
|
||||
|
||||
return $dictionary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the results of the relationship.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResults()
|
||||
{
|
||||
return $this->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the query and get the first related model.
|
||||
*
|
||||
* @param array $columns
|
||||
* @return mixed
|
||||
*/
|
||||
public function first($columns = ['*'])
|
||||
{
|
||||
$results = $this->take(1)->get($columns);
|
||||
|
||||
return count($results) > 0 ? $results->first() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a related model by its primary key.
|
||||
*
|
||||
* @param mixed $id
|
||||
* @param array $columns
|
||||
* @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|null
|
||||
*/
|
||||
public function find($id, $columns = ['*'])
|
||||
{
|
||||
if (is_array($id))
|
||||
{
|
||||
return $this->findMany($id, $columns);
|
||||
}
|
||||
|
||||
$this->where($this->getRelated()->getQualifiedKeyName(), '=', $id);
|
||||
|
||||
return $this->first($columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find multiple related models by their primary keys.
|
||||
*
|
||||
* @param mixed $ids
|
||||
* @param array $columns
|
||||
* @return \Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
public function findMany($ids, $columns = ['*'])
|
||||
{
|
||||
if (empty($ids)) return $this->getRelated()->newCollection();
|
||||
|
||||
$this->whereIn($this->getRelated()->getQualifiedKeyName(), $ids);
|
||||
|
||||
return $this->get($columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the query as a "select" statement.
|
||||
*
|
||||
* @param array $columns
|
||||
* @return \Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
public function get($columns = ['*'])
|
||||
{
|
||||
// First we'll add the proper select columns onto the query so it is run with
|
||||
// the proper columns. Then, we will get the results and hydrate out pivot
|
||||
// models with the result of those columns as a separate model relation.
|
||||
$columns = $this->query->getQuery()->columns ? [] : $columns;
|
||||
|
||||
$select = $this->getSelectColumns($columns);
|
||||
|
||||
$models = $this->query->addSelect($select)->getModels();
|
||||
|
||||
// If we actually found models we will also eager load any relationships that
|
||||
// have been specified as needing to be eager loaded. This will solve the
|
||||
// n + 1 query problem for the developer and also increase performance.
|
||||
if (count($models) > 0)
|
||||
{
|
||||
$models = $this->query->eagerLoadRelations($models);
|
||||
}
|
||||
|
||||
return $this->related->newCollection($models);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the select clause for the relation query.
|
||||
*
|
||||
* @param array $columns
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
protected function getSelectColumns(array $columns = ['*'])
|
||||
{
|
||||
if ($columns == ['*'])
|
||||
{
|
||||
$columns = [$this->related->getTable().'.*'];
|
||||
}
|
||||
|
||||
return array_merge($columns, [$this->parent->getTable().'.'.$this->firstKey]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a paginator for the "select" statement.
|
||||
*
|
||||
* @param int $perPage
|
||||
* @param array $columns
|
||||
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
public function paginate($perPage = null, $columns = ['*'])
|
||||
{
|
||||
$this->query->addSelect($this->getSelectColumns($columns));
|
||||
|
||||
return $this->query->paginate($perPage, $columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate the given query into a simple paginator.
|
||||
*
|
||||
* @param int $perPage
|
||||
* @param array $columns
|
||||
* @return \Illuminate\Contracts\Pagination\Paginator
|
||||
*/
|
||||
public function simplePaginate($perPage = null, $columns = ['*'])
|
||||
{
|
||||
$this->query->addSelect($this->getSelectColumns($columns));
|
||||
|
||||
return $this->query->simplePaginate($perPage, $columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key for comparing against the parent key in "has" query.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHasCompareKey()
|
||||
{
|
||||
return $this->farParent->getQualifiedKeyName();
|
||||
}
|
||||
|
||||
}
|
47
vendor/illuminate/database/Eloquent/Relations/HasOne.php
vendored
Executable file
47
vendor/illuminate/database/Eloquent/Relations/HasOne.php
vendored
Executable file
@ -0,0 +1,47 @@
|
||||
<?php namespace Illuminate\Database\Eloquent\Relations;
|
||||
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class HasOne extends HasOneOrMany {
|
||||
|
||||
/**
|
||||
* Get the results of the relationship.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResults()
|
||||
{
|
||||
return $this->query->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, null);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
412
vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php
vendored
Executable file
412
vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php
vendored
Executable file
@ -0,0 +1,412 @@
|
||||
<?php namespace Illuminate\Database\Eloquent\Relations;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Query\Expression;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
abstract class HasOneOrMany extends Relation {
|
||||
|
||||
/**
|
||||
* The foreign key of the parent model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $foreignKey;
|
||||
|
||||
/**
|
||||
* The local key of the parent model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $localKey;
|
||||
|
||||
/**
|
||||
* Create a new has one or many relationship instance.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Illuminate\Database\Eloquent\Model $parent
|
||||
* @param string $foreignKey
|
||||
* @param string $localKey
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Builder $query, Model $parent, $foreignKey, $localKey)
|
||||
{
|
||||
$this->localKey = $localKey;
|
||||
$this->foreignKey = $foreignKey;
|
||||
|
||||
parent::__construct($query, $parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the base constraints on the relation query.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addConstraints()
|
||||
{
|
||||
if (static::$constraints)
|
||||
{
|
||||
$this->query->where($this->foreignKey, '=', $this->getParentKey());
|
||||
|
||||
$this->query->whereNotNull($this->foreignKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the constraints for a relationship count query.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Illuminate\Database\Eloquent\Builder $parent
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function getRelationCountQuery(Builder $query, Builder $parent)
|
||||
{
|
||||
if ($parent->getQuery()->from == $query->getQuery()->from)
|
||||
{
|
||||
return $this->getRelationCountQueryForSelfRelation($query, $parent);
|
||||
}
|
||||
|
||||
return parent::getRelationCountQuery($query, $parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the constraints for a relationship count query on the same table.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Illuminate\Database\Eloquent\Builder $parent
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function getRelationCountQueryForSelfRelation(Builder $query, Builder $parent)
|
||||
{
|
||||
$query->select(new Expression('count(*)'));
|
||||
|
||||
$tablePrefix = $this->query->getQuery()->getConnection()->getTablePrefix();
|
||||
|
||||
$query->from($query->getModel()->getTable().' as '.$tablePrefix.$hash = $this->getRelationCountHash());
|
||||
|
||||
$key = $this->wrap($this->getQualifiedParentKeyName());
|
||||
|
||||
return $query->where($hash.'.'.$this->getPlainForeignKey(), '=', new Expression($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a relationship join table hash.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRelationCountHash()
|
||||
{
|
||||
return 'self_'.md5(microtime(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the constraints for an eager load of the relation.
|
||||
*
|
||||
* @param array $models
|
||||
* @return void
|
||||
*/
|
||||
public function addEagerConstraints(array $models)
|
||||
{
|
||||
$this->query->whereIn($this->foreignKey, $this->getKeys($models, $this->localKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* Match the eagerly loaded results to their single parents.
|
||||
*
|
||||
* @param array $models
|
||||
* @param \Illuminate\Database\Eloquent\Collection $results
|
||||
* @param string $relation
|
||||
* @return array
|
||||
*/
|
||||
public function matchOne(array $models, Collection $results, $relation)
|
||||
{
|
||||
return $this->matchOneOrMany($models, $results, $relation, 'one');
|
||||
}
|
||||
|
||||
/**
|
||||
* Match the eagerly loaded results to their many parents.
|
||||
*
|
||||
* @param array $models
|
||||
* @param \Illuminate\Database\Eloquent\Collection $results
|
||||
* @param string $relation
|
||||
* @return array
|
||||
*/
|
||||
public function matchMany(array $models, Collection $results, $relation)
|
||||
{
|
||||
return $this->matchOneOrMany($models, $results, $relation, 'many');
|
||||
}
|
||||
|
||||
/**
|
||||
* Match the eagerly loaded results to their many parents.
|
||||
*
|
||||
* @param array $models
|
||||
* @param \Illuminate\Database\Eloquent\Collection $results
|
||||
* @param string $relation
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
protected function matchOneOrMany(array $models, Collection $results, $relation, $type)
|
||||
{
|
||||
$dictionary = $this->buildDictionary($results);
|
||||
|
||||
// Once we have the dictionary we can simply spin through the parent models to
|
||||
// link them up with their children using the keyed dictionary to make the
|
||||
// matching very convenient and easy work. Then we'll just return them.
|
||||
foreach ($models as $model)
|
||||
{
|
||||
$key = $model->getAttribute($this->localKey);
|
||||
|
||||
if (isset($dictionary[$key]))
|
||||
{
|
||||
$value = $this->getRelationValue($dictionary, $key, $type);
|
||||
|
||||
$model->setRelation($relation, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $models;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a relationship by one or many type.
|
||||
*
|
||||
* @param array $dictionary
|
||||
* @param string $key
|
||||
* @param string $type
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getRelationValue(array $dictionary, $key, $type)
|
||||
{
|
||||
$value = $dictionary[$key];
|
||||
|
||||
return $type == 'one' ? reset($value) : $this->related->newCollection($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build model dictionary keyed by the relation's foreign key.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Collection $results
|
||||
* @return array
|
||||
*/
|
||||
protected function buildDictionary(Collection $results)
|
||||
{
|
||||
$dictionary = array();
|
||||
|
||||
$foreign = $this->getPlainForeignKey();
|
||||
|
||||
// First we will create a dictionary of models keyed by the foreign key of the
|
||||
// relationship as this will allow us to quickly access all of the related
|
||||
// models without having to do nested looping which will be quite slow.
|
||||
foreach ($results as $result)
|
||||
{
|
||||
$dictionary[$result->{$foreign}][] = $result;
|
||||
}
|
||||
|
||||
return $dictionary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach a model instance to the parent model.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function save(Model $model)
|
||||
{
|
||||
$model->setAttribute($this->getPlainForeignKey(), $this->getParentKey());
|
||||
|
||||
return $model->save() ? $model : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach an array of models to the parent instance.
|
||||
*
|
||||
* @param array $models
|
||||
* @return array
|
||||
*/
|
||||
public function saveMany(array $models)
|
||||
{
|
||||
array_walk($models, array($this, 'save'));
|
||||
|
||||
return $models;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a model by its primary key or return new instance of the related model.
|
||||
*
|
||||
* @param mixed $id
|
||||
* @param array $columns
|
||||
* @return \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function findOrNew($id, $columns = ['*'])
|
||||
{
|
||||
if (is_null($instance = $this->find($id, $columns)))
|
||||
{
|
||||
$instance = $this->related->newInstance();
|
||||
|
||||
$instance->setAttribute($this->getPlainForeignKey(), $this->getParentKey());
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first related model record matching the attributes or instantiate it.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function firstOrNew(array $attributes)
|
||||
{
|
||||
if (is_null($instance = $this->where($attributes)->first()))
|
||||
{
|
||||
$instance = $this->related->newInstance($attributes);
|
||||
|
||||
$instance->setAttribute($this->getPlainForeignKey(), $this->getParentKey());
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first related record matching the attributes or create it.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function firstOrCreate(array $attributes)
|
||||
{
|
||||
if (is_null($instance = $this->where($attributes)->first()))
|
||||
{
|
||||
$instance = $this->create($attributes);
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or update a related record matching the attributes, and fill it with values.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param array $values
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function updateOrCreate(array $attributes, array $values = [])
|
||||
{
|
||||
$instance = $this->firstOrNew($attributes);
|
||||
|
||||
$instance->fill($values);
|
||||
|
||||
$instance->save();
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the related model.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function create(array $attributes)
|
||||
{
|
||||
// Here we will set the raw attributes to avoid hitting the "fill" method so
|
||||
// that we do not have to worry about a mass accessor rules blocking sets
|
||||
// on the models. Otherwise, some of these attributes will not get set.
|
||||
$instance = $this->related->newInstance($attributes);
|
||||
|
||||
$instance->setAttribute($this->getPlainForeignKey(), $this->getParentKey());
|
||||
|
||||
$instance->save();
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an array of new instances of the related model.
|
||||
*
|
||||
* @param array $records
|
||||
* @return array
|
||||
*/
|
||||
public function createMany(array $records)
|
||||
{
|
||||
$instances = array();
|
||||
|
||||
foreach ($records as $record)
|
||||
{
|
||||
$instances[] = $this->create($record);
|
||||
}
|
||||
|
||||
return $instances;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an update on all the related models.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return int
|
||||
*/
|
||||
public function update(array $attributes)
|
||||
{
|
||||
if ($this->related->usesTimestamps())
|
||||
{
|
||||
$attributes[$this->relatedUpdatedAt()] = $this->related->freshTimestampString();
|
||||
}
|
||||
|
||||
return $this->query->update($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key for comparing against the parent key in "has" query.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHasCompareKey()
|
||||
{
|
||||
return $this->getForeignKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the foreign key for the relationship.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getForeignKey()
|
||||
{
|
||||
return $this->foreignKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plain foreign key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPlainForeignKey()
|
||||
{
|
||||
$segments = explode('.', $this->getForeignKey());
|
||||
|
||||
return $segments[count($segments) - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key value of the parent's local key.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getParentKey()
|
||||
{
|
||||
return $this->parent->getAttribute($this->localKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fully qualified parent key name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQualifiedParentKeyName()
|
||||
{
|
||||
return $this->parent->getTable().'.'.$this->localKey;
|
||||
}
|
||||
|
||||
}
|
47
vendor/illuminate/database/Eloquent/Relations/MorphMany.php
vendored
Executable file
47
vendor/illuminate/database/Eloquent/Relations/MorphMany.php
vendored
Executable file
@ -0,0 +1,47 @@
|
||||
<?php namespace Illuminate\Database\Eloquent\Relations;
|
||||
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class MorphMany extends MorphOneOrMany {
|
||||
|
||||
/**
|
||||
* Get the results of the relationship.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResults()
|
||||
{
|
||||
return $this->query->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->related->newCollection());
|
||||
}
|
||||
|
||||
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->matchMany($models, $results, $relation);
|
||||
}
|
||||
|
||||
}
|
47
vendor/illuminate/database/Eloquent/Relations/MorphOne.php
vendored
Executable file
47
vendor/illuminate/database/Eloquent/Relations/MorphOne.php
vendored
Executable file
@ -0,0 +1,47 @@
|
||||
<?php namespace Illuminate\Database\Eloquent\Relations;
|
||||
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class MorphOne extends MorphOneOrMany {
|
||||
|
||||
/**
|
||||
* Get the results of the relationship.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResults()
|
||||
{
|
||||
return $this->query->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, null);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
236
vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php
vendored
Executable file
236
vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php
vendored
Executable file
@ -0,0 +1,236 @@
|
||||
<?php namespace Illuminate\Database\Eloquent\Relations;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
abstract class MorphOneOrMany extends HasOneOrMany {
|
||||
|
||||
/**
|
||||
* The foreign key type for the relationship.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $morphType;
|
||||
|
||||
/**
|
||||
* The class name of the parent model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $morphClass;
|
||||
|
||||
/**
|
||||
* Create a new morph one or many relationship instance.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Illuminate\Database\Eloquent\Model $parent
|
||||
* @param string $type
|
||||
* @param string $id
|
||||
* @param string $localKey
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Builder $query, Model $parent, $type, $id, $localKey)
|
||||
{
|
||||
$this->morphType = $type;
|
||||
|
||||
$this->morphClass = $parent->getMorphClass();
|
||||
|
||||
parent::__construct($query, $parent, $id, $localKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the base constraints on the relation query.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addConstraints()
|
||||
{
|
||||
if (static::$constraints)
|
||||
{
|
||||
parent::addConstraints();
|
||||
|
||||
$this->query->where($this->morphType, $this->morphClass);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the relationship count query.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Illuminate\Database\Eloquent\Builder $parent
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function getRelationCountQuery(Builder $query, Builder $parent)
|
||||
{
|
||||
$query = parent::getRelationCountQuery($query, $parent);
|
||||
|
||||
return $query->where($this->morphType, $this->morphClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the constraints for an eager load of the relation.
|
||||
*
|
||||
* @param array $models
|
||||
* @return void
|
||||
*/
|
||||
public function addEagerConstraints(array $models)
|
||||
{
|
||||
parent::addEagerConstraints($models);
|
||||
|
||||
$this->query->where($this->morphType, $this->morphClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach a model instance to the parent model.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function save(Model $model)
|
||||
{
|
||||
$model->setAttribute($this->getPlainMorphType(), $this->morphClass);
|
||||
|
||||
return parent::save($model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a related model by its primary key or return new instance of the related model.
|
||||
*
|
||||
* @param mixed $id
|
||||
* @param array $columns
|
||||
* @return \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function findOrNew($id, $columns = ['*'])
|
||||
{
|
||||
if (is_null($instance = $this->find($id, $columns)))
|
||||
{
|
||||
$instance = $this->related->newInstance();
|
||||
|
||||
// When saving a polymorphic relationship, we need to set not only the foreign
|
||||
// key, but also the foreign key type, which is typically the class name of
|
||||
// the parent model. This makes the polymorphic item unique in the table.
|
||||
$this->setForeignAttributesForCreate($instance);
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first related model record matching the attributes or instantiate it.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function firstOrNew(array $attributes)
|
||||
{
|
||||
if (is_null($instance = $this->where($attributes)->first()))
|
||||
{
|
||||
$instance = $this->related->newInstance();
|
||||
|
||||
// When saving a polymorphic relationship, we need to set not only the foreign
|
||||
// key, but also the foreign key type, which is typically the class name of
|
||||
// the parent model. This makes the polymorphic item unique in the table.
|
||||
$this->setForeignAttributesForCreate($instance);
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first related record matching the attributes or create it.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function firstOrCreate(array $attributes)
|
||||
{
|
||||
if (is_null($instance = $this->where($attributes)->first()))
|
||||
{
|
||||
$instance = $this->create($attributes);
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or update a related record matching the attributes, and fill it with values.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param array $values
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function updateOrCreate(array $attributes, array $values = [])
|
||||
{
|
||||
$instance = $this->firstOrNew($attributes);
|
||||
|
||||
$instance->fill($values);
|
||||
|
||||
$instance->save();
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the related model.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function create(array $attributes)
|
||||
{
|
||||
$instance = $this->related->newInstance($attributes);
|
||||
|
||||
// When saving a polymorphic relationship, we need to set not only the foreign
|
||||
// key, but also the foreign key type, which is typically the class name of
|
||||
// the parent model. This makes the polymorphic item unique in the table.
|
||||
$this->setForeignAttributesForCreate($instance);
|
||||
|
||||
$instance->save();
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the foreign ID and type for creating a related model.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
*/
|
||||
protected function setForeignAttributesForCreate(Model $model)
|
||||
{
|
||||
$model->{$this->getPlainForeignKey()} = $this->getParentKey();
|
||||
|
||||
$model->{last(explode('.', $this->morphType))} = $this->morphClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the foreign key "type" name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMorphType()
|
||||
{
|
||||
return $this->morphType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plain morph type name without the table.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPlainMorphType()
|
||||
{
|
||||
return last(explode('.', $this->morphType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class name of the parent model.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMorphClass()
|
||||
{
|
||||
return $this->morphClass;
|
||||
}
|
||||
|
||||
}
|
78
vendor/illuminate/database/Eloquent/Relations/MorphPivot.php
vendored
Executable file
78
vendor/illuminate/database/Eloquent/Relations/MorphPivot.php
vendored
Executable file
@ -0,0 +1,78 @@
|
||||
<?php namespace Illuminate\Database\Eloquent\Relations;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class MorphPivot extends Pivot {
|
||||
|
||||
/**
|
||||
* The type of the polymorphic relation.
|
||||
*
|
||||
* Explicitly define this so it's not included in saved attributes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $morphType;
|
||||
|
||||
/**
|
||||
* The value of the polymorphic relation.
|
||||
*
|
||||
* Explicitly define this so it's not included in saved attributes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $morphClass;
|
||||
|
||||
/**
|
||||
* Set the keys for a save update query.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function setKeysForSaveQuery(Builder $query)
|
||||
{
|
||||
$query->where($this->morphType, $this->morphClass);
|
||||
|
||||
return parent::setKeysForSaveQuery($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the pivot model record from the database.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$query = $this->getDeleteQuery();
|
||||
|
||||
$query->where($this->morphType, $this->morphClass);
|
||||
|
||||
return $query->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the morph type for the pivot.
|
||||
*
|
||||
* @param string $morphType
|
||||
* @return $this
|
||||
*/
|
||||
public function setMorphType($morphType)
|
||||
{
|
||||
$this->morphType = $morphType;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the morph class for the pivot.
|
||||
*
|
||||
* @param string $morphClass
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphPivot
|
||||
*/
|
||||
public function setMorphClass($morphClass)
|
||||
{
|
||||
$this->morphClass = $morphClass;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
247
vendor/illuminate/database/Eloquent/Relations/MorphTo.php
vendored
Executable file
247
vendor/illuminate/database/Eloquent/Relations/MorphTo.php
vendored
Executable file
@ -0,0 +1,247 @@
|
||||
<?php namespace Illuminate\Database\Eloquent\Relations;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Collection as BaseCollection;
|
||||
|
||||
class MorphTo extends BelongsTo {
|
||||
|
||||
/**
|
||||
* The type of the polymorphic relation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $morphType;
|
||||
|
||||
/**
|
||||
* The models whose relations are being eager loaded.
|
||||
*
|
||||
* @var \Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
protected $models;
|
||||
|
||||
/**
|
||||
* All of the models keyed by ID.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dictionary = array();
|
||||
|
||||
/*
|
||||
* Indicates if soft-deleted model instances should be fetched.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $withTrashed = false;
|
||||
|
||||
/**
|
||||
* Create a new morph to relationship instance.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Illuminate\Database\Eloquent\Model $parent
|
||||
* @param string $foreignKey
|
||||
* @param string $otherKey
|
||||
* @param string $type
|
||||
* @param string $relation
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Builder $query, Model $parent, $foreignKey, $otherKey, $type, $relation)
|
||||
{
|
||||
$this->morphType = $type;
|
||||
|
||||
parent::__construct($query, $parent, $foreignKey, $otherKey, $relation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the constraints for an eager load of the relation.
|
||||
*
|
||||
* @param array $models
|
||||
* @return void
|
||||
*/
|
||||
public function addEagerConstraints(array $models)
|
||||
{
|
||||
$this->buildDictionary($this->models = Collection::make($models));
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a dictionary with the models.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Collection $models
|
||||
* @return void
|
||||
*/
|
||||
protected function buildDictionary(Collection $models)
|
||||
{
|
||||
foreach ($models as $model)
|
||||
{
|
||||
if ($model->{$this->morphType})
|
||||
{
|
||||
$this->dictionary[$model->{$this->morphType}][$model->{$this->foreignKey}][] = $model;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 $models;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate the model instance to the given parent.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function associate(Model $model)
|
||||
{
|
||||
$this->parent->setAttribute($this->foreignKey, $model->getKey());
|
||||
|
||||
$this->parent->setAttribute($this->morphType, $model->getMorphClass());
|
||||
|
||||
return $this->parent->setRelation($this->relation, $model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the results of the relationship.
|
||||
*
|
||||
* Called via eager load method of Eloquent query builder.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getEager()
|
||||
{
|
||||
foreach (array_keys($this->dictionary) as $type)
|
||||
{
|
||||
$this->matchToMorphParents($type, $this->getResultsByType($type));
|
||||
}
|
||||
|
||||
return $this->models;
|
||||
}
|
||||
|
||||
/**
|
||||
* Match the results for a given type to their parents.
|
||||
*
|
||||
* @param string $type
|
||||
* @param \Illuminate\Database\Eloquent\Collection $results
|
||||
* @return void
|
||||
*/
|
||||
protected function matchToMorphParents($type, Collection $results)
|
||||
{
|
||||
foreach ($results as $result)
|
||||
{
|
||||
if (isset($this->dictionary[$type][$result->getKey()]))
|
||||
{
|
||||
foreach ($this->dictionary[$type][$result->getKey()] as $model)
|
||||
{
|
||||
$model->setRelation($this->relation, $result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the relation results for a type.
|
||||
*
|
||||
* @param string $type
|
||||
* @return \Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
protected function getResultsByType($type)
|
||||
{
|
||||
$instance = $this->createModelByType($type);
|
||||
|
||||
$key = $instance->getKeyName();
|
||||
|
||||
$query = $instance->newQuery();
|
||||
|
||||
$query = $this->useWithTrashed($query);
|
||||
|
||||
return $query->whereIn($key, $this->gatherKeysByType($type)->all())->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather all of the foreign keys for a given type.
|
||||
*
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
protected function gatherKeysByType($type)
|
||||
{
|
||||
$foreign = $this->foreignKey;
|
||||
|
||||
return BaseCollection::make($this->dictionary[$type])->map(function($models) use ($foreign)
|
||||
{
|
||||
return head($models)->{$foreign};
|
||||
|
||||
})->unique();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new model instance by type.
|
||||
*
|
||||
* @param string $type
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function createModelByType($type)
|
||||
{
|
||||
return new $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the foreign key "type" name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMorphType()
|
||||
{
|
||||
return $this->morphType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the dictionary used by the relationship.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDictionary()
|
||||
{
|
||||
return $this->dictionary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch soft-deleted model instances with query.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function withTrashed()
|
||||
{
|
||||
$this->withTrashed = true;
|
||||
|
||||
$this->query = $this->useWithTrashed($this->query);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return trashed models with query if told so.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function useWithTrashed(Builder $query)
|
||||
{
|
||||
if ($this->withTrashed && $query->getMacro('withTrashed') !== null)
|
||||
{
|
||||
return $query->withTrashed();
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
}
|
158
vendor/illuminate/database/Eloquent/Relations/MorphToMany.php
vendored
Executable file
158
vendor/illuminate/database/Eloquent/Relations/MorphToMany.php
vendored
Executable file
@ -0,0 +1,158 @@
|
||||
<?php namespace Illuminate\Database\Eloquent\Relations;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class MorphToMany extends BelongsToMany {
|
||||
|
||||
/**
|
||||
* The type of the polymorphic relation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $morphType;
|
||||
|
||||
/**
|
||||
* The class name of the morph type constraint.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $morphClass;
|
||||
|
||||
/**
|
||||
* Indicates if we are connecting the inverse of the relation.
|
||||
*
|
||||
* This primarily affects the morphClass constraint.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $inverse;
|
||||
|
||||
/**
|
||||
* Create a new morph to many relationship instance.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Illuminate\Database\Eloquent\Model $parent
|
||||
* @param string $name
|
||||
* @param string $table
|
||||
* @param string $foreignKey
|
||||
* @param string $otherKey
|
||||
* @param string $relationName
|
||||
* @param bool $inverse
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Builder $query, Model $parent, $name, $table, $foreignKey, $otherKey, $relationName = null, $inverse = false)
|
||||
{
|
||||
$this->inverse = $inverse;
|
||||
$this->morphType = $name.'_type';
|
||||
$this->morphClass = $inverse ? $query->getModel()->getMorphClass() : $parent->getMorphClass();
|
||||
|
||||
parent::__construct($query, $parent, $table, $foreignKey, $otherKey, $relationName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the where clause for the relation query.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function setWhere()
|
||||
{
|
||||
parent::setWhere();
|
||||
|
||||
$this->query->where($this->table.'.'.$this->morphType, $this->morphClass);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the constraints for a relationship count query.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Illuminate\Database\Eloquent\Builder $parent
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function getRelationCountQuery(Builder $query, Builder $parent)
|
||||
{
|
||||
$query = parent::getRelationCountQuery($query, $parent);
|
||||
|
||||
return $query->where($this->table.'.'.$this->morphType, $this->morphClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the constraints for an eager load of the relation.
|
||||
*
|
||||
* @param array $models
|
||||
* @return void
|
||||
*/
|
||||
public function addEagerConstraints(array $models)
|
||||
{
|
||||
parent::addEagerConstraints($models);
|
||||
|
||||
$this->query->where($this->table.'.'.$this->morphType, $this->morphClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new pivot attachment record.
|
||||
*
|
||||
* @param int $id
|
||||
* @param bool $timed
|
||||
* @return array
|
||||
*/
|
||||
protected function createAttachRecord($id, $timed)
|
||||
{
|
||||
$record = parent::createAttachRecord($id, $timed);
|
||||
|
||||
return array_add($record, $this->morphType, $this->morphClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new query builder for the pivot table.
|
||||
*
|
||||
* @return \Illuminate\Database\Query\Builder
|
||||
*/
|
||||
protected function newPivotQuery()
|
||||
{
|
||||
$query = parent::newPivotQuery();
|
||||
|
||||
return $query->where($this->morphType, $this->morphClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new pivot model instance.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param bool $exists
|
||||
* @return \Illuminate\Database\Eloquent\Relations\Pivot
|
||||
*/
|
||||
public function newPivot(array $attributes = array(), $exists = false)
|
||||
{
|
||||
$pivot = new MorphPivot($this->parent, $attributes, $this->table, $exists);
|
||||
|
||||
$pivot->setPivotKeys($this->foreignKey, $this->otherKey)
|
||||
->setMorphType($this->morphType)
|
||||
->setMorphClass($this->morphClass);
|
||||
|
||||
return $pivot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the foreign key "type" name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMorphType()
|
||||
{
|
||||
return $this->morphType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class name of the parent model.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMorphClass()
|
||||
{
|
||||
return $this->morphClass;
|
||||
}
|
||||
|
||||
}
|
171
vendor/illuminate/database/Eloquent/Relations/Pivot.php
vendored
Executable file
171
vendor/illuminate/database/Eloquent/Relations/Pivot.php
vendored
Executable file
@ -0,0 +1,171 @@
|
||||
<?php namespace Illuminate\Database\Eloquent\Relations;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class Pivot extends Model {
|
||||
|
||||
/**
|
||||
* The parent model of the relationship.
|
||||
*
|
||||
* @var \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* The name of the foreign key column.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $foreignKey;
|
||||
|
||||
/**
|
||||
* The name of the "other key" column.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $otherKey;
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = array();
|
||||
|
||||
/**
|
||||
* Create a new pivot model instance.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $parent
|
||||
* @param array $attributes
|
||||
* @param string $table
|
||||
* @param bool $exists
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Model $parent, $attributes, $table, $exists = false)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// The pivot model is a "dynamic" model since we will set the tables dynamically
|
||||
// for the instance. This allows it work for any intermediate tables for the
|
||||
// many to many relationship that are defined by this developer's classes.
|
||||
$this->setRawAttributes($attributes, true);
|
||||
|
||||
$this->setTable($table);
|
||||
|
||||
$this->setConnection($parent->getConnectionName());
|
||||
|
||||
// We store off the parent instance so we will access the timestamp column names
|
||||
// for the model, since the pivot model timestamps aren't easily configurable
|
||||
// from the developer's point of view. We can use the parents to get these.
|
||||
$this->parent = $parent;
|
||||
|
||||
$this->exists = $exists;
|
||||
|
||||
$this->timestamps = $this->hasTimestampAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the keys for a save update query.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function setKeysForSaveQuery(Builder $query)
|
||||
{
|
||||
$query->where($this->foreignKey, $this->getAttribute($this->foreignKey));
|
||||
|
||||
return $query->where($this->otherKey, $this->getAttribute($this->otherKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the pivot model record from the database.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
return $this->getDeleteQuery()->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query builder for a delete operation on the pivot.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function getDeleteQuery()
|
||||
{
|
||||
$foreign = $this->getAttribute($this->foreignKey);
|
||||
|
||||
$query = $this->newQuery()->where($this->foreignKey, $foreign);
|
||||
|
||||
return $query->where($this->otherKey, $this->getAttribute($this->otherKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the foreign key column name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getForeignKey()
|
||||
{
|
||||
return $this->foreignKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the "other key" column name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOtherKey()
|
||||
{
|
||||
return $this->otherKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the key names for the pivot model instance.
|
||||
*
|
||||
* @param string $foreignKey
|
||||
* @param string $otherKey
|
||||
* @return $this
|
||||
*/
|
||||
public function setPivotKeys($foreignKey, $otherKey)
|
||||
{
|
||||
$this->foreignKey = $foreignKey;
|
||||
|
||||
$this->otherKey = $otherKey;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the pivot model has timestamp attributes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasTimestampAttributes()
|
||||
{
|
||||
return array_key_exists($this->getCreatedAtColumn(), $this->attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the "created at" column.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCreatedAtColumn()
|
||||
{
|
||||
return $this->parent->getCreatedAtColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the "updated at" column.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUpdatedAtColumn()
|
||||
{
|
||||
return $this->parent->getUpdatedAtColumn();
|
||||
}
|
||||
|
||||
}
|
290
vendor/illuminate/database/Eloquent/Relations/Relation.php
vendored
Executable file
290
vendor/illuminate/database/Eloquent/Relations/Relation.php
vendored
Executable file
@ -0,0 +1,290 @@
|
||||
<?php namespace Illuminate\Database\Eloquent\Relations;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Query\Expression;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
abstract class Relation {
|
||||
|
||||
/**
|
||||
* The Eloquent query builder instance.
|
||||
*
|
||||
* @var \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* The parent model instance.
|
||||
*
|
||||
* @var \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* The related model instance.
|
||||
*
|
||||
* @var \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
protected $related;
|
||||
|
||||
/**
|
||||
* Indicates if the relation is adding constraints.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected static $constraints = true;
|
||||
|
||||
/**
|
||||
* Create a new relation instance.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Illuminate\Database\Eloquent\Model $parent
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Builder $query, Model $parent)
|
||||
{
|
||||
$this->query = $query;
|
||||
$this->parent = $parent;
|
||||
$this->related = $query->getModel();
|
||||
|
||||
$this->addConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the base constraints on the relation query.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract public function addConstraints();
|
||||
|
||||
/**
|
||||
* Set the constraints for an eager load of the relation.
|
||||
*
|
||||
* @param array $models
|
||||
* @return void
|
||||
*/
|
||||
abstract public function addEagerConstraints(array $models);
|
||||
|
||||
/**
|
||||
* Initialize the relation on a set of models.
|
||||
*
|
||||
* @param array $models
|
||||
* @param string $relation
|
||||
* @return array
|
||||
*/
|
||||
abstract public function initRelation(array $models, $relation);
|
||||
|
||||
/**
|
||||
* Match the eagerly loaded results to their parents.
|
||||
*
|
||||
* @param array $models
|
||||
* @param \Illuminate\Database\Eloquent\Collection $results
|
||||
* @param string $relation
|
||||
* @return array
|
||||
*/
|
||||
abstract public function match(array $models, Collection $results, $relation);
|
||||
|
||||
/**
|
||||
* Get the results of the relationship.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function getResults();
|
||||
|
||||
/**
|
||||
* Get the relationship for eager loading.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
public function getEager()
|
||||
{
|
||||
return $this->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Touch all of the related models for the relationship.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function touch()
|
||||
{
|
||||
$column = $this->getRelated()->getUpdatedAtColumn();
|
||||
|
||||
$this->rawUpdate(array($column => $this->getRelated()->freshTimestampString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a raw update against the base query.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return int
|
||||
*/
|
||||
public function rawUpdate(array $attributes = array())
|
||||
{
|
||||
return $this->query->update($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the constraints for a relationship count query.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Illuminate\Database\Eloquent\Builder $parent
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function getRelationCountQuery(Builder $query, Builder $parent)
|
||||
{
|
||||
$query->select(new Expression('count(*)'));
|
||||
|
||||
$key = $this->wrap($this->getQualifiedParentKeyName());
|
||||
|
||||
return $query->where($this->getHasCompareKey(), '=', new Expression($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a callback with constraints disabled on the relation.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @return mixed
|
||||
*/
|
||||
public static function noConstraints(Closure $callback)
|
||||
{
|
||||
$previous = static::$constraints;
|
||||
|
||||
static::$constraints = false;
|
||||
|
||||
// When resetting the relation where clause, we want to shift the first element
|
||||
// off of the bindings, leaving only the constraints that the developers put
|
||||
// as "extra" on the relationships, and not original relation constraints.
|
||||
$results = call_user_func($callback);
|
||||
|
||||
static::$constraints = $previous;
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the primary keys for an array of models.
|
||||
*
|
||||
* @param array $models
|
||||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
protected function getKeys(array $models, $key = null)
|
||||
{
|
||||
return array_unique(array_values(array_map(function($value) use ($key)
|
||||
{
|
||||
return $key ? $value->getAttribute($key) : $value->getKey();
|
||||
|
||||
}, $models)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the underlying query for the relation.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function getQuery()
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base query builder driving the Eloquent builder.
|
||||
*
|
||||
* @return \Illuminate\Database\Query\Builder
|
||||
*/
|
||||
public function getBaseQuery()
|
||||
{
|
||||
return $this->query->getQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent model of the relation.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fully qualified parent key name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQualifiedParentKeyName()
|
||||
{
|
||||
return $this->parent->getQualifiedKeyName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the related model of the relation.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function getRelated()
|
||||
{
|
||||
return $this->related;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the "created at" column.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function createdAt()
|
||||
{
|
||||
return $this->parent->getCreatedAtColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the "updated at" column.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function updatedAt()
|
||||
{
|
||||
return $this->parent->getUpdatedAtColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the related model's "updated at" column.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function relatedUpdatedAt()
|
||||
{
|
||||
return $this->related->getUpdatedAtColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the given value with the parent query's grammar.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function wrap($value)
|
||||
{
|
||||
return $this->parent->newQueryWithoutScopes()->getQuery()->getGrammar()->wrap($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle dynamic method calls to the relationship.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
{
|
||||
$result = call_user_func_array(array($this->query, $method), $parameters);
|
||||
|
||||
if ($result === $this->query) return $this;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user