Skip to content

Commit be905be

Browse files
authored
Merge pull request #8 from koffinate/master
fix grouped menu
2 parents 329658b + 0fd6dd7 commit be905be

File tree

5 files changed

+152
-50
lines changed

5 files changed

+152
-50
lines changed

src/Contracts/GroupedMenu.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ interface GroupedMenu
1010
* @param string $name
1111
* @param string $title
1212
* @param array|object $attributes
13+
* @param int $sort
1314
*
1415
* @return static
1516
*/
1617
public function add(
1718
string $name,
1819
string $title,
1920
array|object $attributes = [],
21+
int $sort = 0
2022
): static;
2123

2224
/**

src/Factory.php

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
namespace Kfn\Menu;
66

7+
use Exception;
78
use Illuminate\Support\Fluent;
9+
use Throwable;
810

911
/**
1012
* @implements \Kfn\Menu\Contracts\GroupedMenu
@@ -21,7 +23,7 @@ class Factory implements \Kfn\Menu\Contracts\GroupedMenu
2123
* @param string|null $name
2224
*/
2325
public function __construct(
24-
string|null $name = null
26+
string|null $name = null,
2527
) {
2628
static::$name = $name ?: 'main';
2729
if (! static::$factory instanceof Fluent) {
@@ -43,14 +45,18 @@ public function add(
4345
string $name,
4446
string $title,
4547
object|array $attributes = [],
46-
int $sort = 0
48+
int $sort = 0,
4749
): static {
4850
if (! static::$factory[static::$name] instanceof GroupedMenu) {
49-
static::$factory[static::$name] = new GroupedMenu(
50-
name: $name,
51-
title: $title,
52-
attributes: $attributes
53-
);
51+
static::$factory[static::$name] = new GroupedMenu();
52+
}
53+
if (! static::$factory[static::$name]->has($name)) {
54+
static::$factory[static::$name]->add([
55+
'name' => $name,
56+
'title' => $title,
57+
'attributes' => $attributes,
58+
'sort' => $sort,
59+
]);
5460
}
5561

5662
return $this;
@@ -63,32 +69,49 @@ public function add(
6369
* @param bool $resolvedOnly
6470
*
6571
* @return \Kfn\Menu\GroupedMenu|\Kfn\Menu\GroupItem
72+
* @throws \Throwable
6673
*/
6774
public function get(
6875
string|null $groupName = null,
69-
bool $resolvedOnly = true
76+
bool $resolvedOnly = true,
7077
): GroupedMenu|GroupItem {
71-
$groupedMenu = static::$factory[static::$name];
78+
try {
79+
$groupedMenu = static::$factory->get(static::$name);
80+
if (! $groupedMenu instanceof GroupedMenu) {
81+
$groupedMenu = new GroupedMenu();
82+
}
7283

73-
if ($groupName) {
74-
$groupedMenu = $groupedMenu->get($groupName);
75-
}
84+
if (! $groupedMenu instanceof GroupedMenu) {
85+
throw new Exception('menu not yet initialized');
86+
}
7687

77-
if ($groupedMenu instanceof GroupedMenu && $resolvedOnly) {
78-
$groupedMenu = $groupedMenu->each(function (GroupItem $group) {
79-
$groupItems = $group->items->filter(fn ($it) => $it->resolve());
80-
$group->items = $groupItems;
88+
if ($groupName) {
89+
$groupedMenu = $groupedMenu->get($groupName);
90+
if (! $groupedMenu instanceof GroupItem) {
91+
$groupedMenu = new GroupItem();
92+
}
93+
}
8194

82-
return $group;
83-
});
84-
}
95+
if ($groupedMenu instanceof GroupedMenu && $resolvedOnly && $groupedMenu->isNotEmpty()) {
96+
$groupedMenu = $groupedMenu->each(function (GroupItem $group) {
97+
if ($group->items->isNotEmpty()) {
98+
$groupItems = $group->items->filter(fn (MenuItem $it) => $it->resolve());
99+
$group->items = $groupItems;
100+
}
85101

86-
// throw_if(app()->hasDebugModeEnabled(), $e);
87-
// app('log')->error('failed on get menu factory\n', [
88-
// 'message' => $e->getMessage(),
89-
// 'traces' => $e->getTraceAsString(),
90-
// ]);
102+
return $group;
103+
});
104+
}
105+
106+
return $groupedMenu;
107+
} catch (Throwable $e) {
108+
throw_if(app()->hasDebugModeEnabled(), $e);
109+
app('log')->error('failed on get menu factory\n', [
110+
'message' => $e->getMessage(),
111+
'traces' => $e->getTraceAsString(),
112+
]);
113+
}
91114

92-
return $groupedMenu;
115+
return new GroupedMenu();
93116
}
94117
}

src/GroupItem.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ class GroupItem implements \Kfn\Menu\Contracts\GroupItem
5353
* @param int $sort
5454
*/
5555
public function __construct(
56-
string $name,
57-
string $title,
56+
string $name = 'default',
57+
string $title = 'Default',
5858
array|object $attribute = [],
5959
int $sort = 0
6060
) {

src/GroupedMenu.php

Lines changed: 95 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,111 @@
22

33
namespace Kfn\Menu;
44

5+
use Exception;
56
use Illuminate\Support\Collection;
7+
use Illuminate\Support\Fluent;
68

79
class GroupedMenu extends Collection
810
{
911
/** @var string */
1012
private static string $collectionName;
1113

12-
public function __construct(
13-
string $name = 'default',
14-
string $title = 'Default',
15-
array|object $attributes = [],
16-
int $sort = 0
17-
) {
18-
if (empty($name)) {
19-
$name = str($title)->slug()->toString();
14+
/**
15+
* @param $items
16+
*/
17+
public function __construct($items = [])
18+
{
19+
parent::__construct([]);
20+
}
21+
22+
/**
23+
* @param $item
24+
*
25+
* @return $this
26+
* @throws \Exception
27+
*/
28+
public function add($item): static
29+
{
30+
$item = $this->_setItem($item);
31+
32+
return $this->put($item->get('name'), $item->toArray());
33+
}
34+
35+
/**
36+
* @param ...$values
37+
*
38+
* @return $this
39+
* @throws \Exception
40+
*/
41+
public function push(...$values): static
42+
{
43+
foreach ($values as $value) {
44+
$this->add($value);
2045
}
2146

22-
parent::__construct([
23-
$name => new GroupItem(
24-
name: $name,
25-
title: $title,
26-
attribute: $attributes,
27-
sort: $sort
28-
),
29-
]);
47+
return $this;
3048
}
3149

32-
public static function init(
33-
string $name = 'default',
34-
string $title = 'Default',
35-
array $attributes = []
36-
): static {
37-
return new static($name, $title, $attributes);
50+
/**
51+
* @param $key
52+
* @param $value
53+
*
54+
* @return void
55+
* @throws \Exception
56+
*/
57+
public function offsetSet($key, $value): void
58+
{
59+
$value = $this->_setItem($value);
60+
61+
parent::offsetSet($key, new GroupItem(
62+
name: $value->get('name'),
63+
title: $value->get('title'),
64+
attribute: $value->get('attributes'),
65+
sort: $value->get('sort'),
66+
));
3867
}
68+
69+
/**
70+
* @param mixed $item
71+
*
72+
* @return \Illuminate\Support\Fluent
73+
* @throws \Exception
74+
*/
75+
private function _setItem(mixed $item): Fluent
76+
{
77+
if (! (is_string($item) || is_array($item) || is_object($item))) {
78+
throw new Exception('an item must be a string or an array');
79+
}
80+
81+
if (is_string($item)) {
82+
$name = str($item)->slug()->toString();
83+
$title = $item;
84+
$attributes = [];
85+
$sort = 0;
86+
} else {
87+
if (is_array($item) || is_object($item)) {
88+
$item = new Fluent($item);
89+
}
90+
$name = $item->get('name')
91+
?: str($item->get('title'))->slug()->toString();
92+
$title = $item->get('title') ?: $name;
93+
$attributes = $item->get('attributes') ?: [];
94+
$sort = $item->get('sort') ?: 0;
95+
}
96+
97+
return new Fluent([
98+
'name' => $name,
99+
'title' => $title,
100+
'attributes' => $attributes,
101+
'sort' => $sort,
102+
]);
103+
}
104+
105+
// public static function init(
106+
// string $name = 'default',
107+
// string $title = 'Default',
108+
// array $attributes = []
109+
// ): static {
110+
// return new static($name, $title, $attributes);
111+
// }
39112
}

src/MenuItem.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ public function __construct(
5959

6060
$this->attribute = $attribute;
6161
$this->items = new MenuCollection();
62-
$this->resolveHref();
6362
}
6463

6564
/**
@@ -75,6 +74,8 @@ public function getHref(): string
7574
*/
7675
public function resolve(): bool
7776
{
77+
$this->resolveHref();
78+
7879
if ($this->resolver instanceof \Closure) {
7980
return (bool) $this->resolver->call($this);
8081
}
@@ -102,6 +103,9 @@ private function resolveHref(): void
102103
if ($name->isEmpty()) {
103104
throw new Exception('Menu item attribute name is empty');
104105
}
106+
if ($name->is('#')) {
107+
throw new Exception('hashed link');
108+
}
105109

106110
$name = $name->toString();
107111
$this->href = match ($this->type) {

0 commit comments

Comments
 (0)