Reputation: 1276
I'm trying to get categories tree of a sub-category
Let's say i have a sub-category called Accessories
this sub-category have parents of Electronics > Laptops
So it is Electronics > Laptops > Accessories
Table :
-----------------------------------------
| id | parent_id | name |
|---- |----------- |------------- |
| 1 | 0 | Electronics |
| 2 | 1 | Laptops |
| 3 | 2 | Accessories |
-----------------------------------------
I can get the root category of a sub-category like :
function getTopParent($category) {
if($category->parent_id === null) {
return $category->name;
}
return getTopParent(App\Category::find($category->parent_id));
// Will return Electronics
}
Also i know how to display categories like tree, see here
function printCategoryName($categories, $parentName = '') {
foreach ($categories as $category) {
$name = $parentName ? implode(' > ', [$parentName, $category->name]) : $category->name;
echo sprintf('%s%s', $name, PHP_EOL);
if (count($category->children) > 0) {
printCategoryName($category->children, $name);
}
}
}
printCategoryName($categories);
What i need is give a category like Accessories and get tree and get category tree for this sub-category :
Electronics > Laptops > Accessories.
How can i achieve this?
Upvotes: 3
Views: 5660
Reputation: 119
protected function getCategoriesTree()
{
$categories = Category::where('parent_id',0)->get();
if($categories->count())
{
foreach ($categories as $category)
{
$categories_tree[$category->id] = $this->getChildCategories($category);
}
}
return response()->json(['categories' => $categories_tree]);
}
private function getChildCategories($category)
{
$sub_categories = [];
$childs = Category::where('parent_id', $category->id)->get();
$sub_categories = $category;
$sub_categories['sub_categories'] = [];
if($childs->count())
{
$sub_categories['sub_categories'] = $childs;
}
return $sub_categories;
}
Upvotes: 3
Reputation: 17
I'm using this structure
your enter category model App\Category.php
class Categories extends Model
{
public function parent()
{
return $this->hasOne('App\Category', 'parent_id','id');
}
public function childiren()
{
return $this->hasMany('App\Category', 'id','parent_id');
}
}
your controller ExampleController.php
public function example()
{
$data = Category::all();
return view('index', compact('data'));
}
your blade index.blade.php
<select>
@foreach($data as $categories)
<optgroup label="{{ $categories->name }}">
@foreach($categories->children as $category)
<option value="{{ $category->id }}">{{ $category->name }}</option>
@endforeach
</optgroup>
@endforeach
</select>
also you use jquery select 2
Upvotes: 0
Reputation: 1276
This is how i got it working :
function getParentsTree($category, $name)
{
if ($category->parent_id == null)
{
return $name;
}
$parent = Category::find($category->parent_id);
$name = $parent->name . ' > ' . $name;
return getParentsTree($parent, $name);
}
$cat = Category::find(1);
echo getParentsTree($cat, $cat->name);
Output : Electronics > Laptops > Accessories
Upvotes: 1
Reputation: 4813
This is a Common problem solved by the composite design pattern
Compose objects into tree structures to represent whole-part hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. Recursive composition "Directories contain entries, each of which could be a directory." 1-to-many "has a" up the "is a" hierarchy
You can see an example of composite design pattern implementation with php here
Upvotes: 0