I have a model called Source
which contains a parent_id
column. Each source can have a parent_id
, and the hierarchy is infinite. If a Source
has no parent_id
, then it is a root.
Now, I currently have the following methods in my model:
public function parent()
{
return $this->hasOne('App\Source', 'id', 'parent_id');
}
public function children()
{
return $this->hasMany('App\Source', 'parent_id')->orderBy('name');
}
I have no problem obtaining a nice list of the children eg:
$parents = Source::with('children')->whereNull('parent_id')->orderBy('name')->get();
$traverse = function ($parents, $prefix = '') use (&$traverse) {
foreach ($parents as $parent) {
echo '<option value="'.$parent->id.'">'.$prefix.$parent->name.'</option>';
$traverse($parent->children, $prefix.'- ');
}
};
$traverse($parents);
My problem is that I want to get a full string of the model name along with its parents names.
So say I had the following sources:
Parent 1
- Child 1
- - Subchild 1
- - Subchild 2
- Child 2
I'm trying to create a function that will give me Parent 1 - Child 1 - Subchild 1
when called on Subchild 1
Here is what I've tried, which only seems to give me the top level parent name:
public static function treeName(Source $source, &$tree)
{
if ($source->parent) {
$tree[] = self::treeName($source->parent, $tree);
}
else {
$tree[] = $source->name;
}
}
$source = Source::where('name', 'Subchild 1')->first();
$tree = [];
Source::treeName($source, $tree);
Log::info($tree);
This gives me:
[2018-04-25 23:02:25] laravel.INFO: array (
0 => 'Parent 1',
1 => NULL,
2 => NULL,
)
I can simply implode the array by -
but the array isn't giving me what I want. How can I get this to work?
Here is what I want:
array (
0 => 'Parent 1',
1 => 'Child 1',
2 => 'Subchild 1',
)
This should get you the desired result in an array:
function toArray($child) {
$tree = [];
while($child) {
// Prepand the name to the front of the array
array_unshift($tree, $child->name);
// Overwrites `$child` with it's parent, for next iteration
// If the parent doesn't exist, $child will be null
// which will also end the `while` loop
$child = $child->parent;
}
return $tree;
}
Pass it the child's object and it'll return the array.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.