Skip to content

Commit ae2698e

Browse files
author
Nur Alam
committed
attribute added to generate nav items
1 parent 8d8e6ed commit ae2698e

File tree

10 files changed

+1177
-737
lines changed

10 files changed

+1177
-737
lines changed

composer.lock

Lines changed: 480 additions & 701 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/navbar.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
use RadiateCode\LaravelNavbar\Presenter\NavBarPresenter;
44

55
return [
6+
/**
7+
* Controllers path to generate navs
8+
*/
9+
'controllers-path' => app_path('Http/Controllers'),
10+
611
/**
712
* Presenter for navbar style
813
*

src/Attributes/AppendTo.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace RadiateCode\LaravelNavbar\Attributes;
4+
5+
use Attribute;
6+
7+
#[Attribute(Attribute::TARGET_METHOD)]
8+
class AppendTo
9+
{
10+
public function __construct(public string $name)
11+
{
12+
}
13+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace RadiateCode\LaravelNavbar\Attributes;
4+
5+
use Attribute;
6+
7+
#[Attribute(Attribute::TARGET_CLASS)]
8+
class AppendableNavLinks
9+
{
10+
11+
}

src/Attributes/Nav.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace RadiateCode\LaravelNavbar\Attributes;
4+
5+
use Attribute;
6+
7+
#[Attribute(Attribute::TARGET_CLASS)]
8+
class Nav
9+
{
10+
public function __construct(public int $serial, public string $header, public string $name, public string $icon)
11+
{
12+
}
13+
}

src/Attributes/NavLinks.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace RadiateCode\LaravelNavbar\Attributes;
4+
5+
use Attribute;
6+
7+
#[Attribute(Attribute::TARGET_METHOD)]
8+
class NavLinks
9+
{
10+
public function __construct(
11+
public bool $condition,
12+
public string $title,
13+
public ?string $icon = null,
14+
) {
15+
}
16+
}

src/Attributes/ParentNav.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace RadiateCode\LaravelNavbar\Attributes;
4+
5+
use Attribute;
6+
7+
#[Attribute(Attribute::TARGET_CLASS)]
8+
class ParentNav
9+
{
10+
public function __construct(public string $name, public string $icon = 'fa fa-home')
11+
{
12+
}
13+
}

src/FilesFinderService.php

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
namespace RadiateCode\LaravelNavbar;
4+
5+
use Illuminate\Support\Str;
6+
7+
class FilesFinderService
8+
{
9+
public static function make()
10+
{
11+
return new self();
12+
}
13+
14+
/**
15+
* Find files
16+
*
17+
* @param string $path // for unix path should contains forward slash / instead of backward slash \
18+
* @param string $ext
19+
* @return void
20+
*/
21+
public function findFiles($path, string $ext = '\*')
22+
{
23+
$files = [];
24+
25+
$basePath = base_path();
26+
27+
$direactory = Str::contains($path, $basePath) ? $path : base_path($path);
28+
29+
$results = glob($direactory . $ext, GLOB_BRACE);
30+
31+
// for unix system glob ext should be forward slash /*
32+
if (!in_array($ext, ['\*', '*', '/*'])) {
33+
return $results;
34+
}
35+
36+
foreach ($results as $item) {
37+
if (is_dir($item)) {
38+
$files = array_merge($files, $this->findFiles($item, $ext));
39+
} elseif (is_file($item)) {
40+
$files[] = $item;
41+
}
42+
}
43+
44+
return $files;
45+
}
46+
47+
public function findClasses($path): array
48+
{
49+
$globePattern = strtolower(PHP_OS) == 'windows' ? '\*' : '/*'; // php_uname('s') also shows os name
50+
51+
$files = $this->findFiles($path, $globePattern);
52+
53+
$basePath = base_path();
54+
55+
$classList = [];
56+
57+
foreach ($files as $file) {
58+
if (is_file($file)) {
59+
//$fileName = pathinfo($file, PATHINFO_FILENAME);
60+
61+
$class = str_replace([$basePath . '/', '.php'], '', $file);
62+
63+
if(strtolower(PHP_OS) != 'windows' ){
64+
$class = str_replace('/', '\\', $class);
65+
}
66+
67+
$classList[] = ucfirst($class);
68+
}
69+
}
70+
71+
return $classList;
72+
}
73+
}

src/NavService.php

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@
1010
use Illuminate\Support\Facades\Route;
1111
use Illuminate\Contracts\Foundation\Application;
1212
use Illuminate\Support\Str;
13+
use RadiateCode\LaravelNavbar\Attributes\NavAttribute;
14+
use RadiateCode\LaravelNavbar\Attributes\NavItemsAttribute;
1315
use RadiateCode\LaravelNavbar\Contracts\WithNavbar;
1416
use RadiateCode\LaravelNavbar\Enums\Constant;
17+
use ReflectionClass;
18+
use ReflectionMethod;
1519

1620
class NavService
1721
{
@@ -46,6 +50,15 @@ public function menus(): NavService
4650

4751
$routes = Route::getRoutes();
4852

53+
$this->menus = $this->navItemsGenerate($routes);
54+
55+
$this->cacheNavs();
56+
57+
return $this;
58+
}
59+
60+
protected function navItemsGenerate($routes)
61+
{
4962
$menus = [];
5063

5164
$childrenTobeInjectInParent = [];
@@ -63,9 +76,9 @@ public function menus(): NavService
6376
continue;
6477
}
6578

66-
$currentControllerInstance = app('\\'.$currentController);
79+
$currentControllerInstance = app('\\' . $currentController);
6780

68-
if ( ! $currentControllerInstance instanceof WithNavbar) {
81+
if (!$currentControllerInstance instanceof WithNavbar) {
6982
continue;
7083
}
7184

@@ -77,11 +90,11 @@ public function menus(): NavService
7790

7891
$this->currentNavInstance = $currentControllerInstance->getNavbarInstance();
7992

80-
if(! $this->currentNavInstance->isCreatable()){
81-
continue;
93+
if (!$this->currentNavInstance->isCreatable()) {
94+
continue;
8295
}
8396

84-
if($this->currentNavInstance->hasHeader()){
97+
if ($this->currentNavInstance->hasHeader()) {
8598
$this->prepareHeader($menus);
8699
}
87100

@@ -91,7 +104,7 @@ public function menus(): NavService
91104
* Nav link keys are generated by controller action method,
92105
* so check current controller action method is a nav link
93106
*/
94-
if ( ! in_array($this->currentControllerMethod, array_keys($this->currentNavLinks))) {
107+
if (!in_array($this->currentControllerMethod, array_keys($this->currentNavLinks))) {
95108
continue;
96109
}
97110

@@ -126,9 +139,9 @@ public function menus(): NavService
126139

127140
$currentMenuName = $currentMenu['name'];
128141

129-
if (Arr::get($menus, $currentMenuName.'.nav-links')) {
130-
$this->arr_push($menus,$currentMenuName.'.nav-links',$this->prepareNavLink($route));
131-
}else{
142+
if (Arr::get($menus, $currentMenuName . '.nav-links')) {
143+
$this->arr_push($menus, $currentMenuName . '.nav-links', $this->prepareNavLink($route));
144+
} else {
132145
$preparedMenu = $this->prepareNav($currentMenu, $this->prepareNavLink($route));
133146

134147
$menus[$currentMenuName] = $preparedMenu[$currentMenuName];
@@ -145,11 +158,7 @@ public function menus(): NavService
145158
// check is there any nav-links waiting to be inject in the menus
146159
$this->linksToBeAppend($navLinksTobeInject, $menus);
147160

148-
$this->menus = $menus;
149-
150-
$this->cacheNavs();
151-
152-
return $this;
161+
return $menus;
153162
}
154163

155164
protected function getCacheNavs()
@@ -168,7 +177,7 @@ protected function cacheNavs()
168177

169178
$enable = config('navbar.cache-enable');
170179

171-
if ($enable && ! $this->hasCacheNavs()) {
180+
if ($enable && !$this->hasCacheNavs()) {
172181
Cache::put(Constant::CACHE_NAVS, $this->menus, $ttl);
173182
}
174183
}
@@ -186,13 +195,14 @@ public function toArray(): array
186195
return $this->menus;
187196
}
188197

189-
protected function prepareHeader(&$menus){
198+
protected function prepareHeader(&$menus)
199+
{
190200
$header = $this->currentNavInstance->getHeader();
191201

192-
if (! Arr::get($menus, $header['name'])) {
202+
if (!Arr::get($menus, $header['name'])) {
193203
$menus[$header['name']] = [
194-
'title' => ucwords(str_replace('-', ' ', $header['name'])),
195-
'type' => $header['type']
204+
'title' => ucwords(str_replace('-', ' ', $header['name'])),
205+
'type' => $header['type']
196206
];
197207
}
198208
}
@@ -213,10 +223,10 @@ protected function prepareChildrenNav(&$menus, &$childrenTobeInjectInParent, $cu
213223
* If parent menu is not a controller class then prepare the parent menu from the given string
214224
* [Note: This non-class parent menu only works as root level menu, it will not append as child]
215225
*/
216-
if (! class_exists('\\'.$parent['name'])){
226+
if (!class_exists('\\' . $parent['name'])) {
217227
$parentMenuName = Str::slug($parent['name']);
218228

219-
if (! Arr::get($menus, $parentMenuName)) {
229+
if (!Arr::get($menus, $parentMenuName)) {
220230
$menus[$parentMenuName] = [
221231
'icon' => $parent['icon'],
222232
'title' => ucwords(str_replace('-', ' ', $parentMenuName)),
@@ -230,11 +240,10 @@ protected function prepareChildrenNav(&$menus, &$childrenTobeInjectInParent, $cu
230240
* If the parent menu is a controller then get the menu info from the controller
231241
*/
232242

233-
else
234-
{
235-
$parentControllerInstance = app('\\'.$parent['name']);
243+
else {
244+
$parentControllerInstance = app('\\' . $parent['name']);
236245

237-
if ( ! $parentControllerInstance instanceof WithNavbar) {
246+
if (!$parentControllerInstance instanceof WithNavbar) {
238247
return false;
239248
}
240249

@@ -254,7 +263,7 @@ protected function prepareChildrenNav(&$menus, &$childrenTobeInjectInParent, $cu
254263

255264
// if parent menu is not exist temporarily store it to $childrenTobeInjectInParent
256265
// so that when parent menu appear we can inject the children menu
257-
if ( ! $exist) {
266+
if (!$exist) {
258267
$navLinks = $this->prepareNavLink($route);
259268

260269
$preparedMenu = $this->prepareNav($currentMenu, $navLinks);
@@ -266,7 +275,7 @@ protected function prepareChildrenNav(&$menus, &$childrenTobeInjectInParent, $cu
266275

267276
// parent menu save to $childrenTobeInjectInParent
268277
// so that when the parent menu will appear we can injects it's children
269-
$navLinksOfChildren = $parentMenuName.'.children.'.$currentMenuName.'.nav-links';
278+
$navLinksOfChildren = $parentMenuName . '.children.' . $currentMenuName . '.nav-links';
270279

271280
if (Arr::get($childrenTobeInjectInParent, $navLinksOfChildren)) {
272281
$this->arr_push($childrenTobeInjectInParent, $navLinksOfChildren, $navLinks);
@@ -285,7 +294,7 @@ protected function prepareChildrenNav(&$menus, &$childrenTobeInjectInParent, $cu
285294
$livingTails = $this->tail();
286295

287296
// add children key to the position of the parent menu
288-
$children = $livingTails.".children";
297+
$children = $livingTails . ".children";
289298

290299
// prepare the current menu array
291300
$navLinks = $this->prepareNavLink($route);
@@ -297,9 +306,9 @@ protected function prepareChildrenNav(&$menus, &$childrenTobeInjectInParent, $cu
297306
$preparedMenu[$currentMenuName]['children'] = $childrenTobeInjectInParent[$currentMenuName]['children'];
298307
}
299308

300-
$childrenMenu = $children.'.'.$currentMenuName;
309+
$childrenMenu = $children . '.' . $currentMenuName;
301310

302-
$navLinksOfChildren = $childrenMenu.'.nav-links';
311+
$navLinksOfChildren = $childrenMenu . '.nav-links';
303312

304313
if (Arr::get($menus, $childrenMenu)) { // if children menu exist
305314
// then add only a nav link to the nav-links of that children menu
@@ -317,7 +326,8 @@ protected function prepareChildrenNav(&$menus, &$childrenTobeInjectInParent, $cu
317326
*
318327
* @throws Exception
319328
*/
320-
protected function prepareOrAppendLinks(&$menus, &$navLinksTobeInject, $route) {
329+
protected function prepareOrAppendLinks(&$menus, &$navLinksTobeInject, $route)
330+
{
321331
if ($this->currentNavInstance->hasInconsistencyInAppend()) {
322332
throw new Exception(
323333
'Inconsistency occurred between links and append to!'
@@ -326,7 +336,7 @@ protected function prepareOrAppendLinks(&$menus, &$navLinksTobeInject, $route) {
326336

327337
$appendControllerInstance = $this->makeAppendControllerInstance();
328338

329-
if ( ! $appendControllerInstance instanceof WithNavbar) {
339+
if (!$appendControllerInstance instanceof WithNavbar) {
330340
return null;
331341
}
332342

@@ -352,7 +362,7 @@ protected function prepareOrAppendLinks(&$menus, &$navLinksTobeInject, $route) {
352362
$livingTails = $this->tail();
353363

354364
// add nav-links key to the position of the append menu
355-
$navLinks = $livingTails.".nav-links";
365+
$navLinks = $livingTails . ".nav-links";
356366

357367
// prepare the appended link
358368
$navLink = $this->prepareNavLink($route);
@@ -382,7 +392,7 @@ protected function linksToBeAppend(&$navLinksTobeInject, &$menus)
382392

383393
if ($exist) {
384394
// get the position of the parent menu
385-
$livingTails = $this->tail().'.nav-links';
395+
$livingTails = $this->tail() . '.nav-links';
386396

387397
$links = Arr::get($menus, $livingTails);
388398

@@ -464,7 +474,7 @@ protected function makeAppendControllerInstance()
464474

465475
$appendTo = $appendMenus[$position];
466476

467-
return app('\\'.$appendTo);
477+
return app('\\' . $appendTo);
468478
}
469479

470480
/**
@@ -525,7 +535,7 @@ private function arr_push(&$array, $key, $value)
525535
// If the key doesn't exist at this depth, we will just create an empty array
526536
// to hold the next value, allowing us to create the arrays to hold final
527537
// values at the correct depth. Then we'll keep digging into the array.
528-
if ( ! isset($array[$key]) || ! is_array($array[$key])) {
538+
if (!isset($array[$key]) || !is_array($array[$key])) {
529539
$array[$key] = [];
530540
}
531541

0 commit comments

Comments
 (0)