Skip to content

Commit 74d09dd

Browse files
committed
add nested menus
1 parent d3ab8c1 commit 74d09dd

File tree

6 files changed

+78
-18
lines changed

6 files changed

+78
-18
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
"providers": [
2929
"Pharaonic\\Laravel\\Menus\\MenusServiceProvider"
3030
]
31-
}
31+
},
32+
"file": ["src/helper.php"]
3233
},
3334
"autoload": {
3435
"psr-4": {

src/MenusServiceProvider.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,7 @@ public function boot()
3939

4040
// Blade - Directive
4141
Blade::directive('menu', function ($section) {
42-
$section = Menu::section(trim($section, '\'"'))->get();
43-
if ($section->isEmpty()) return;
44-
45-
return view('laravel-menus::section', ['section' => $section])->render();
42+
return "<?php echo \menu($section, true); ?>";
4643
});
4744
}
4845
}

src/Models/Menu.php

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
* @property string $url
1212
* @property integer $sort
1313
* @property integer $visible
14+
* @property integer $parent_id
1415
* @property Carbon $created_at
1516
* @property Carbon $updated_at
17+
* @property Menu $children
1618
* @property MenuTranslation $translations
1719
*
1820
* @author Moamen Eltouny (Raggi) <[email protected]>
@@ -26,7 +28,7 @@ class Menu extends Model
2628
*
2729
* @var array
2830
*/
29-
protected $fillable = ['section', 'url', 'sort', 'visible'];
31+
protected $fillable = ['section', 'url', 'sort', 'visible', 'parent_id'];
3032

3133
/**
3234
* Translatable attributes names.
@@ -47,7 +49,7 @@ class Menu extends Model
4749
];
4850

4951
/**
50-
* Get section'items.
52+
* Get section items.
5153
*
5254
* @param \Illuminate\Database\Eloquent\Builder $query
5355
* @param string $section
@@ -56,7 +58,34 @@ class Menu extends Model
5658
*/
5759
public function scopeSection($query, string $section, string $locale = null)
5860
{
59-
return $query->translated($locale)->where('section', $section)->where('visible', true)->orderBy('sort', 'ASC');
61+
return $query->translated($locale)->with([
62+
'children' => function ($q) {
63+
return $q->visible();
64+
},
65+
'children.translations'
66+
])->where([
67+
'section' => $section,
68+
'parent_id' => null
69+
])->visible()->orderBy('sort', 'ASC');
70+
}
71+
72+
/**
73+
* Get visible items.
74+
*
75+
* @param \Illuminate\Database\Eloquent\Builder $query
76+
* @return \Illuminate\Database\Eloquent\Builder
77+
*/
78+
public function scopeVisible($query)
79+
{
80+
return $query->where('visible', true);
81+
}
82+
83+
/**
84+
* @return \Illuminate\Database\Eloquent\Relations\HasMany
85+
*/
86+
public function children()
87+
{
88+
return $this->hasMany(Menu::class, 'parent_id', 'id');
6089
}
6190

6291
/**
@@ -70,18 +99,25 @@ public function scopeSection($query, string $section, string $locale = null)
7099
* @param string $locale
71100
* @return Menu
72101
*/
73-
public static function set(string $section, string $title, string $url, int $sort = 0, bool $visible = true, string $locale = null)
102+
public static function set(string $section, mixed $title, string $url, int $parent = null, int $sort = 0, bool $visible = true)
74103
{
75-
$menu = new self;
76-
$menu->section = $section;
77-
$menu->url = $url;
78-
$menu->sort = $sort;
79-
$menu->visible = $visible;
80-
$menu->save();
104+
$menu = new self;
105+
$data = [
106+
'section' => $section,
107+
'url' => $url,
108+
'parent_id' => $parent,
109+
'sort' => $sort,
110+
'visible' => $visible
111+
];
112+
113+
$localKey = $menu->translationsKey ?? 'locale';
81114

82-
$menu->translateOrNew($locale ?? app()->getLocale())->title = $title;
83-
$menu->save();
115+
if (is_array($title))
116+
$data[$localKey] = $title;
117+
else
118+
$data[$localKey][app()->getLocale()]['title'] = $title;
84119

120+
$menu->fill($data)->save();
85121
return $menu;
86122
}
87123
}

src/database/migrations/2021_02_01_000016_create_menus_table.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ public function up()
2121

2222
$table->integer('sort')->default(0);
2323
$table->boolean('visible')->default(true);
24+
$table->unsignedBigInteger('parent_id')->nullable();
2425

2526
$table->timestamps();
27+
$table->foreign('parent_id')->references('id')->on('menus')->onDelete('set null');
2628
});
2729
}
2830

src/helper.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
use Pharaonic\Laravel\Menus\Models\Menu;
4+
5+
if (!function_exists('menu')) {
6+
function menu(string $section, bool $view = false)
7+
{
8+
$section = Menu::section(trim($section, '\'"'))->get();
9+
10+
if ($section->isEmpty()) return;
11+
if (!$view) return $section;
12+
13+
return view('laravel-menus::section', ['section' => $section]);
14+
}
15+
}

src/views/section.blade.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
<ul>
22
@foreach($section as $item)
3-
<li><a href="{{ $item->url }}">{!! $item->title !!}</a></li>
3+
<li>
4+
<a href="{{ $item->url }}">{!! $item->translateOrDefault()->title ?? null !!}</a>
5+
@if($item->children->isNotEmpty())
6+
<ul>
7+
@foreach($item->children as $sub)
8+
<li><a href="{{ $sub->url }}">{!! $sub->translateOrDefault()->title ?? null !!}</a></li>
9+
@endforeach
10+
</ul>
11+
@endif
12+
</li>
413
@endforeach
514
</ul>

0 commit comments

Comments
 (0)