adding counter on menu
This commit is contained in:
@@ -3,13 +3,18 @@
|
||||
namespace App\Http\Controllers\Superuser;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Menus\Menu as MenusMenu;
|
||||
use App\Models\Menu;
|
||||
use App\Models\Permission;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Str;
|
||||
use Inertia\Inertia;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use SplFileInfo;
|
||||
use Throwable;
|
||||
|
||||
@@ -29,13 +34,55 @@ class MenuController extends Controller
|
||||
'routes' => array_values($routes),
|
||||
'icons' => $this->icons(),
|
||||
'menus' => $this->get(),
|
||||
'handlers' => $this->handlers(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function icons()
|
||||
private function handlers() : array
|
||||
{
|
||||
$handlers = [];
|
||||
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(
|
||||
app_path('Menus')
|
||||
));
|
||||
|
||||
foreach ($iterator as $splFileInfo) {
|
||||
/**
|
||||
* @var \SplFileInfo $splFileInfo
|
||||
*/
|
||||
if ($splFileInfo->isDir()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($splFileInfo->getFilename() === 'Menu.php') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$class = str_replace(dirname(app_path()), '', $splFileInfo->getRealPath());
|
||||
$class = mb_substr(trim($class, DIRECTORY_SEPARATOR), 0, -4);
|
||||
$class = str_replace(DIRECTORY_SEPARATOR, '\\', ucfirst($class));
|
||||
|
||||
if (!class_exists($class) && !is_subclass_of($class, MenusMenu::class)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = str_replace(['App\\Menus\\', '\\'], ['', ' '], $class);
|
||||
|
||||
$handlers[] = [
|
||||
'class' => $class,
|
||||
'name' => ucwords(Str::snake($name, ' ')),
|
||||
];
|
||||
}
|
||||
|
||||
return $handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function icons() : array
|
||||
{
|
||||
return array_map(
|
||||
callback: fn (string $name) => mb_substr(
|
||||
@@ -78,14 +125,24 @@ class MenuController extends Controller
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$post = $request->validate([
|
||||
Validator::make($request->all(), [
|
||||
'name' => 'required|string',
|
||||
'icon' => 'nullable|string',
|
||||
'route_or_url' => 'nullable|string',
|
||||
'counter_handler' => 'nullable|string',
|
||||
'actives.*' => 'nullable|string',
|
||||
'permissions.*' => 'nullable|integer|exists:permissions,id',
|
||||
]);
|
||||
])->after(function ($validator) use ($request) {
|
||||
if (($class = $request->counter_handler) && !class_exists($class)) {
|
||||
$validator->errors()->add('counter_handler', __(
|
||||
'class :name doesn\'t exists', [
|
||||
'name' => $class,
|
||||
],
|
||||
));
|
||||
}
|
||||
})->validate();
|
||||
|
||||
$post = $request->all();
|
||||
$post['position'] = Menu::whereNull('parent_id')->count() + 1;
|
||||
|
||||
if ($menu = Menu::create($post)) {
|
||||
@@ -112,13 +169,22 @@ class MenuController extends Controller
|
||||
*/
|
||||
public function update(Request $request, Menu $menu)
|
||||
{
|
||||
$request->validate([
|
||||
Validator::make($request->all(), [
|
||||
'name' => 'required|string',
|
||||
'icon' => 'nullable|string',
|
||||
'route_or_url' => 'nullable|string',
|
||||
'counter_handler' => 'nullable|string',
|
||||
'actives.*' => 'nullable|string',
|
||||
'permissions.*' => 'nullable|integer|exists:permissions,id',
|
||||
]);
|
||||
])->after(function ($validator) use ($request) {
|
||||
if (($class = $request->counter_handler) && !class_exists($class)) {
|
||||
$validator->errors()->add('counter_handler', __(
|
||||
'class :name doesn\'t exists', [
|
||||
'name' => $class,
|
||||
],
|
||||
));
|
||||
}
|
||||
})->validate();
|
||||
|
||||
if ($menu->update($request->all())) {
|
||||
$menu->permissions()->sync($request->input('permissions', []));
|
||||
@@ -251,4 +317,27 @@ class MenuController extends Controller
|
||||
return $new;
|
||||
}, $menus);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \App\Models\Menu $menu
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function counter(Menu $menu)
|
||||
{
|
||||
$menu = Menu::with('childs')->find($menu->id);
|
||||
|
||||
return [
|
||||
'count' => $this->counters(0, $menu),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $total
|
||||
* @param \App\Models\Menu $menu
|
||||
* @return int
|
||||
*/
|
||||
public function counters(int $total, Menu $menu)
|
||||
{
|
||||
return $total + $menu->counter?->count() + $menu->childs->reduce([$this, 'counters'], 0);
|
||||
}
|
||||
}
|
||||
|
||||
13
app/Menus/Menu.php
Normal file
13
app/Menus/Menu.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Menus;
|
||||
|
||||
use Countable;
|
||||
|
||||
abstract class Menu implements Countable
|
||||
{
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
abstract public function count() : int;
|
||||
}
|
||||
16
app/Menus/UserMenu.php
Normal file
16
app/Menus/UserMenu.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Menus;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
class UserMenu extends Menu
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function count() : int
|
||||
{
|
||||
return User::count();
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ class Menu extends Model
|
||||
'name',
|
||||
'icon',
|
||||
'route_or_url',
|
||||
'counter_handler',
|
||||
'position',
|
||||
'enable',
|
||||
'actives',
|
||||
@@ -34,6 +35,13 @@ class Menu extends Model
|
||||
'permissions',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $appends = [
|
||||
'counter',
|
||||
];
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||
*/
|
||||
@@ -88,4 +96,14 @@ class Menu extends Model
|
||||
set: fn ($value) => is_array($value) || $value instanceof JsonSerializable || $value instanceof stdClass ? json_encode($value) : $value,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Casts\Attribute
|
||||
*/
|
||||
public function counter() : Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->counter_handler ? new $this->counter_handler : null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user