Created
February 24, 2017 16:39
-
-
Save fenos/1b2c2ad4c3d6bc3db252eaf5085202d4 to your computer and use it in GitHub Desktop.
nested relations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Get includes that are valid relations | |
* on models, it can go deep as much as we need | |
* it will also cut off the not existing relations | |
* | |
* @param array $relations | |
* @return array|bool | |
*/ | |
public function validateRelations(array $relations = []) | |
{ | |
$model = $this->model(); | |
$validRelations = []; | |
// I'm going to check if the relations | |
// are valid | |
foreach ($relations as $include) { | |
if ($validatedRelation = $this->isValidRelationship($include, $model)) { | |
// If the valid relations are more then 2 means | |
// that we have nested relations let's join them | |
if (count($validatedRelation) >= 2) { | |
$parentRelation = array_shift($validatedRelation); | |
$validRelations[] = $parentRelation . '.' . implode('.', $validatedRelation); | |
} else { | |
$validRelations[] = $validatedRelation; | |
} | |
} | |
} | |
return $this->relationsValidated = array_reverse(array_flatten($validRelations)); | |
} | |
/** | |
* This function will define if the relation | |
* and the nested one are valid relations | |
* | |
* @param $nameRelation | |
* @param $parentModel | |
* @param int $deepness | |
* @return array | |
*/ | |
public function isValidRelationship($nameRelation, $parentModel, $deepness = 1) | |
{ | |
$breakingPoint = false; | |
$model = $parentModel; | |
$validRelations = []; | |
$parts = explode('.', $nameRelation); | |
// Todo: this while loop might be refactor in a short way | |
// I'll check if every include given is a | |
// valid model relation | |
while ($relation = array_shift($parts)) { | |
if (method_exists($model, $relation)) { | |
// I'll trigger the method to check if the relation | |
// return to me a Relation Instance | |
$rel = call_user_func([$model, $relation]); | |
// only if this pass I can consider the | |
// relation valid | |
if ($rel instanceof Relation) { | |
$model = $rel->getRelated(); | |
// I save the models that are related to this | |
// Rest instance so i can reuse them later | |
if (!($model instanceof $parentModel) or ($rel instanceof BelongsTo) or ($rel instanceof BelongsToMany)) { | |
$this->modelsRelated[ $deepness ][ $relation ] = $model; | |
} | |
$validRelations[] = $relation; | |
$deepness++; | |
} else { | |
$breakingPoint = true; | |
} | |
} else { | |
$breakingPoint = true; | |
} | |
if ($breakingPoint) { | |
break; | |
} | |
} | |
return $validRelations; | |
} | |
// USAGE | |
$this->validateRelations([ | |
'user', | |
'users.cars', | |
'users.cars.models' | |
]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment