/**
* Get the pivot attributes from a model.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return array
*/
protected function cleanPivotAttributes(Model $model)
{//Get the pivot attributes from a model
$values = [];// set the store values
foreach ($model->getAttributes() as $key => $value) {// loop attributes
// To get the pivots attributes we will just take any of the attributes which
// begin with "pivot_" and add those to this arrays, as well as unsetting
// them from the parent's models since they exist in a different table.
if (strpos($key, 'pivot_') === 0) {// if has this pivot_* key,
$values[substr($key, 6)] = $value;// dump the value in target array
unset($model->$key);// unset the source
}
}
return $values;// return this result
}
/**
* Set the base constraints on the relation query.
*
* @return void
*/
public function addConstraints()
{//Set the base constraints on the relation query.
$this->setJoin();// first to set Join
// set Constraints
if (static::$constraints) {// if has this flag then set Where
$this->setWhere();
}
}
/**
* Add the constraints for a relationship query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Builder $parent
* @param array|mixed $columns
* @return \Illuminate\Database\Eloquent\Builder
*/
public function getRelationQuery(Builder $query, Builder $parent, $columns = ['*'])
{//Add the constraints for a relationship query.
if ($parent->getQuery()->from == $query->getQuery()->from) {
return $this->getRelationQueryForSelfJoin($query, $parent, $columns);
}// if same the parent with this class self
// return the getRelation Query For Self Join
$this->setJoin($query);//setJoin
return parent::getRelationQuery($query, $parent, $columns);// just Relation Query
}// default use parents function
/**
* Add the constraints for a relationship query on the same table.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Builder $parent
* @param array|mixed $columns
* @return \Illuminate\Database\Eloquent\Builder
*/
public function getRelationQueryForSelfJoin(Builder $query, Builder $parent, $columns = ['*'])
{//Add the constraints for a relationship query on the same table.
$query->select($columns);// first set select
$query->from($this->related->getTable().' as '.$hash = $this->getRelationCountHash());
//set from
$this->related->setTable($hash);
// set table
$this->setJoin($query);
// set Join
return parent::getRelationQuery($query, $parent, $columns);
}// then use the GetRelationQuery
/**
* Get a relationship join table hash.
*
* @return string
*/
public function getRelationCountHash()
{
return 'self_'.md5(microtime(true));
}// get the hash key
/**
* Set the select clause for the relation query.
*
* @param array $columns
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
protected function getSelectColumns(array $columns = ['*'])
{//Set the select clause for the relation query.
// clause like constraints like this html tag list, yeah
if ($columns == ['*']) {
$columns = [$this->related->getTable().'.*'];
}// if this * options ,so we will get all table
return array_merge($columns, $this->getAliasedPivotColumns());
}// return this columns with the origin columns options
// even the alias , so it is every import
/**
* Get the pivot columns for the relation.
*
* @return array
*/
protected function getAliasedPivotColumns()
{//Get the pivot columns for the relation
$defaults = [$this->foreignKey, $this->otherKey];// first we set the defaults
// We need to alias all of the pivot columns with the "pivot_" prefix so we
// can easily extract them out of the models and put them into the pivot
// relationships when they are retrieved and hydrated into the models.
$columns = [];// retrieved like cover;
//columns : be prepare for the columns
foreach (array_merge($defaults, $this->pivotColumns) as $column) {// loop source as column
$columns[] = $this->table.'.'.$column.' as pivot_'.$column;
}// set the columns
return array_unique($columns);
}// return the unique key array
/**
* Determine whether the given column is defined as a pivot column.
*
* @param string $column
* @return bool
*/
protected function hasPivotColumn($column)
{//Determine whether the given column is defined as a pivot column
return in_array($column, $this->pivotColumns);
}// a system function be wrap by a package function
/**
* Set the join clause for the relation query.
*
* @param \Illuminate\Database\Eloquent\Builder|null $query
* @return $this
*/
protected function setJoin($query = null)
{// Set the join clause for the relation query
$query = $query ?: $this->query;// first to set the query sql
// We need to join to the intermediate table on the related model's primary
// key column with the intermediate table's foreign key for the related
// model instance. Then we can set the "where" for the parent models.
$baseTable = $this->related->getTable();
// inter mediate like middle
// get the base Table
$key = $baseTable.'.'.$this->related->getKeyName();// set key
$query->join($this->table, $key, '=', $this->getOtherKey());
return $this;// return this class query
}
/**
* Set the where clause for the relation query.
*
* @return $this
*/
protected function setWhere()
{//Set the where clause for the relation query.
$foreign = $this->getForeignKey();// first get the foregin
$this->query->where($foreign, '=', $this->parent->getKey());// set the where sql query
return $this;
}// return the query
/**
* Set the constraints for an eager load of the relation.
*
* @param array $models
* @return void
*/
public function addEagerConstraints(array $models)
{// add Eager Constraints
$this->query->whereIn($this->getForeignKey(), $this->getKeys($models));// wrap this function with whereIn
}//Set the constraints for an eager load of the relation
/**
* Initialize the relation on a set of models.
*
* @param array $models
* @param string $relation
* @return array
*/
public function initRelation(array $models, $relation)
{//Initialize the relation on a set of models
foreach ($models as $model) {
$model->setRelation($relation, $this->related->newCollection());
}// loop it and set the Relation
return $models;
}// return this models family
/**
* 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)
{//Match the eagerly loaded results to their parents
$dictionary = $this->buildDictionary($results);// set the dictionary be build Dictionary
// Once we have an array dictionary of child objects we can easily match the
// children back to their parent using the dictionary and the keys on the
// the parent models. Then we will return the hydrated models back out.
foreach ($models as $model) {//loop all values by this dictionary
if (isset($dictionary[$key = $model->getKey()])) {
$collection = $this->related->newCollection($dictionary[$key]);
$model->setRelation($relation, $collection);
}
}
return $models;// return the models
}
/**
* Build model dictionary keyed by the relation's foreign key.
*
* @param \Illuminate\Database\Eloquent\Collection $results
* @return array
*/
protected function buildDictionary(Collection $results)
{//Build model dictionary keyed by the relation foreign key
$foreign = $this->foreignKey;// just use self key
// First we will build a dictionary of child models keyed by the foreign key
// of the relation so that we will easily and quickly match them to their
// parents without having a possibly slow inner loops for every models.
$dictionary = [];// build a dictionary
foreach ($results as $result) {
$dictionary[$result->pivot->$foreign][] = $result;
}// set this
return $dictionary;
}// return the dictionary
/**
* Touch all of the related models for the relationship.
*
* E.g.: Touch all roles associated with this user.
*
* @return void
*/
public function touch()
{// associated : like relation
// touch is a order in linux system
$key = $this->getRelated()->getKeyName();// set the ke
$columns = $this->getRelatedFreshUpdate();// set or even get the columns
// If we actually have IDs for the relation, we will run the query to update all
// the related model's timestamps, to make sure these all reflect the changes
// to the parent models. This will help us keep any caching synced up here.
$ids = $this->getRelatedIds();// get ids
// caching synced
if (count($ids) > 0) {
$this->getRelated()->newQuery()->whereIn($key, $ids)->update($columns);
}// count the get Related
}
/**
* Get all of the IDs for the related models.
*
* @return \Illuminate\Support\Collection
*/
public function getRelatedIds()
{// Get all of the IDs for the related models
$related = $this->getRelated();// related
$fullKey = $related->getQualifiedKeyName();// set fullkey
return $this->getQuery()->select($fullKey)->pluck($related->getKeyName());
}// get Query