├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── logs └── v3.3.5.txt └── src ├── Commands └── PackageSetup.php ├── Controllers ├── Admin │ ├── AdminController.php │ ├── MenusController.php │ ├── PagesController.php │ ├── PermissionsController.php │ ├── RolesController.php │ ├── Traits │ │ ├── MenuOps.php │ │ ├── PageOps.php │ │ ├── Paginate.php │ │ ├── RolePermOps.php │ │ └── UserPageOps.php │ └── UsersController.php ├── BaseController.php └── DummyController.php ├── Facade └── SimpleMenu.php ├── Middleware ├── PermissionMiddleware.php └── RoleMiddleware.php ├── Models ├── Menu.php ├── Page.php └── Traits │ └── SMUsers.php ├── Observers ├── BaseObserver.php ├── MenuObserver.php ├── PageObserver.php └── UserObserver.php ├── SimpleMenu.php ├── SimpleMenuServiceProvider.php ├── Traits ├── Menus.php ├── Navigation.php ├── Ops.php ├── PackageRoutes.php └── Routes.php ├── config └── simpleMenu.php ├── database ├── migrations │ ├── 2014_10_12_000000_create_users_table.php │ ├── 2017_02_28_202951_create_pages_table.php │ ├── 2017_03_01_232714_create_menus_table.php │ └── 2017_03_01_232836_create_menu_page_table.php └── seeds │ ├── DatabaseSeeder.example │ ├── MenuPagesTableSeeder.php │ ├── MenusTableSeeder.php │ ├── PagesTableSeeder.php │ └── RolePermSeeder.php └── resources ├── assets ├── js │ ├── index.vue │ ├── manager.js │ ├── menu.vue │ ├── menu_child.vue │ ├── mixins │ │ ├── menu.js │ │ └── search.js │ └── page.vue └── sass │ ├── _checkbox.scss │ └── style.scss ├── lang └── en │ └── messages.php ├── pagination └── bulma.blade.php └── views ├── admin ├── admin.blade.php ├── editors.blade.php ├── menus │ ├── create.blade.php │ ├── edit.blade.php │ └── index.blade.php ├── pages │ ├── create.blade.php │ ├── edit.blade.php │ └── index.blade.php ├── permissions │ ├── create.blade.php │ ├── edit.blade.php │ └── index.blade.php ├── roles │ ├── create.blade.php │ ├── edit.blade.php │ └── index.blade.php ├── shared.blade.php └── users │ ├── create.blade.php │ ├── edit.blade.php │ └── index.blade.php ├── breadCrumb.blade.php ├── langSwitcher.blade.php ├── menu ├── example.blade.php └── partials │ ├── nested.blade.php │ └── r_params.blade.php └── template-example.blade.php /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: ctf0 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .history 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Muah 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | SimpleMenu 3 |
4 | Latest Stable Version Total Downloads 5 |

6 | 7 | Create menus & pages that support (multiLocale "title, url, body, ...", nesting, template, static & dynamic data, roles & permissions). 8 | 9 | - package requires Laravel v5.5+ 10 | - package rely heavily on caching so make sure to install one of the tag enabled drivers [Memcached / Redis](https://laravel.com/docs/5.5/cache) 11 | 12 |
13 | 14 | ## Installation 15 | 16 | - `composer require ctf0/simple-menu` 17 | 18 | - after installation, run `php artisan sm:setup` to add 19 | + package routes to `routes/web.php` 20 | + package assets compiling to `webpack.mix.js` 21 | 22 | - publish the packages assets with `php artisan vendor:publish` 23 | - [simpleMenu](https://github.com/ctf0/simple-menu/wiki/Publish) 24 | - [laravel-permission](https://github.com/spatie/laravel-permission#laravel) 25 | - [laravel-translatable](https://github.com/spatie/laravel-translatable#installation) 26 | - [laravel-localization](https://github.com/mcamara/laravel-localization#config) 27 | 28 | - install JS dependencies 29 | 30 | ```bash 31 | yarn add vue axios vue-tippy@v2 vuedraggable vue-notif vue-multi-ref vue-awesome@v2 list.js 32 | ``` 33 | 34 | - add this one liner to your main js file and run `npm run watch` to compile your `js/css` files. 35 | + if you are having issues [Check](https://ctf0.wordpress.com/2017/09/12/laravel-mix-es6/). 36 | 37 | ```js 38 | // app.js 39 | 40 | window.Vue = require('vue') 41 | 42 | require('../vendor/SimpleMenu/js/manager') 43 | 44 | new Vue({ 45 | el: '#app' 46 | }) 47 | ``` 48 | 49 |
50 | 51 | ## Config 52 | 53 | **config/simpleMenu.php** 54 | 55 | ```php 56 | return [ 57 | /* 58 | * the menu list classes to be used for "render()" 59 | */ 60 | 'listClasses' => [ 61 | 'ul' => 'menu-list', 62 | 'li' => 'list-item', 63 | 'a' => 'is-active', 64 | ], 65 | 66 | /* 67 | * the path where we will save the routes list 68 | */ 69 | 'routeListPath' => storage_path('logs/simpleMenu.php'), 70 | 71 | /* 72 | * where to redirect when a route is available in one locale "en" but not in another "fr" ? 73 | */ 74 | 'unFoundLocalizedRoute' => 'root', 75 | 76 | /* 77 | * package models 78 | */ 79 | 'models'=> [ 80 | 'user' => App\User::class, 81 | 'page' => \ctf0\SimpleMenu\Models\Page::class, 82 | 'menu' => \ctf0\SimpleMenu\Models\Menu::class, 83 | ], 84 | 85 | /* 86 | * when adding a page which is a nest of a nother to a menu, ex. 87 | * 88 | * root 89 | * | child 1 90 | * | child 2 "add this along with its childrens to another menu" 91 | * | child 3 92 | * 93 | * do you want to clear its parent and make it a root ? 94 | */ 95 | 'clearPartialyNestedParent' => true, 96 | 97 | /* 98 | * when removing a root page from a menu, ex. 99 | * 100 | * root "remove" 101 | * | child 1 102 | * | child 2 103 | * | child 3 104 | * 105 | * do you want clear all of its 'Descendants' ? 106 | */ 107 | 'clearRootDescendants' => false, 108 | 109 | /* 110 | * when removing a nest from a list, ex. 111 | * 112 | * root 113 | * | child 1 114 | * | child 2 "remove" 115 | * | child 3 116 | * 117 | * do you want to reset its hierarchy ? 118 | */ 119 | 'clearNestDescendants'=> false, 120 | 121 | /* 122 | * when deleting a page "from the db", ex. 123 | * 124 | * page "delete/destroy" 125 | * | nested child 1 126 | * | nested child 2 127 | * | nested child 3 128 | * 129 | * do you also want to delete all of its children ? 130 | */ 131 | 'deletePageAndNests' => false, 132 | 133 | /* 134 | * package routes url & route name prefix 135 | */ 136 | 'crud_prefix' => 'admin', 137 | 138 | /* 139 | * all the package controllers 140 | * 141 | * if you need to change anything, just create new controller 142 | * and extend from the below original 143 | * ex. "class ExampleController extends PagesController" 144 | */ 145 | 'controllers'=> [ 146 | 'permissions' => '\ctf0\SimpleMenu\Controllers\Admin\PermissionsController', 147 | 'admin' => '\ctf0\SimpleMenu\Controllers\Admin\AdminController@index', 148 | 'users' => '\ctf0\SimpleMenu\Controllers\Admin\UsersController', 149 | 'pages' => '\ctf0\SimpleMenu\Controllers\Admin\PagesController', 150 | 'roles' => '\ctf0\SimpleMenu\Controllers\Admin\RolesController', 151 | 'menus' => '\ctf0\SimpleMenu\Controllers\Admin\MenusController', 152 | ], 153 | ]; 154 | ``` 155 | 156 |
157 | 158 | ## Usage 159 | 160 | > [Demo](https://github.com/ctf0/demos/tree/simple-menu)
161 | > [Usage](https://github.com/ctf0/simple-menu/wiki/Usage)
162 | > [Views](https://github.com/ctf0/SimpleMenu/wiki/Crud-Views) 163 | 164 | - add `SMUsers` trait to your **User Model** 165 | 166 | ```php 167 | use ctf0\SimpleMenu\Models\Traits\SMUsers; 168 | 169 | // ... 170 | 171 | class User extends Authenticatable 172 | { 173 | use Notifiable, SMUsers; 174 | } 175 | ``` 176 | 177 | - visit `localhost:8000/admin` 178 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ctf0/simple-menu", 3 | "description": "create a menu that support page (multiLocale 'title/ url/ prefix', nesting, template, static/dynamic, roles & permissions).", 4 | "homepage": "https://github.com/ctf0/SimpleMenu", 5 | "license": "MIT", 6 | "keywords": [ 7 | "ctf0", 8 | "SimpleMenu", 9 | "menu", 10 | "manager", 11 | "laravel", 12 | "gui", 13 | "multi-locale" 14 | ], 15 | "authors": [ 16 | { 17 | "name": "Muah", 18 | "email": "muah003@gmail.com" 19 | } 20 | ], 21 | "require": { 22 | "illuminate/support": ">=5.4 <9.0", 23 | "gazsp/baum": "*", 24 | "mcamara/laravel-localization": "*", 25 | "spatie/laravel-permission": "*", 26 | "spatie/laravel-translatable": "*", 27 | "codezero/laravel-unique-translation": "*", 28 | "ctf0/package-changelog": "*", 29 | "laravelcollective/html": "*" 30 | }, 31 | "autoload": { 32 | "psr-4": { 33 | "ctf0\\SimpleMenu\\": "src" 34 | } 35 | }, 36 | "extra": { 37 | "laravel": { 38 | "providers": [ 39 | "ctf0\\SimpleMenu\\SimpleMenuServiceProvider" 40 | ], 41 | "aliases": { 42 | "SimpleMenu": "ctf0\\SimpleMenu\\Facade\\SimpleMenu" 43 | } 44 | }, 45 | "changeLog": "logs" 46 | }, 47 | "config": { 48 | "sort-packages": true 49 | }, 50 | "scripts": { 51 | "post-package-install": [ 52 | "@php artisan vendor:publish" 53 | ] 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /logs/v3.3.5.txt: -------------------------------------------------------------------------------- 1 | - use role & perm models from the config instead of spatie 2 | - fix anchor class in render() not using passed className 3 | - cleanup 4 | - fix not working with swoole -------------------------------------------------------------------------------- /src/Commands/PackageSetup.php: -------------------------------------------------------------------------------- 1 | file = app('files'); 20 | 21 | parent::__construct(); 22 | } 23 | 24 | /** 25 | * Execute the console command. 26 | * 27 | * @return mixed 28 | */ 29 | public function handle() 30 | { 31 | // routes 32 | $route_file = base_path('routes/web.php'); 33 | $search = 'SimpleMenu'; 34 | 35 | if ($this->checkExist($route_file, $search)) { 36 | $data = "\n// SimpleMenu\nSimpleMenu::menuRoutes();"; 37 | 38 | $this->file->append($route_file, $data); 39 | } 40 | 41 | // mix 42 | $mix_file = base_path('webpack.mix.js'); 43 | $search = 'SimpleMenu'; 44 | 45 | if ($this->checkExist($mix_file, $search)) { 46 | $data = "\n// SimpleMenu\nmix.sass('resources/assets/vendor/SimpleMenu/sass/style.scss', 'public/assets/vendor/SimpleMenu/style.css')"; 47 | 48 | $this->file->append($mix_file, $data); 49 | } 50 | 51 | $this->info('All Done'); 52 | } 53 | 54 | /** 55 | * [checkExist description]. 56 | * 57 | * @param [type] $file [description] 58 | * @param [type] $search [description] 59 | * 60 | * @return [type] [description] 61 | */ 62 | protected function checkExist($file, $search) 63 | { 64 | return $this->file->exists($file) && !Str::contains($this->file->get($file), $search); 65 | } 66 | } -------------------------------------------------------------------------------- /src/Controllers/Admin/AdminController.php: -------------------------------------------------------------------------------- 1 | adminPath}.admin")->with([ 17 | 'title' => 'DashBoard', 18 | 'desc' => 'Admin DashBoard', 19 | ]); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Controllers/Admin/MenusController.php: -------------------------------------------------------------------------------- 1 | cache->tags('sm')->get('menus'); 21 | 22 | return view("{$this->adminPath}.menus.index", compact('menus')); 23 | } 24 | 25 | /** 26 | * Show the form for creating new Menu. 27 | * 28 | * @return \Illuminate\Http\Response 29 | */ 30 | public function create() 31 | { 32 | return view("{$this->adminPath}.menus.create"); 33 | } 34 | 35 | /** 36 | * Store a newly created Menu in storage. 37 | * 38 | * @param \App\Http\Requests\StoreMenusRequest $request 39 | * 40 | * @return \Illuminate\Http\Response 41 | */ 42 | public function store(Request $request) 43 | { 44 | $this->validate($request, [ 45 | 'name' => 'required|unique:menus,name', 46 | ]); 47 | 48 | $menu = $this->menuModel->create($request->all()); 49 | 50 | return redirect() 51 | ->route($this->crud_prefix . '.menus.index') 52 | ->with('status', trans('SimpleMenu::messages.model_created')); 53 | } 54 | 55 | /** 56 | * Show the form for editing Menu. 57 | * 58 | * @param int $id 59 | * 60 | * @return \Illuminate\Http\Response 61 | */ 62 | public function edit($id) 63 | { 64 | $menu = $this->cache->tags('sm')->get('menus')->find($id) ?: abort(404); 65 | 66 | return view("{$this->adminPath}.menus.edit", compact('menu')); 67 | } 68 | 69 | /** 70 | * Update Menu in storage. 71 | * 72 | * @param \App\Http\Requests\UpdateMenusRequest $request 73 | * @param int $id 74 | * 75 | * @return \Illuminate\Http\Response 76 | */ 77 | public function update($id, Request $request) 78 | { 79 | $this->validate($request, [ 80 | 'name' => 'required|unique:menus,name,' . $id, 81 | ]); 82 | 83 | $menu = $this->menuModel->findOrFail($id); 84 | 85 | // clear prev records 86 | $menu->pages()->detach(); 87 | 88 | foreach (json_decode($request->saveList) as $item) { 89 | if (config('simpleMenu.clearPartialyNestedParent')) { 90 | $this->clearSelfAndNests($item->id); 91 | } else { 92 | $this->clearNests($item->id); 93 | } 94 | 95 | // save page hierarchy 96 | if ($item->children) { 97 | $this->saveListToDb($item->children); 98 | } 99 | 100 | // update the menu root list 101 | $menu->pages()->attach($item->id, ['order'=>$item->order]); 102 | } 103 | 104 | // update and trigger events 105 | $menu->update($request->except('saveList')); 106 | $menu->touch(); 107 | 108 | return back()->with('status', trans('SimpleMenu::messages.model_updated')); 109 | } 110 | 111 | /** 112 | * Remove Menu from storage. 113 | * 114 | * @param int $id 115 | * 116 | * @return \Illuminate\Http\Response 117 | */ 118 | public function destroy($id, Request $request) 119 | { 120 | $menu = $this->menuModel->findOrFail($id); 121 | $menu->pages()->detach(); 122 | $menu->delete(); 123 | 124 | if ($request->expectsJson()) { 125 | return response()->json(['done'=>true]); 126 | } 127 | 128 | return redirect() 129 | ->route($this->crud_prefix . '.menus.index') 130 | ->with('status', trans('SimpleMenu::messages.model_deleted')); 131 | } 132 | 133 | public function destroyMulti(Request $request) 134 | { 135 | $ids = explode(',', $request->ids); 136 | 137 | foreach ($ids as $one) { 138 | $menu = $this->menuModel->findOrFail($one); 139 | $menu->pages()->detach(); 140 | $menu->delete(); 141 | } 142 | 143 | return redirect() 144 | ->route($this->crud_prefix . '.menus.index') 145 | ->with('status', trans('SimpleMenu::messages.models_deleted')); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/Controllers/Admin/PagesController.php: -------------------------------------------------------------------------------- 1 | cache->tags('sm')->get('pages'); 23 | 24 | return view("{$this->adminPath}.pages.index", compact('pages')); 25 | } 26 | 27 | /** 28 | * Show the form for creating new Page. 29 | * 30 | * @return \Illuminate\Http\Response 31 | */ 32 | public function create() 33 | { 34 | $locales = SimpleMenu::AppLocales(); 35 | $roles = $this->roleModel->pluck('name', 'name'); 36 | $permissions = $this->permissionModel->pluck('name', 'name'); 37 | $menus = $this->cache->tags('sm')->get('menus')->pluck('name', 'id'); 38 | $templates = array_unique($this->cache->tags('sm')->get('pages')->pluck('template')->filter()->all()); 39 | 40 | return view("{$this->adminPath}.pages.create", compact('locales', 'roles', 'permissions', 'menus', 'templates')); 41 | } 42 | 43 | /** 44 | * Store a newly created Page in storage. 45 | * 46 | * @param \App\Http\Requests\StorePagesRequest $request 47 | * 48 | * @return \Illuminate\Http\Response 49 | */ 50 | public function store(Request $request) 51 | { 52 | $this->sT_uP_Validaiton($request); 53 | 54 | $img = $this->getImage($request->cover); 55 | $page = $this->pageModel->create(array_merge(['cover'=>$img], $this->cleanEmptyTranslations($request))); 56 | $roles = $request->roles ?: []; 57 | $permissions = $request->permissions ?: []; 58 | $menus = $request->menus ?: []; 59 | 60 | $page->assignRole($roles); 61 | $page->givePermissionTo($permissions); 62 | $page->assignToMenus($menus); 63 | 64 | return redirect() 65 | ->route($this->crud_prefix . '.pages.index') 66 | ->with('status', trans('SimpleMenu::messages.model_created')); 67 | } 68 | 69 | /** 70 | * Show the form for editing Page. 71 | * 72 | * @param int $id 73 | * 74 | * @return \Illuminate\Http\Response 75 | */ 76 | public function edit($id) 77 | { 78 | $locales = SimpleMenu::AppLocales(); 79 | $roles = $this->roleModel->pluck('name', 'name'); 80 | $permissions = $this->permissionModel->pluck('name', 'name'); 81 | $page = $this->pageModel->findOrFail($id); 82 | $menus = $this->cache->tags('sm')->get('menus')->pluck('name', 'id'); 83 | $templates = array_unique($this->cache->tags('sm')->get('pages')->pluck('template')->filter()->all()); 84 | 85 | $controllerFile = $page->action ? $this->actionFileContent($page->action, 'get') : null; 86 | 87 | return view("{$this->adminPath}.pages.edit", compact('locales', 'roles', 'permissions', 'page', 'menus', 'templates', 'controllerFile')); 88 | } 89 | 90 | /** 91 | * Update Page in storage. 92 | * 93 | * @param \App\Http\Requests\UpdatePagesRequest $request 94 | * @param int $id 95 | * 96 | * @return \Illuminate\Http\Response 97 | */ 98 | public function update($id, Request $request) 99 | { 100 | $this->sT_uP_Validaiton($request, $id); 101 | 102 | $img = $this->getImage($request->cover); 103 | $page = $this->getItem($id); 104 | $roles = $request->roles; 105 | $permissions = $request->permissions; 106 | $menus = $request->menus ?: []; 107 | 108 | $page->update(array_merge(['cover'=>$img], $this->cleanEmptyTranslations($request))); 109 | 110 | if (!$this->checkBeforeAssign($page->roles, $roles)) { 111 | $page->syncRoles($roles ?: []); 112 | } 113 | 114 | if (!$this->checkBeforeAssign($page->permissions, $permissions)) { 115 | $page->syncPermissions($permissions ?: []); 116 | } 117 | 118 | $page->syncMenus($menus); 119 | 120 | if (!is_null($request->controllerFile)) { 121 | $this->actionFileContent($request->action, 'update', $request->controllerFile); 122 | } 123 | 124 | $page->touch(); 125 | 126 | return back()->with('status', trans('SimpleMenu::messages.model_updated')); 127 | } 128 | 129 | /** 130 | * Remove Page. 131 | * 132 | * @param int $id 133 | * 134 | * @return \Illuminate\Http\Response 135 | */ 136 | public function destroy($id, Request $request) 137 | { 138 | $this->pageModel->destroy($id); 139 | 140 | if ($request->expectsJson()) { 141 | return response()->json(['done'=>true]); 142 | } 143 | 144 | return redirect() 145 | ->route($this->crud_prefix . '.pages.index') 146 | ->with('status', trans('SimpleMenu::messages.model_deleted')); 147 | } 148 | 149 | public function destroyMulti(Request $request) 150 | { 151 | $ids = explode(',', $request->ids); 152 | 153 | $this->pageModel->destroy($ids); 154 | 155 | return redirect() 156 | ->route($this->crud_prefix . '.pages.index') 157 | ->with('status', trans('SimpleMenu::messages.models_deleted')); 158 | } 159 | 160 | /** 161 | * restore model. 162 | * 163 | * @param [type] $id [description] 164 | * 165 | * @return [type] [description] 166 | */ 167 | public function restore($id) 168 | { 169 | $this->getItem($id)->restore(); 170 | 171 | return redirect() 172 | ->route($this->crud_prefix . '.pages.index') 173 | ->with('status', trans('SimpleMenu::messages.model_updated')); 174 | } 175 | 176 | /** 177 | * Remove Page Permanently. 178 | * 179 | * @param [type] $id [description] 180 | * 181 | * @return [type] [description] 182 | */ 183 | public function forceDelete($id) 184 | { 185 | $this->getItem($id)->forceDelete(); 186 | 187 | return redirect() 188 | ->route($this->crud_prefix . '.pages.index') 189 | ->with('status', trans('SimpleMenu::messages.model_deleted_perm')); 190 | } 191 | 192 | /** 193 | * helper. 194 | * 195 | * @param [type] $id [description] 196 | * 197 | * @return [type] [description] 198 | */ 199 | protected function getItem($id) 200 | { 201 | return $this->pageModel->withTrashed()->findOrFail($id); 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /src/Controllers/Admin/PermissionsController.php: -------------------------------------------------------------------------------- 1 | permissionModel->get(); 21 | 22 | return view("{$this->adminPath}.permissions.index", compact('permissions')); 23 | } 24 | 25 | /** 26 | * Show the form for creating new Permission. 27 | * 28 | * @return \Illuminate\Http\Response 29 | */ 30 | public function create() 31 | { 32 | return view("{$this->adminPath}.permissions.create"); 33 | } 34 | 35 | /** 36 | * Store a newly created Permission in storage. 37 | * 38 | * @param \App\Http\Requests\StorePermissionsRequest $request 39 | * 40 | * @return \Illuminate\Http\Response 41 | */ 42 | public function store(Request $request) 43 | { 44 | $this->validate($request, [ 45 | 'name' => 'required|unique:permissions,name', 46 | ]); 47 | 48 | $this->permissionModel->create($request->all()); 49 | 50 | return redirect() 51 | ->route($this->crud_prefix . '.permissions.index') 52 | ->with('status', trans('SimpleMenu::messages.model_created')); 53 | } 54 | 55 | /** 56 | * Show the form for editing Permission. 57 | * 58 | * @param int $id 59 | * 60 | * @return \Illuminate\Http\Response 61 | */ 62 | public function edit($id) 63 | { 64 | $permission = $this->permissionModel->findOrFail($id); 65 | 66 | return view("{$this->adminPath}.permissions.edit", compact('permission')); 67 | } 68 | 69 | /** 70 | * Update Permission in storage. 71 | * 72 | * @param \App\Http\Requests\UpdatePermissionsRequest $request 73 | * @param int $id 74 | * 75 | * @return \Illuminate\Http\Response 76 | */ 77 | public function update($id, Request $request) 78 | { 79 | $this->validate($request, [ 80 | 'name' => 'required|unique:permissions,name,' . $id, 81 | ]); 82 | 83 | $this->permissionModel->findOrFail($id)->update($request->all()); 84 | $this->permissionModel->touch(); 85 | 86 | $this->clearCache(); 87 | 88 | return back()->with('status', trans('SimpleMenu::messages.model_updated')); 89 | } 90 | 91 | /** 92 | * Remove Permission from storage. 93 | * 94 | * @param int $id 95 | * 96 | * @return \Illuminate\Http\Response 97 | */ 98 | public function destroy($id, Request $request) 99 | { 100 | $this->permissionModel->destroy($id); 101 | 102 | $this->clearCache(); 103 | 104 | if ($request->expectsJson()) { 105 | return response()->json(['done'=>true]); 106 | } 107 | 108 | return redirect() 109 | ->route($this->crud_prefix . '.permissions.index') 110 | ->with('status', trans('SimpleMenu::messages.model_deleted')); 111 | } 112 | 113 | public function destroyMulti(Request $request) 114 | { 115 | $ids = explode(',', $request->ids); 116 | 117 | $this->permissionModel->destroy($ids); 118 | 119 | return redirect() 120 | ->route($this->crud_prefix . '.permissions.index') 121 | ->with('status', trans('SimpleMenu::messages.models_deleted')); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/Controllers/Admin/RolesController.php: -------------------------------------------------------------------------------- 1 | roleModel->with('permissions')->get(); 21 | 22 | return view("{$this->adminPath}.roles.index", compact('roles')); 23 | } 24 | 25 | /** 26 | * Show the form for creating new Role. 27 | * 28 | * @return \Illuminate\Http\Response 29 | */ 30 | public function create() 31 | { 32 | $permissions = $this->permissionModel->pluck('name', 'name'); 33 | 34 | return view("{$this->adminPath}.roles.create", compact('permissions')); 35 | } 36 | 37 | /** 38 | * Store a newly created Role in storage. 39 | * 40 | * @param \App\Http\Requests\StoreRolesRequest $request 41 | * 42 | * @return \Illuminate\Http\Response 43 | */ 44 | public function store(Request $request) 45 | { 46 | $this->validate($request, [ 47 | 'name' => 'required|unique:roles,name', 48 | ]); 49 | 50 | $role = $this->roleModel->create($request->except('permissions')); 51 | $permissions = $request->permissions ?: []; 52 | 53 | $role->givePermissionTo($permissions); 54 | 55 | return redirect() 56 | ->route($this->crud_prefix . '.roles.index') 57 | ->with('status', trans('SimpleMenu::messages.model_created')); 58 | } 59 | 60 | /** 61 | * Show the form for editing Role. 62 | * 63 | * @param int $id 64 | * 65 | * @return \Illuminate\Http\Response 66 | */ 67 | public function edit($id) 68 | { 69 | $role = $this->roleModel->findOrFail($id); 70 | $permissions = $this->permissionModel->pluck('name', 'name'); 71 | 72 | return view("{$this->adminPath}.roles.edit", compact('role', 'permissions')); 73 | } 74 | 75 | /** 76 | * Update Role in storage. 77 | * 78 | * @param \App\Http\Requests\UpdateRolesRequest $request 79 | * @param int $id 80 | * 81 | * @return \Illuminate\Http\Response 82 | */ 83 | public function update($id, Request $request) 84 | { 85 | $this->validate($request, [ 86 | 'name' => 'required|unique:roles,name,' . $id, 87 | ]); 88 | 89 | $role = $this->roleModel->findOrFail($id); 90 | $permissions = $request->permissions ?: []; 91 | 92 | $role->update($request->except('permissions')); 93 | $role->syncPermissions($permissions); 94 | $role->touch(); 95 | 96 | $this->clearCache(); 97 | 98 | return back()->with('status', trans('SimpleMenu::messages.model_updated')); 99 | } 100 | 101 | /** 102 | * Remove Role from storage. 103 | * 104 | * @param int $id 105 | * 106 | * @return \Illuminate\Http\Response 107 | */ 108 | public function destroy($id, Request $request) 109 | { 110 | $this->roleModel->destroy($id); 111 | 112 | $this->clearCache(); 113 | 114 | if ($request->expectsJson()) { 115 | return response()->json(['done'=>true]); 116 | } 117 | 118 | return redirect() 119 | ->route($this->crud_prefix . '.roles.index') 120 | ->with('status', trans('SimpleMenu::messages.model_deleted')); 121 | } 122 | 123 | public function destroyMulti(Request $request) 124 | { 125 | $ids = explode(',', $request->ids); 126 | 127 | $this->roleModel->destroy($ids); 128 | 129 | return redirect() 130 | ->route($this->crud_prefix . '.roles.index') 131 | ->with('status', trans('SimpleMenu::messages.models_deleted')); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/Controllers/Admin/Traits/MenuOps.php: -------------------------------------------------------------------------------- 1 | cache->tags('sm')->get('menus')->find($id) ?: abort(404); 19 | $pages = collect($menu->pages) 20 | ->sortBy('pivot_order') 21 | ->each(function ($item) { 22 | $item['from'] = 'pages'; 23 | })->values()->all(); 24 | 25 | $allPages = $this->cache->tags('sm')->get('pages')->diff($pages)->each(function ($item) { 26 | $item['from'] = 'allPages'; 27 | }); 28 | 29 | return response()->json(compact('pages', 'allPages')); 30 | } 31 | 32 | /** 33 | * remove page from menu with ajax. 34 | * 35 | * @param [type] $id [description] 36 | * @param Request $request [description] 37 | * 38 | * @return [type] [description] 39 | */ 40 | public function removePage($id, Request $request) 41 | { 42 | // remove page from menu 43 | $menu = $this->menuModel->findOrFail($id); 44 | $menu->pages()->detach($request->page_id); 45 | $menu->touch(); 46 | 47 | // clear page nesting 48 | if (config('simpleMenu.clearRootDescendants')) { 49 | $this->clearSelfAndNests($request->page_id); 50 | } 51 | 52 | return response()->json(['done'=>true]); 53 | } 54 | 55 | /** 56 | * remove nested child with ajax. 57 | * 58 | * @param Request $request [description] 59 | * 60 | * @return [type] [description] 61 | */ 62 | public function removeChild(Request $request) 63 | { 64 | if (config('simpleMenu.clearNestDescendants')) { 65 | $this->clearSelfAndNests($request->child_id); 66 | } else { 67 | $page = $this->findPage($request->child_id); 68 | $page->makeRoot(); 69 | $page->touch(); 70 | } 71 | 72 | return response()->json(['done'=>true]); 73 | } 74 | 75 | /** 76 | * save page hierarchy to db. 77 | * 78 | * @param [type] $list [description] 79 | * 80 | * @return [type] [description] 81 | */ 82 | protected function saveListToDb($list) 83 | { 84 | foreach ($list as $one) { 85 | $child = $this->findPage($one->id); 86 | $parent = $this->findPage($one->parent_id); 87 | 88 | if ($child == $parent) { 89 | return; 90 | } 91 | 92 | $child->makeChildOf($parent); 93 | 94 | $child->touch(); 95 | $parent->touch(); 96 | 97 | if ($one->children) { 98 | $this->saveListToDb($one->children); 99 | } 100 | } 101 | } 102 | 103 | /** 104 | * helpers. 105 | * 106 | * @param mixed $id 107 | * 108 | * @return [type] [description] 109 | */ 110 | protected function clearNests($id) 111 | { 112 | return $this->findPage($id)->destroyDescendants(); 113 | } 114 | 115 | protected function clearSelfAndNests($id) 116 | { 117 | $page = $this->findPage($id); 118 | 119 | return $page->clearSelfAndDescendants(); 120 | } 121 | 122 | protected function findPage($id) 123 | { 124 | return $this->pageModel->findOrFail($id); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/Controllers/Admin/Traits/PageOps.php: -------------------------------------------------------------------------------- 1 | trans('SimpleMenu::messages.regex', ['attribute' => trans('SimpleMenu::messages.action')]), 22 | 'template.required_without' => trans('validation.required_without', [ 23 | 'attribute' => trans('SimpleMenu::messages.template'), 24 | 'values' => trans('SimpleMenu::messages.action'), 25 | ]), 26 | 'route_name.required' => trans('validation.required', ['attribute' => trans('SimpleMenu::messages.route_name')]), 27 | 'url.required' => trans('validation.required', ['attribute' => trans('SimpleMenu::messages.url')]), 28 | 'url.unique' => trans('validation.unique', ['attribute' => trans('SimpleMenu::messages.url')]), 29 | 'title.required' => trans('validation.required', ['attribute' => trans('SimpleMenu::messages.title')]), 30 | 'title.unique' => trans('validation.unique', ['attribute' => trans('SimpleMenu::messages.title')]), 31 | ]; 32 | 33 | // main 34 | $validator = Validator::make($request->all(), [ 35 | 'action' => 'nullable|regex:/@/ius', 36 | 'template' => 'required_without:action', 37 | 'route_name' => 'required|unique:pages,route_name,' . $id ?: '', 38 | 'url.*' => 'unique_translation:pages,url,' . $id ?: '', 39 | 'title.*' => 'unique_translation:pages,title,' . $id ?: '', 40 | ], $customMessages); 41 | 42 | // extra 43 | $validator->after(function ($validator) use ($request, $customMessages) { 44 | // url 45 | if (!array_filter($request->url)) { 46 | $validator->errors()->add('url', $customMessages['url.required']); 47 | } 48 | 49 | // title 50 | if (!array_filter($request->title)) { 51 | $validator->errors()->add('title', $customMessages['title.required']); 52 | } 53 | }); 54 | 55 | if ($validator->fails()) { 56 | throw (new ValidationException($validator)) 57 | ->errorBag('default') 58 | ->redirectTo(url()->previous()); 59 | } 60 | } 61 | 62 | /** 63 | * make sure we only have fields with values. 64 | * 65 | * @param [type] $request [description] 66 | * 67 | * @return [type] [description] 68 | */ 69 | protected function cleanEmptyTranslations($request) 70 | { 71 | $result = $request->except(['roles', 'permissions', 'menus', 'cover', 'controllerFile']); 72 | 73 | foreach ($result as $k => $v) { 74 | if (is_array($v)) { 75 | $result[$k] = array_filter($v) ?: null; 76 | } 77 | } 78 | 79 | return $result; 80 | } 81 | 82 | /** 83 | * save or get controller content. 84 | * 85 | * @param [type] $action [description] 86 | * @param [type] $type [description] 87 | * @param [type] $data [description] 88 | * 89 | * @return [type] [description] 90 | */ 91 | protected function actionFileContent($action, $type, $data = null) 92 | { 93 | $class = substr($action, 0, strpos($action, '@')); 94 | $file = (new \ReflectionClass($class))->getFileName(); 95 | 96 | if ($type == 'get') { 97 | return file_get_contents($file); 98 | } 99 | 100 | return file_put_contents($file, $data); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/Controllers/Admin/Traits/Paginate.php: -------------------------------------------------------------------------------- 1 | forPage($page, $perPage)->values(), 22 | $items->count(), 23 | $perPage, 24 | $page, 25 | [ 26 | 'path' => Paginator::resolveCurrentPath(), 27 | 'pageName' => $pageName, 28 | ] 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Controllers/Admin/Traits/RolePermOps.php: -------------------------------------------------------------------------------- 1 | cache->tags('sm')->flush(); 10 | 11 | event('sm-perms.cleared'); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Controllers/Admin/Traits/UserPageOps.php: -------------------------------------------------------------------------------- 1 | pluck('name')->sort()->values()->all(); 24 | $new = collect($input)->sort()->values()->all(); 25 | 26 | return $self === $new; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Controllers/Admin/UsersController.php: -------------------------------------------------------------------------------- 1 | cache->get('sm-users'); 21 | 22 | return view("{$this->adminPath}.users.index", compact('users')); 23 | } 24 | 25 | /** 26 | * Show the form for creating new User. 27 | * 28 | * @return \Illuminate\Http\Response 29 | */ 30 | public function create() 31 | { 32 | $roles = $this->roleModel->pluck('name', 'name'); 33 | $permissions = $this->permissionModel->pluck('name', 'name'); 34 | 35 | return view("{$this->adminPath}.users.create", compact('roles', 'permissions')); 36 | } 37 | 38 | /** 39 | * Store a newly created User in storage. 40 | * 41 | * @param \App\Http\Requests\StoreUsersRequest $request 42 | * 43 | * @return \Illuminate\Http\Response 44 | */ 45 | public function store(Request $request) 46 | { 47 | $this->validate($request, [ 48 | 'name' => 'required', 49 | 'email' => 'required|email|unique:users,email', 50 | 'password' => 'required', 51 | ]); 52 | 53 | $img = $this->getImage($request->avatar); 54 | $user = $this->userModel->create(array_merge(['avatar'=>$img], $request->except(['roles', 'permissions']))); 55 | $roles = $request->roles ?: []; 56 | $permissions = $request->permissions ?: []; 57 | 58 | $user->assignRole($roles); 59 | $user->givePermissionTo($permissions); 60 | 61 | return redirect() 62 | ->route($this->crud_prefix . '.users.index') 63 | ->with('status', trans('SimpleMenu::messages.model_created')); 64 | } 65 | 66 | /** 67 | * Show the form for editing User. 68 | * 69 | * @param int $id 70 | * 71 | * @return \Illuminate\Http\Response 72 | */ 73 | public function edit($id) 74 | { 75 | $user = $this->userModel->findOrFail($id); 76 | $roles = $this->roleModel->pluck('name', 'name'); 77 | $permissions = $this->permissionModel->pluck('name', 'name'); 78 | 79 | return view("{$this->adminPath}.users.edit", compact('user', 'roles', 'permissions')); 80 | } 81 | 82 | /** 83 | * Update User in storage. 84 | * 85 | * @param \App\Http\Requests\UpdateUsersRequest $request 86 | * @param int $id 87 | * 88 | * @return \Illuminate\Http\Response 89 | */ 90 | public function update($id, Request $request) 91 | { 92 | $this->validate($request, [ 93 | 'name' => 'required', 94 | 'email' => 'required|email|unique:users,email,' . $id, 95 | ]); 96 | 97 | $user = $this->userModel->findOrFail($id); 98 | $img = $this->getImage($request->avatar); 99 | $roles = $request->roles; 100 | $permissions = $request->permissions; 101 | 102 | $user->update(array_merge(['avatar'=>$img], $request->except(['roles', 'permissions']))); 103 | 104 | if (!$this->checkBeforeAssign($user->roles, $roles)) { 105 | $user->syncRoles($roles ?: []); 106 | } 107 | 108 | if (!$this->checkBeforeAssign($user->permissions, $permissions)) { 109 | $user->syncPermissions($permissions ?: []); 110 | } 111 | 112 | $user->touch(); 113 | 114 | return back()->with('status', trans('SimpleMenu::messages.model_updated')); 115 | } 116 | 117 | /** 118 | * Remove User from storage. 119 | * 120 | * @param int $id 121 | * 122 | * @return \Illuminate\Http\Response 123 | */ 124 | public function destroy($id, Request $request) 125 | { 126 | // dont remove self 127 | // if (auth()->user()->id == $id) { 128 | // abort(403); 129 | // } 130 | 131 | $this->userModel->destroy($id); 132 | 133 | if ($request->expectsJson()) { 134 | return response()->json(['done'=>true]); 135 | } 136 | 137 | return redirect() 138 | ->route($this->crud_prefix . '.users.index') 139 | ->with('status', trans('SimpleMenu::messages.model_deleted')); 140 | } 141 | 142 | public function destroyMulti(Request $request) 143 | { 144 | $ids = explode(',', $request->ids); 145 | 146 | $this->userModel->destroy($ids); 147 | 148 | return redirect() 149 | ->route($this->crud_prefix . '.users.index') 150 | ->with('status', trans('SimpleMenu::messages.models_deleted')); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/Controllers/BaseController.php: -------------------------------------------------------------------------------- 1 | cache = app('cache'); 33 | $this->adminPath = 'SimpleMenu::admin'; 34 | $this->crud_prefix = $sm_config['crud_prefix']; 35 | 36 | $this->userModel = app(Arr::get($sm_config, 'models.user')); 37 | $this->pageModel = app(Arr::get($sm_config, 'models.page')); 38 | $this->menuModel = app(Arr::get($sm_config, 'models.menu')); 39 | $this->roleModel = app(Arr::get($sp_config, 'models.role')); 40 | $this->permissionModel = app(Arr::get($sp_config, 'models.permission')); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Controllers/DummyController.php: -------------------------------------------------------------------------------- 1 | currentRouteName())); 12 | 13 | return view($template, compact('title', 'body', 'desc', 'meta', 'cover', 'breadCrumb')); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Facade/SimpleMenu.php: -------------------------------------------------------------------------------- 1 | guest()) { 26 | throw UnauthorizedException::notLoggedIn(); 27 | } 28 | 29 | if (!$request->user()->load('permissions')->hasAnyPermission($permissions)) { 30 | throw UnauthorizedException::forPermissions($permissions); 31 | } 32 | 33 | return $next($request); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Middleware/RoleMiddleware.php: -------------------------------------------------------------------------------- 1 | guest()) { 26 | throw UnauthorizedException::notLoggedIn(); 27 | } 28 | 29 | if (!$request->user()->load('roles')->hasAnyRole($roles)) { 30 | throw UnauthorizedException::forRoles($roles); 31 | } 32 | 33 | return $next($request); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Models/Menu.php: -------------------------------------------------------------------------------- 1 | belongsToMany(config('simpleMenu.models.page'))->withPivot('order'); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Models/Page.php: -------------------------------------------------------------------------------- 1 | belongsToMany(config('simpleMenu.models.menu')); 32 | } 33 | 34 | protected function getCrntLocale() 35 | { 36 | return LaravelLocalization::getCurrentLocale(); 37 | } 38 | 39 | /** 40 | * override HasTranslations\getAttributeValue(). 41 | * 42 | * @param [type] $key [description] 43 | * 44 | * @return [type] [description] 45 | */ 46 | public function getAttributeValue($key) 47 | { 48 | if (!$this->isTranslatableAttribute($key)) { 49 | return parent::getAttributeValue($key); 50 | } 51 | 52 | return $this->getTranslationWithoutFallback($key, $this->getCrntLocale()); 53 | } 54 | 55 | /** 56 | * Menus. 57 | * 58 | * @param [type] $menus [description] 59 | * 60 | * @return [type] [description] 61 | */ 62 | public function assignToMenus($menus) 63 | { 64 | $this->menus()->attach($menus); 65 | $this->touch(); 66 | } 67 | 68 | public function syncMenus($menus) 69 | { 70 | $this->menus()->sync($menus); 71 | $this->touch(); 72 | } 73 | 74 | /** 75 | * Nesting. 76 | * 77 | * @param mixed $columns 78 | * 79 | * @return [type] [description] 80 | */ 81 | public function getAncestors($columns = ['*']) 82 | { 83 | return app('cache')->tags('sm')->rememberForever($this->getCrntLocale() . "-{$this->route_name}_ancestors", function () use ($columns) { 84 | return $this->ancestors()->get($columns); 85 | }); 86 | } 87 | 88 | public function getNestsAttribute() 89 | { 90 | return app('cache')->tags('sm')->rememberForever($this->getCrntLocale() . "-{$this->route_name}_nests", function () { 91 | return Arr::flatten(current($this->getDescendants()->toHierarchy())); 92 | }); 93 | } 94 | 95 | /** 96 | * clear Nesting. 97 | * 98 | * @return [type] [description] 99 | */ 100 | public function destroyDescendants() 101 | { 102 | if (config('simpleMenu.deletePageAndNests')) { 103 | parent::destroyDescendants(); 104 | } else { 105 | $this->clearNests(); 106 | } 107 | } 108 | 109 | public function clearSelfAndDescendants() 110 | { 111 | $this->makeRoot(); 112 | $this->clearNests(); 113 | } 114 | 115 | protected function clearNests() 116 | { 117 | $lft = $this->getLeft(); 118 | $rgt = $this->getRight(); 119 | 120 | if (is_null($lft) || is_null($rgt)) { 121 | return; 122 | } 123 | 124 | $lftCol = $this->getLeftColumnName(); 125 | $rgtCol = $this->getRightColumnName(); 126 | 127 | $this->where($lftCol, '>', $lft)->where($rgtCol, '<', $rgt)->each(function ($one) { 128 | $one->makeRoot(); 129 | }); 130 | 131 | $this->touch(); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/Models/Traits/SMUsers.php: -------------------------------------------------------------------------------- 1 | password; 16 | } 17 | 18 | $this->attributes['password'] = app('hash')->needsRehash($value) 19 | ? app('hash')->make($value) 20 | : $value; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Observers/BaseObserver.php: -------------------------------------------------------------------------------- 1 | cache = app('cache'); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Observers/MenuObserver.php: -------------------------------------------------------------------------------- 1 | cleanData(); 13 | } 14 | 15 | /** 16 | * Listen to the Menu deleted event. 17 | */ 18 | public function deleted() 19 | { 20 | return $this->cleanData(); 21 | } 22 | 23 | /** 24 | * helpers. 25 | * 26 | * @return [type] [description] 27 | */ 28 | protected function cleanData() 29 | { 30 | $this->cache->tags('sm')->flush(); 31 | 32 | event('sm-menus.cleared'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Observers/PageObserver.php: -------------------------------------------------------------------------------- 1 | cleanData($page); 15 | } 16 | 17 | /** 18 | * Listen to the Page deleted event. 19 | */ 20 | public function deleted(Page $page) 21 | { 22 | return $this->cleanData($page); 23 | } 24 | 25 | /** 26 | * helpers. 27 | * 28 | * @param [type] $page [description] 29 | * 30 | * @return [type] [description] 31 | */ 32 | protected function cleanData($page) 33 | { 34 | $route_name = $page->route_name; 35 | 36 | // clear page session 37 | session()->forget($route_name); 38 | 39 | // remove the route file 40 | app('files')->delete(config('simpleMenu.routeListPath')); 41 | 42 | // clear all cache 43 | $this->cache->tags('sm')->flush(); 44 | 45 | event('sm-pages.cleared'); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Observers/UserObserver.php: -------------------------------------------------------------------------------- 1 | cleanData(); 13 | } 14 | 15 | /** 16 | * Listen to the User deleting event. 17 | */ 18 | public function deleted() 19 | { 20 | return $this->cleanData(); 21 | } 22 | 23 | /** 24 | * helpers. 25 | * 26 | * @return [type] [description] 27 | */ 28 | protected function cleanData() 29 | { 30 | $this->cache->forget('sm-users'); 31 | 32 | event('sm-users.cleared'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/SimpleMenu.php: -------------------------------------------------------------------------------- 1 | cache = app('cache'); 27 | $this->listFileDir = config('simpleMenu.routeListPath'); 28 | $this->localeCodes = array_keys(LaravelLocalization::getSupportedLocales()); 29 | 30 | if ($this->listFileDir) { 31 | static::create_LFD($this->listFileDir); 32 | 33 | if (!app()->runningInConsole()) { 34 | // create caches 35 | $this->createCaches(); 36 | 37 | // create routes 38 | $this->createRoutes(); 39 | 40 | // create menu 41 | $this->createMenus(); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/SimpleMenuServiceProvider.php: -------------------------------------------------------------------------------- 1 | packagePublish(); 24 | $this->observers(); 25 | $this->macros(); 26 | $this->viewComp(); 27 | $this->command(); 28 | $this->app['simplemenu']; 29 | } 30 | 31 | protected function packagePublish() 32 | { 33 | // config 34 | $this->publishes([ 35 | __DIR__ . '/config' => config_path(), 36 | ], 'config'); 37 | 38 | // migrations 39 | $this->publishes([ 40 | __DIR__ . '/database/migrations' => database_path('migrations'), 41 | ], 'migrations'); 42 | 43 | // seeds 44 | $this->publishes([ 45 | __DIR__ . '/database/seeds' => database_path('seeds'), 46 | ], 'seeds'); 47 | 48 | // resources 49 | $this->publishes([ 50 | __DIR__ . '/resources/assets' => resource_path('assets/vendor/SimpleMenu'), 51 | ], 'assets'); 52 | 53 | // trans 54 | $this->loadTranslationsFrom(__DIR__ . '/resources/lang', 'SimpleMenu'); 55 | $this->publishes([ 56 | __DIR__ . '/resources/lang' => resource_path('lang/vendor/SimpleMenu'), 57 | ], 'trans'); 58 | 59 | // views 60 | $this->loadViewsFrom(__DIR__ . '/resources/views', 'SimpleMenu'); 61 | $this->publishes([ 62 | __DIR__ . '/resources/views' => resource_path('views/vendor/SimpleMenu'), 63 | __DIR__ . '/resources/pagination' => resource_path('views/vendor/pagination'), 64 | ], 'views'); 65 | } 66 | 67 | /** 68 | * model events observers. 69 | * 70 | * @return [type] [description] 71 | */ 72 | protected function observers() 73 | { 74 | $models = $this->app['config']->get('simpleMenu.models'); 75 | 76 | if ($models) { 77 | $this->app->make($models['page'])->observe(PageObserver::class); 78 | $this->app->make($models['menu'])->observe(MenuObserver::class); 79 | $this->app->make($models['user'])->observe(UserObserver::class); 80 | } 81 | } 82 | 83 | /** 84 | * package macros. 85 | * 86 | * @return [type] [description] 87 | */ 88 | protected function macros() 89 | { 90 | // same as "Route::is()" but better 91 | $this->app['url']->macro('is', function ($route_name, $params = null) { 92 | return $params 93 | ? request()->url() == route($route_name, $params) 94 | : request()->url() == route($route_name); 95 | }); 96 | 97 | $this->app['url']->macro('has', function ($needle) { 98 | return Str::contains($this->current(), $needle); 99 | }); 100 | } 101 | 102 | /** 103 | * share var across views. 104 | * 105 | * @return [type] [description] 106 | */ 107 | protected function viewComp() 108 | { 109 | view()->composer('SimpleMenu::admin.*', function ($view) { 110 | $view->with([ 111 | 'crud_prefix' => $this->app['config']->get('simpleMenu.crud_prefix'), 112 | ]); 113 | }); 114 | } 115 | 116 | /** 117 | * package commands. 118 | * 119 | * @return [type] [description] 120 | */ 121 | protected function command() 122 | { 123 | $this->commands([ 124 | PackageSetup::class, 125 | ]); 126 | } 127 | 128 | /** 129 | * Register any package services. 130 | */ 131 | public function register() 132 | { 133 | $this->app->singleton('simplemenu', function () { 134 | return new SimpleMenu(); 135 | }); 136 | 137 | $this->regPSP(); 138 | $this->regPMW(); 139 | } 140 | 141 | /** 142 | * packages service providers. 143 | * 144 | * @return [type] [description] 145 | */ 146 | protected function regPSP() 147 | { 148 | $packagesSP = [ 149 | \Baum\Providers\BaumServiceProvider::class, 150 | \ctf0\PackageChangeLog\PackageChangeLogServiceProvider::class, 151 | ]; 152 | 153 | foreach ($packagesSP as $one) { 154 | $this->app->register($one); 155 | } 156 | } 157 | 158 | /** 159 | * packages middlewares. 160 | * 161 | * @return [type] [description] 162 | */ 163 | protected function regPMW() 164 | { 165 | $this->app['router']->aliasMiddleware('perm', PermissionMiddleware::class); 166 | $this->app['router']->aliasMiddleware('role', RoleMiddleware::class); 167 | $this->app['router']->aliasMiddleware('localizationRedirect', LaravelLocalizationRedirectFilter::class); 168 | $this->app['router']->aliasMiddleware('localeSessionRedirect', LocaleSessionRedirect::class); 169 | } 170 | } -------------------------------------------------------------------------------- /src/Traits/Menus.php: -------------------------------------------------------------------------------- 1 | cache->tags('sm')->get('menus')->pluck('name')->each(function ($name) { 15 | $this->viewComp($name); 16 | }); 17 | } 18 | 19 | /** 20 | * [viewComp description]. 21 | * 22 | * @param [type] $name [description] 23 | * 24 | * @return [type] [description] 25 | */ 26 | public function viewComp($name) 27 | { 28 | $viewFile = view()->exists("SimpleMenu::menu.{$name}") 29 | ? "SimpleMenu::menu.{$name}" 30 | : 'SimpleMenu::menu.example'; 31 | 32 | return view()->composer($viewFile, function ($view) use ($name) { 33 | $view->with([ 34 | 'PAGES' => $this->query($name), 35 | 'menuName' => $name, 36 | ]); 37 | }); 38 | } 39 | 40 | /** 41 | * menu logic. 42 | * 43 | * @param [type] $name [description] 44 | * @param null|mixed $nest 45 | * 46 | * @return [type] [description] 47 | */ 48 | public function query($name) 49 | { 50 | $locale = $this->getCrntLocale(); 51 | 52 | if ($this->cache->tags('sm')->get('menus')->isNotEmpty()) { 53 | return $this->cache->tags('sm')->rememberForever("{$name}Menu-{$locale}Pages", function () use ($name) { 54 | return collect($this->cache->tags('sm')->get('menus')->where('name', $name)->first()->pages) 55 | ->sortBy('pivot_order') 56 | ->filter(function ($item) { 57 | return $item->url != ''; 58 | }); 59 | }); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Traits/Navigation.php: -------------------------------------------------------------------------------- 1 | currentRouteName(); 23 | 24 | // redir to '/' if the first item in "bc" is in diff locale 25 | $bc = $this->getRouteData($name)['breadCrumb']; 26 | 27 | if (isset($bc) && count($bc) && !$this->searchForRoute($bc->pluck('route_name')->first(), $code)) { 28 | return LaravelLocalization::getLocalizedURL($code, url('/'), [], true); 29 | } 30 | 31 | // routeName is not saved in the db (ex.php artisan make:auth) 32 | // or only url 33 | $routesListFile = include $this->listFileDir; 34 | 35 | if (is_null($name) || !isset($routesListFile[$name])) { 36 | return LaravelLocalization::getLocalizedURL($code, null, [], true); 37 | } 38 | 39 | $url = $this->routeLink($name, $code); 40 | 41 | // if we have a saved params 42 | if (session()->has($name)) { 43 | $params = session()->get($name); 44 | 45 | return LaravelLocalization::getLocalizedURL($code, url($this->getParams($url, $params)), [], true); 46 | } 47 | 48 | // no params 49 | return LaravelLocalization::getLocalizedURL($code, url($this->rmvUnUsedParams($url)), [], true); 50 | } 51 | 52 | /** 53 | * resolve route & params for links. 54 | * 55 | * @param [type] $crntRouteName [description] 56 | * @param array|null $params [description] 57 | * 58 | * @return [type] [description] 59 | */ 60 | public function getRoute($crntRouteName, $params = null) 61 | { 62 | // where route is available under one locale but not the other 63 | if (!app('router')->has($crntRouteName)) { 64 | return; 65 | } 66 | 67 | $locale = $this->getCrntLocale(); 68 | $url = $this->routeLink($crntRouteName, $locale); 69 | $forceDefaultLocation = LaravelLocalization::hideDefaultLocaleInURL() && $locale == LaravelLocalization::getDefaultLocale() ? false : true; 70 | 71 | // resolve route params 72 | if ($params) { 73 | foreach ($params as $key => $value) { 74 | if ($crntRouteName == $key) { 75 | session([$key => $value]); 76 | 77 | // fix link not being 'is-active'when"hideDefaultLocaleInURL => true" 78 | $finalUrl = LaravelLocalization::getLocalizedURL($locale, url($this->getParams($url, $value)), [], $forceDefaultLocation); 79 | $this->urlRoute = $finalUrl; 80 | 81 | return $finalUrl; 82 | } 83 | } 84 | } 85 | 86 | $this->urlRoute = route($crntRouteName); 87 | 88 | return $this->urlRoute; 89 | } 90 | 91 | /** 92 | * helpers. 93 | * 94 | * @return [type] [description] 95 | */ 96 | public function routeUrl() 97 | { 98 | return $this->urlRoute; 99 | } 100 | 101 | public function isActiveRoute() 102 | { 103 | return request()->url() == $this->urlRoute; 104 | } 105 | 106 | public function getRouteData($name) 107 | { 108 | return $this->cache->tags('sm')->get($this->getCrntLocale() . "-$name"); 109 | } 110 | 111 | public function getBC() 112 | { 113 | $name = app('router')->currentRouteName(); 114 | $bc = $this->getRouteData($name)['breadCrumb']; 115 | 116 | if (isset($bc) && count($bc)) { 117 | return $bc; 118 | } 119 | } 120 | 121 | /** 122 | * resolve route url. 123 | * 124 | * @param [type] $name [description] 125 | * @param [type] $code [description] 126 | * 127 | * @return [type] [description] 128 | */ 129 | protected function routeLink($name, $code) 130 | { 131 | $searchCode = $this->searchForRoute($name, $code); 132 | 133 | // if notFound, then either redir to home or show 404 134 | if (!$searchCode) { 135 | switch (config('simpleMenu.unFoundLocalizedRoute')) { 136 | case 'error': 137 | return '404'; 138 | break; 139 | default: 140 | return '/'; 141 | } 142 | } 143 | 144 | return $searchCode; 145 | } 146 | 147 | protected function searchForRoute($name, $code) 148 | { 149 | $routesListFile = include $this->listFileDir; 150 | 151 | // check if we have a link according to that "routeName & code" 152 | return Arr::get($routesListFile, "$name.$code", false); 153 | } 154 | 155 | /** 156 | * render menu. 157 | * 158 | * @param [type] $pages [description] 159 | * @param [type] $classes [description] 160 | * @param [type] $params [description] 161 | * @param [type] $url [description] 162 | * 163 | * @return [type] [description] 164 | */ 165 | public function render($pages, $classes = null, $params = null) 166 | { 167 | $url = request()->url(); 168 | 169 | switch ($classes) { 170 | case 'config': 171 | $ul = config('simpleMenu.listClasses.ul'); 172 | $li = config('simpleMenu.listClasses.li'); 173 | $a = config('simpleMenu.listClasses.a'); 174 | break; 175 | default: 176 | $ul = $classes['ul']; 177 | $li = $classes['li']; 178 | $a = $classes['a']; 179 | break; 180 | } 181 | 182 | return $this->getHtml($pages, $ul, $li, $a, $params, $url); 183 | } 184 | 185 | /** 186 | * generate menu html. 187 | * 188 | * @param [type] $pages [description] 189 | * @param [type] $params [description] 190 | * @param [type] $url [description] 191 | * @param mixed $ul_ClassName 192 | * @param mixed $li_ClassName 193 | * @param mixed $a_ClassName 194 | * 195 | * @return [type] [description] 196 | */ 197 | protected function getHtml($pages, $ul_ClassName, $li_ClassName, $a_ClassName, $params, $url) 198 | { 199 | $html = ''; 200 | $html .= "'; 221 | 222 | return $html; 223 | } 224 | 225 | /** 226 | * resolve params. 227 | * 228 | * @param [type] $url [description] 229 | * @param [type] $params [description] 230 | * 231 | * @return [type] [description] 232 | */ 233 | protected function getParams($url, $params) 234 | { 235 | foreach ($params as $key => $value) { 236 | $url = preg_replace('/\{' . preg_quote($key) . '(\?)?\}/', $value, $url); 237 | } 238 | 239 | return $this->rmvUnUsedParams($url); 240 | } 241 | 242 | /** 243 | * remove optional params. so we dont get badly formated url. 244 | * 245 | * @param [type] $url [description] 246 | * 247 | * @return [type] [description] 248 | */ 249 | protected function rmvUnUsedParams($url) 250 | { 251 | return preg_replace('/\{.*\}/', '', $url); 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /src/Traits/Ops.php: -------------------------------------------------------------------------------- 1 | localeCodes; 15 | } 16 | 17 | protected function getCrntLocale() 18 | { 19 | return LaravelLocalization::getCurrentLocale(); 20 | } 21 | 22 | /** 23 | * cacheing. 24 | * 25 | * @return [type] [description] 26 | */ 27 | protected function createCaches() 28 | { 29 | $models = config('simpleMenu.models'); 30 | 31 | $this->cache->tags('sm')->rememberForever('menus', function () use ($models) { 32 | return app($models['menu'])->with('pages')->get(); 33 | }); 34 | 35 | $this->cache->tags('sm')->rememberForever('pages', function () use ($models) { 36 | return app($models['page'])->withTrashed()->get(); 37 | }); 38 | 39 | $this->cache->rememberForever('sm-users', function () use ($models) { 40 | return app($models['user'])->with(['roles', 'permissions'])->get(); 41 | }); 42 | } 43 | 44 | /** 45 | * route list dir. 46 | * 47 | * @param mixed $dir 48 | */ 49 | protected static function create_LFD($dir) 50 | { 51 | $files = app('files'); 52 | 53 | if ($files->exists(config_path('simpleMenu.php'))) { 54 | $dir_name = dirname($dir); 55 | 56 | if (!$files->exists($dir_name)) { 57 | return $files->makeDirectory($dir_name, 0755, true); 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Traits/PackageRoutes.php: -------------------------------------------------------------------------------- 1 | group([ 18 | 'prefix'=> $prefix, 19 | ], function () use ($prefix, $controllers) { 20 | /* Home */ 21 | if (isset($controllers['admin'])) { 22 | app('router')->get('/', $controllers['admin'])->name($prefix); 23 | } 24 | 25 | /* Everything Else */ 26 | app('router')->group([ 27 | 'as'=> "$prefix.", 28 | ], function () use ($controllers) { 29 | /* Roles */ 30 | app('router')->resource('roles', $controllers['roles'], ['except'=>'show']); 31 | app('router')->post('roles/remove-multi', $controllers['roles'] . '@destroyMulti')->name('roles.destroy_multi'); 32 | 33 | /* Perms */ 34 | app('router')->resource('permissions', $controllers['permissions'], ['except'=>'show']); 35 | app('router')->post('permissions/remove-multi', $controllers['permissions'] . '@destroyMulti')->name('permissions.destroy_multi'); 36 | 37 | /* Menus */ 38 | app('router')->post('menus/removechild', $controllers['menus'] . '@removeChild')->name('menus.removeChild'); 39 | app('router')->post('menus/removepage/{id}', $controllers['menus'] . '@removePage')->name('menus.removePage'); 40 | app('router')->get('menus/getmenupages/{id}', $controllers['menus'] . '@getMenuPages')->name('menus.getMenuPages'); 41 | app('router')->resource('menus', $controllers['menus'], ['except'=>'show']); 42 | app('router')->post('menus/remove-multi', $controllers['menus'] . '@destroyMulti')->name('menus.destroy_multi'); 43 | 44 | /* Users */ 45 | app('router')->resource('users', $controllers['users'], ['except'=>'show']); 46 | app('router')->post('users/remove-multi', $controllers['users'] . '@destroyMulti')->name('users.destroy_multi'); 47 | 48 | /* Pages */ 49 | app('router')->resource('pages', $controllers['pages'], ['except'=>'show']); 50 | app('router')->post('pages/remove-multi', $controllers['pages'] . '@destroyMulti')->name('pages.destroy_multi'); 51 | app('router')->put('pages/{id}/restore', $controllers['pages'] . '@restore')->name('pages.restore'); 52 | app('router')->delete('pages/{id}/remove-force', $controllers['pages'] . '@forceDelete')->name('pages.destroy_force'); 53 | }); 54 | }); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Traits/Routes.php: -------------------------------------------------------------------------------- 1 | group([ 16 | 'prefix' => LaravelLocalization::setLocale(), 17 | 'middleware' => [ 18 | 'web', 19 | 'localeSessionRedirect', 20 | 'localizationRedirect', 21 | ], 22 | ], function () { 23 | $this->utilCheck(); 24 | }); 25 | } 26 | 27 | protected function utilCheck() 28 | { 29 | if (!app('files')->exists($this->listFileDir)) { 30 | $this->listFileFound = false; 31 | 32 | $this->utilLoop(); 33 | $this->saveRoutesListToFile($this->allRoutes); 34 | } else { 35 | $this->utilLoop(); 36 | } 37 | } 38 | 39 | /** 40 | * runs everytime you change the current local 41 | * so routes links gets dynamically changed without causing issues. 42 | * 43 | * @return [type] [description] 44 | */ 45 | protected function utilLoop() 46 | { 47 | foreach ($this->cache->tags('sm')->get('pages') as $page) { 48 | // make route 49 | $this->routeGen($page); 50 | 51 | // create route list 52 | if (!$this->listFileFound) { 53 | $this->createRoutesList($page); 54 | } 55 | } 56 | } 57 | 58 | protected function routeGen($page) 59 | { 60 | if ($this->escapeEmptyRoute($page->url)) { 61 | return; 62 | } 63 | 64 | // route data 65 | $url = $page->url; 66 | $action = $page->action; 67 | $prefix = $page->prefix; 68 | $routeName = $page->route_name; 69 | 70 | // page data 71 | $title = $page->title; 72 | $body = $page->body; 73 | $desc = $page->desc; 74 | $meta = $page->meta; 75 | $cover = $page->cover; 76 | $template = $page->template; 77 | $breadCrumb = $page->getAncestors(); 78 | 79 | // middlewares 80 | $middlewares = is_null($page->middlewares) ? null : preg_split('/[\s,]+/', $page->middlewares); 81 | $roles = empty($page->roles->pluck('name')->toArray()) ? null : 'role:' . implode(',', $page->roles->pluck('name')->toArray()); 82 | $permissions = empty($page->permissions->pluck('name')->toArray()) ? null : 'perm:' . implode(',', $page->permissions->pluck('name')->toArray()); 83 | 84 | // cache the page so we can pass the page params to the controller@method 85 | $compact = compact('template', 'title', 'body', 'desc', 'meta', 'cover', 'breadCrumb', 'middlewares', 'roles', 'permissions'); 86 | 87 | $this->cache->tags('sm')->rememberForever($this->getCrntLocale() . "-$routeName", function () use ($compact) { 88 | return $compact; 89 | }); 90 | 91 | $route = $this->getRouteUrl($url, $prefix); 92 | 93 | $uses = $action 94 | ? starts_with($action, '\\') ? $action : "\\$action" 95 | : '\ctf0\SimpleMenu\Controllers\DummyController@handle'; 96 | 97 | $mds = array_filter(Arr::flatten([$middlewares, $roles, $permissions])); 98 | 99 | app('router')->get($route) 100 | ->uses($uses) 101 | ->name($routeName) 102 | ->middleware($mds); 103 | } 104 | 105 | protected function createRoutesList($page) 106 | { 107 | $routeName = $page->route_name; 108 | 109 | foreach ($this->AppLocales() as $code) { 110 | $url = $page->getTranslationWithoutFallback('url', $code); 111 | $prefix = $page->getTranslationWithoutFallback('prefix', $code); 112 | 113 | if ($this->escapeEmptyRoute($url)) { 114 | continue; 115 | } 116 | 117 | $route = $this->getRouteUrl($url, $prefix); 118 | 119 | $this->allRoutes[$routeName][$code] = $route; 120 | } 121 | } 122 | 123 | protected function escapeEmptyRoute($url) 124 | { 125 | return empty($url); 126 | } 127 | 128 | protected function getRouteUrl($url, $prefix) 129 | { 130 | if (empty($prefix)) { 131 | $clear = $url; 132 | } else { 133 | $clear = "$prefix/$url"; 134 | } 135 | 136 | return $this->clearExtraSlash($clear); 137 | } 138 | 139 | protected function saveRoutesListToFile($routes) 140 | { 141 | $data = "clearExtraSlash($data); 143 | 144 | // array(...) to [...] 145 | $data = str_replace('array (', '[', $data); 146 | $data = str_replace(')', ']', $data); 147 | $data = preg_replace('/=>\s+\[/', '=> [', $data); 148 | 149 | return app('files')->put($this->listFileDir, $data); 150 | } 151 | 152 | protected function clearExtraSlash($url) 153 | { 154 | return preg_replace('/\/+/', '/', $url); 155 | } 156 | } -------------------------------------------------------------------------------- /src/config/simpleMenu.php: -------------------------------------------------------------------------------- 1 | [ 8 | 'ul' => 'menu-list', 9 | 'li' => 'list-item', 10 | 'a' => 'is-active', 11 | ], 12 | 13 | /* 14 | * the path where we will save the routes list 15 | */ 16 | 'routeListPath' => storage_path('logs/simpleMenu.php'), 17 | 18 | /* 19 | * dynamic pages controller namespace 20 | */ 21 | 'pagesControllerNS' => 'App\Http\Controllers', 22 | 23 | /* 24 | * where to redirect when a route is available in one locale "en" but not in another "fr" ? 25 | * 26 | * add 27 | * 'root' = '/' 28 | * 'error' = '404' 29 | */ 30 | 'unFoundLocalizedRoute' => 'root', 31 | 32 | /* 33 | * package models 34 | */ 35 | 'models'=> [ 36 | 'user' => App\User::class, 37 | 'page' => \ctf0\SimpleMenu\Models\Page::class, 38 | 'menu' => \ctf0\SimpleMenu\Models\Menu::class, 39 | ], 40 | 41 | /* 42 | * when adding a page which is a nest of another to a menu, ex. 43 | * 44 | * root 45 | * | child 1 46 | * | child 2 "add this along with its children to another menu" 47 | * | child 3 48 | * 49 | * do you want to clear its parent and make it a root ? 50 | * 51 | * note that this will cause issues for breadcumb as to "what to show" and "what to hide" 52 | * if set to "false" 53 | */ 54 | 'clearPartialyNestedParent'=> true, 55 | 56 | /* 57 | * when removing a root page from a menu, ex. 58 | * 59 | * root "remove" 60 | * | child 1 61 | * | child 2 62 | * | child 3 63 | * 64 | * do you want clear all of its 'Descendants' ? 65 | */ 66 | 'clearRootDescendants' => false, 67 | 68 | /* 69 | * when removing a nest from a list, ex. 70 | * 71 | * root 72 | * | child 1 73 | * | child 2 "remove" 74 | * | child 3 75 | * 76 | * do you want to reset its hierarchy ? 77 | */ 78 | 'clearNestDescendants'=> false, 79 | 80 | /* 81 | * when deleting a page "from the db", ex. 82 | * 83 | * page "delete/destroy" 84 | * | nested child 1 85 | * | nested child 2 86 | * | nested child 3 87 | * 88 | * do you also want to delete all of its children ? 89 | */ 90 | 'deletePageAndNests' => false, 91 | 92 | /* 93 | * package routes url & route name prefix ex. 94 | * url = 'admin/pages' 95 | * route name = 'admin.pages.*' 96 | */ 97 | 'crud_prefix' => 'admin', 98 | 99 | /* 100 | * package controllers 101 | * 102 | * all the controllers are https://laravel.com/docs/5.5/controllers#resource-controllers 103 | * except admin which is using a single method "index" to return the admin page 104 | * 105 | * if you need to change anything, just create new controller 106 | * and extend from the below original 107 | * ex. "class ExampleController extends PagesController" 108 | * 109 | * for admin, the route name will be == "crud_prefix" 110 | */ 111 | 'controllers'=> [ 112 | 'admin' => '\ctf0\SimpleMenu\Controllers\Admin\AdminController@index', 113 | 'users' => '\ctf0\SimpleMenu\Controllers\Admin\UsersController', 114 | 'pages' => '\ctf0\SimpleMenu\Controllers\Admin\PagesController', 115 | 'roles' => '\ctf0\SimpleMenu\Controllers\Admin\RolesController', 116 | 'permissions' => '\ctf0\SimpleMenu\Controllers\Admin\PermissionsController', 117 | 'menus' => '\ctf0\SimpleMenu\Controllers\Admin\MenusController', 118 | ], 119 | ]; 120 | -------------------------------------------------------------------------------- /src/database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 16 | $table->string('name'); 17 | $table->string('email')->unique(); 18 | $table->string('password'); 19 | $table->string('avatar')->nullable(); 20 | 21 | $table->rememberToken(); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | */ 29 | public function down() 30 | { 31 | Schema::dropIfExists('users'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/database/migrations/2017_02_28_202951_create_pages_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 16 | $table->integer('parent_id')->nullable(); 17 | $table->integer('lft')->nullable(); 18 | $table->integer('rgt')->nullable(); 19 | $table->integer('depth')->nullable(); 20 | 21 | $table->string('cover')->nullable(); 22 | $table->string('action')->nullable(); 23 | $table->string('icon')->nullable(); 24 | $table->string('template')->nullable(); 25 | $table->string('middlewares')->nullable(); 26 | $table->string('route_name')->nullable(); 27 | $table->json('prefix')->nullable(); 28 | $table->json('url'); 29 | $table->json('title'); 30 | $table->json('body')->nullable(); 31 | $table->json('desc')->nullable(); 32 | $table->json('meta')->nullable(); 33 | 34 | $table->softDeletes(); 35 | $table->timestamps(); 36 | }); 37 | } 38 | 39 | /** 40 | * Reverse the migrations. 41 | */ 42 | public function down() 43 | { 44 | Schema::dropIfExists('pages'); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/database/migrations/2017_03_01_232714_create_menus_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 16 | $table->string('name'); 17 | $table->timestamps(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | */ 24 | public function down() 25 | { 26 | Schema::dropIfExists('menus'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/database/migrations/2017_03_01_232836_create_menu_page_table.php: -------------------------------------------------------------------------------- 1 | integer('menu_id')->unsigned()->index(); 16 | $table->foreign('menu_id')->references('id')->on('menus')->onDelete('cascade'); 17 | $table->integer('page_id')->unsigned()->index(); 18 | $table->foreign('page_id')->references('id')->on('pages')->onDelete('cascade'); 19 | 20 | $table->integer('order')->nullable(); 21 | }); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | */ 27 | public function down() 28 | { 29 | Schema::dropIfExists('menu_page'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/database/seeds/DatabaseSeeder.example: -------------------------------------------------------------------------------- 1 | flush(); 13 | app('files')->delete(config('simpleMenu.routeListPath')); 14 | 15 | $this->call(PagesTableSeeder::class); 16 | $this->call(MenusTableSeeder::class); 17 | $this->call(MenuPagesTableSeeder::class); 18 | $this->call(RolePermSeeder::class); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/database/seeds/MenuPagesTableSeeder.php: -------------------------------------------------------------------------------- 1 | all() as $key => $val) { 16 | $menu = $menuModel->inRandomOrder()->first(); 17 | $menu->pages()->attach($val->id); 18 | } 19 | 20 | $pageModel->findOrFail(4)->makeChildOf($pageModel->findOrFail(3)); 21 | $pageModel->findOrFail(5)->makeChildOf($pageModel->findOrFail(4)); 22 | $pageModel->findOrFail(6)->makeChildOf($pageModel->findOrFail(5)); 23 | $pageModel->findOrFail(7)->makeChildOf($pageModel->findOrFail(6)); 24 | $pageModel->findOrFail(8)->makeChildOf($pageModel->findOrFail(7)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/database/seeds/MenusTableSeeder.php: -------------------------------------------------------------------------------- 1 | create(['name'=>$one]); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/database/seeds/PagesTableSeeder.php: -------------------------------------------------------------------------------- 1 | unique()->city; 19 | $es = $faker->unique()->city; 20 | 21 | $pageModel->create([ 22 | 'template' => 'SimpleMenu::template-example', 23 | 'route_name'=> Str::slug($en), 24 | 'title' => [ 25 | 'en' => Str::title($en), 26 | 'es' => Str::title($es), 27 | ], 28 | 'body' => [ 29 | 'en' => $faker->text(), 30 | 'es' => $faker->text(), 31 | ], 32 | 'desc' => [ 33 | 'en' => $faker->text(), 34 | 'es' => $faker->text(), 35 | ], 36 | 'prefix' => [ 37 | 'en' => Str::slug($faker->unique()->country), 38 | 'es' => Str::slug($faker->unique()->country), 39 | ], 40 | 'url' => [ 41 | 'en' => Str::slug($en), 42 | 'es' => Str::slug($es), 43 | ], 44 | ]); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/database/seeds/RolePermSeeder.php: -------------------------------------------------------------------------------- 1 | create(['name' => $role]); 22 | } 23 | 24 | foreach ($perms as $perm) { 25 | $permissionModel->create(['name' => $perm]); 26 | } 27 | 28 | // foreach ($pageModel->all() as $page) { 29 | // $page->givePermissionTo('guest'); 30 | // $page->assignRole('guest'); 31 | // } 32 | 33 | $userModel->first()->assignRole('admin'); 34 | $userModel->first()->givePermissionTo('access_backend'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/resources/assets/js/index.vue: -------------------------------------------------------------------------------- 1 | 91 | -------------------------------------------------------------------------------- /src/resources/assets/js/manager.js: -------------------------------------------------------------------------------- 1 | /* Packages */ 2 | window.EventHub = require('vuemit') 3 | Vue.use(require('vue-tippy'), { 4 | arrow: true, 5 | touchHold: true, 6 | inertia: true, 7 | performance: true, 8 | flipDuration: 0, 9 | popperOptions: { 10 | modifiers: { 11 | preventOverflow: { 12 | enabled: false 13 | }, 14 | hide: { 15 | enabled: false 16 | } 17 | } 18 | } 19 | }) 20 | require('vue-multi-ref') 21 | 22 | // icons 23 | import 'vue-awesome/icons/search' 24 | import 'vue-awesome/icons/times' 25 | import 'vue-awesome/icons/pencil' 26 | Vue.component('icon', require('vue-awesome/components/Icon').default) 27 | 28 | // table sort 29 | window.ListJS = require('list.js') 30 | 31 | // axios 32 | window.axios = require('axios') 33 | axios.defaults.headers.common = { 34 | 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'), 35 | 'X-Requested-With': 'XMLHttpRequest' 36 | } 37 | axios.interceptors.response.use( 38 | (response) => response, 39 | (error) => Promise.reject(error.response) 40 | ) 41 | 42 | /* Component */ 43 | Vue.component('SmPage', require('./page.vue').default) 44 | Vue.component('SmMenu', require('./menu.vue').default) 45 | Vue.component('SmIndex', require('./index.vue').default) 46 | Vue.component('MyNotification', require('vue-notif').default) 47 | -------------------------------------------------------------------------------- /src/resources/assets/js/menu.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 176 | -------------------------------------------------------------------------------- /src/resources/assets/js/menu_child.vue: -------------------------------------------------------------------------------- 1 | 47 | 48 | 67 | 68 | 121 | -------------------------------------------------------------------------------- /src/resources/assets/js/mixins/menu.js: -------------------------------------------------------------------------------- 1 | export default { 2 | props: ['locale', 'delChild', 'editPage', 'translation'], 3 | data() { 4 | return { 5 | isDragging: false 6 | } 7 | }, 8 | created() { 9 | this.eventsListeners() 10 | }, 11 | methods: { 12 | getTitle(title) { 13 | let locale = this.locale 14 | 15 | return title.hasOwnProperty(locale) 16 | ? title[locale] 17 | : Object.values(title)[0].concat(` "${Object.keys(title)[0]}"`) 18 | }, 19 | goTo(id) { 20 | return this.editPage.replace(0, id) 21 | }, 22 | trans(key) { 23 | return this.translation[key] 24 | }, 25 | 26 | // ops 27 | eventsListeners() { 28 | EventHub.listen('DragStart', () => { 29 | this.isDragging = true 30 | }) 31 | 32 | EventHub.listen('DragEnd', () => { 33 | this.isDragging = false 34 | }) 35 | }, 36 | hasChilds(item) { 37 | return item.nests && item.nests.length > 0 38 | }, 39 | 40 | // style 41 | classObj(item) { 42 | if (this.checkFrom(item)) { 43 | return 'is-warning' 44 | } 45 | if (item.created_at == null) { 46 | return 'is-danger' 47 | } 48 | }, 49 | 50 | // notif 51 | showNotif(msg) { 52 | EventHub.fire('showNotif', { 53 | title: 'Success', 54 | body: msg, 55 | type: 'success', 56 | duration: 2, 57 | icon: false 58 | }) 59 | }, 60 | 61 | // nests 62 | dragStart() { 63 | this.isDragging = true 64 | EventHub.fire('DragStart') 65 | }, 66 | dragEnd() { 67 | this.isDragging = false 68 | EventHub.fire('DragEnd') 69 | } 70 | 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/resources/assets/js/mixins/search.js: -------------------------------------------------------------------------------- 1 | export default { 2 | data() { 3 | return { 4 | searchFor: null 5 | } 6 | }, 7 | methods: { 8 | resetSearch() { 9 | this.searchFor = null 10 | } 11 | }, 12 | watch: { 13 | searchFor(val) { 14 | let res = this.sorter.search(val, [this.searchColName]) 15 | 16 | if (typeof this.updateCounter == 'function') { 17 | this.updateCounter(res.length) 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/resources/assets/js/page.vue: -------------------------------------------------------------------------------- 1 | 136 | -------------------------------------------------------------------------------- /src/resources/assets/sass/_checkbox.scss: -------------------------------------------------------------------------------- 1 | // https://codepen.io/andreasstorm/pen/ybPwre 2 | 3 | $grey-lighter: #dbdbdb; 4 | $primary: #ff3860; 5 | 6 | .cbx-checkbox { 7 | &[type='checkbox'], 8 | &:checked { 9 | display: none; 10 | } 11 | } 12 | 13 | .cbx { 14 | position: relative; 15 | top: 1px; 16 | display: inline-block; 17 | width: 14px; 18 | height: 14px; 19 | margin-right: 6px; 20 | cursor: pointer; 21 | vertical-align: sub; 22 | border: 1px solid $grey-lighter; 23 | border-radius: 3px; 24 | 25 | &::before { 26 | position: absolute; 27 | top: 50%; 28 | left: 50%; 29 | width: 20px; 30 | height: 20px; 31 | margin: -10px 0 0 -10px; 32 | content: ''; 33 | transform: scale(0); 34 | border-radius: 100%; 35 | background: $primary; 36 | } 37 | 38 | &::after { 39 | position: absolute; 40 | top: 5px; 41 | left: 5px; 42 | width: 2px; 43 | height: 2px; 44 | content: ''; 45 | transform: scale(0); 46 | border-radius: 2px; 47 | box-shadow: 0 -18px 0 $primary, 12px -12px 0 $primary, 18px 0 0 $primary, 12px 12px 0 $primary, 0 18px 0 $primary, -12px 12px 0 $primary, -18px 0 0 $primary, -12px -12px 0 $primary; 48 | } 49 | 50 | svg { 51 | position: relative; 52 | top: -1px; 53 | transform: scale(0); 54 | fill: none; 55 | stroke-linecap: round; 56 | stroke-linejoin: round; 57 | 58 | polyline { 59 | stroke: $primary; 60 | stroke-width: 2; 61 | } 62 | } 63 | } 64 | 65 | input:checked + .cbx { 66 | top: 0; 67 | border-color: transparent; 68 | 69 | &::before { 70 | transition: all 0.3s ease; 71 | transform: scale(1); 72 | opacity: 0; 73 | } 74 | 75 | &::after { 76 | transition: all 0.6s ease; 77 | transform: scale(1); 78 | opacity: 0; 79 | } 80 | 81 | svg { 82 | transition: all 0.4s ease; 83 | transition-delay: 0.1s; 84 | transform: scale(1); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/resources/assets/sass/style.scss: -------------------------------------------------------------------------------- 1 | @import './checkbox'; 2 | 3 | $blue: #3273dc; 4 | $mce-brdr: #eee; 5 | $mce-btn: #a3afb7; 6 | 7 | [v-cloak] { 8 | display: none; 9 | } 10 | 11 | td { 12 | vertical-align: middle !important; 13 | } 14 | 15 | thead th { 16 | position: sticky; 17 | z-index: 1; 18 | top: 0; 19 | background-color: white; 20 | } 21 | 22 | .m-t-5 { 23 | margin-top: 5px; 24 | } 25 | 26 | .link { 27 | cursor: pointer; 28 | } 29 | 30 | .static-cell { 31 | width: 1%; 32 | white-space: nowrap; 33 | } 34 | 35 | // select 36 | .choices { 37 | font-size: 1rem; 38 | } 39 | 40 | .choices__inner { 41 | font-size: 1rem; 42 | min-height: 29px; 43 | padding: 0.5rem; 44 | border-radius: 3px; 45 | background-color: transparent; 46 | } 47 | 48 | .choices__input { 49 | width: auto !important; 50 | margin: 0; 51 | padding: 0; 52 | background-color: transparent; 53 | } 54 | 55 | .choices__list--multiple .choices__item { 56 | margin-bottom: 0; 57 | border: none; 58 | border-radius: 100vw; 59 | background-color: $blue; 60 | } 61 | 62 | .choices__button { 63 | margin: 0 !important; 64 | padding: 0 !important; 65 | padding-left: 1.5rem !important; 66 | border: none !important; 67 | } 68 | 69 | // input locales 70 | .input-box { 71 | position: relative; 72 | } 73 | 74 | .toggle-locale { 75 | position: absolute; 76 | z-index: 1; 77 | top: 0; 78 | right: 1px; 79 | opacity: 0.3; 80 | 81 | &:hover { 82 | opacity: 1; 83 | } 84 | 85 | &::after { 86 | display: none !important; 87 | } 88 | 89 | select { 90 | font-weight: bold; 91 | padding: 0.4rem 0.5rem 0.5rem !important; 92 | text-transform: capitalize; 93 | border: none; 94 | background-color: transparent; 95 | } 96 | } 97 | 98 | .toggle-pad { 99 | padding-right: 32px; 100 | } 101 | 102 | // tinymce 103 | .mce-statusbar { 104 | border: none !important; 105 | } 106 | 107 | .mce-path { 108 | visibility: hidden !important; 109 | } 110 | 111 | .mce-panel { 112 | border-color: $mce-brdr !important; 113 | border-radius: 3px !important; 114 | } 115 | 116 | .mce-tinymce, 117 | .mce-top-part::before { 118 | box-shadow: none !important; 119 | } 120 | 121 | .mce-btn { 122 | &:hover, 123 | &:active { 124 | border-color: transparent !important; 125 | } 126 | 127 | button { 128 | padding: 4px 8px !important; 129 | } 130 | } 131 | 132 | .mce-btn-group:not(:first-child) { 133 | border-left: none !important; 134 | } 135 | 136 | .mce-btn, 137 | .mce-ico { 138 | color: $mce-btn !important; 139 | } 140 | 141 | // ace 142 | #ace-editor { 143 | width: 100%; 144 | height: 500px; 145 | } 146 | 147 | // menu 148 | .menu-item { 149 | margin-bottom: 0.5em !important; 150 | padding: 0.5em; 151 | padding-left: 1em; 152 | } 153 | 154 | .dragArea { 155 | display: block; 156 | min-height: 25px; 157 | } 158 | 159 | .ghost { 160 | opacity: 1; 161 | } 162 | 163 | .is-white { 164 | color: white; 165 | } 166 | -------------------------------------------------------------------------------- /src/resources/lang/en/messages.php: -------------------------------------------------------------------------------- 1 | 'Access', 5 | 'account' => 'Account', 6 | 'action' => 'Action', 7 | 'add_new' => 'Add new', 8 | 'avatar' => 'Avatar', 9 | 'background' => 'Background', 10 | 'bio' => 'Bio', 11 | 'body' => 'Body', 12 | 'content' => 'Content', 13 | 'control' => 'Control', 14 | 'cover' => 'Cover', 15 | 'icon' => 'Icon', 16 | 'create_new' => 'Create new', 17 | 'delete' => 'Delete', 18 | 'delete_selected' => 'Delete Selected', 19 | 'desc' => 'Description', 20 | 'edit' => 'Edit', 21 | 'email' => 'Email', 22 | 'find' => 'Find', 23 | 'go_back' => 'Go Back', 24 | 'guards' => 'Guards', 25 | 'locals' => 'Title Available In', 26 | 'menus' => 'Menus', 27 | 'meta' => 'Meta Keywords', 28 | 'middlewares' => 'MiddleWares', 29 | 'model_created' => 'Model Created !', 30 | 'model_deleted' => 'Model Deleted !', 31 | 'model_deleted_perm' => 'Model Deleted Permanently !', 32 | 'model_updated' => 'Model Updated !', 33 | 'models_deleted' => 'Models Deleted !', 34 | 'name' => 'Name', 35 | 'no_entries' => 'No Data To Display', 36 | 'ops' => 'Operations', 37 | 'pages' => 'Pages', 38 | 'password' => 'Password', 39 | 'perm_delete' => 'Permanently Delete', 40 | 'permissions' => 'Permissions', 41 | 'regex' => 'The :attribute must have an "@"', 42 | 'remove_child' => 'Remove Child', 43 | 'remove_page' => 'Remove Page', 44 | 'restore' => 'Restore', 45 | 'roles' => 'Roles', 46 | 'route' => 'Route Name', 47 | 'route_name' => 'Route Name', 48 | 'save' => 'Save', 49 | 'select_all' => 'Select All', 50 | 'select_non' => 'Select Non', 51 | 'status' => 'Status', 52 | 'template' => 'Template', 53 | 'title' => 'Title', 54 | 'undo' => 'Undo', 55 | 'update' => 'Update', 56 | 'url' => 'Url', 57 | 'url_prefix' => 'Url Prefix', 58 | 'users' => 'Users', 59 | ]; 60 | -------------------------------------------------------------------------------- /src/resources/pagination/bulma.blade.php: -------------------------------------------------------------------------------- 1 | @if ($paginator->hasPages()) 2 | 39 | @endif 40 | -------------------------------------------------------------------------------- /src/resources/views/admin/admin.blade.php: -------------------------------------------------------------------------------- 1 | @include("SimpleMenu::admin.shared") 2 | -------------------------------------------------------------------------------- /src/resources/views/admin/editors.blade.php: -------------------------------------------------------------------------------- 1 | {{-- choices --}} 2 | 3 | {{-- tinymce --}} 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {{-- ace --}} 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/resources/views/admin/menus/create.blade.php: -------------------------------------------------------------------------------- 1 | @extends("SimpleMenu::admin.shared") 2 | @section('title'){{ trans('SimpleMenu::messages.create_new') }} {{ trans('SimpleMenu::messages.menus') }}@endsection 3 | 4 | @section('sub') 5 |

6 | {{ trans('SimpleMenu::messages.go_back') }} 7 |

8 | 9 | {{ Form::open(['method' => 'POST', 'route' => $crud_prefix.'.menus.store']) }} 10 | 11 | {{-- name --}} 12 |
13 | {{ Form::label('name', trans('SimpleMenu::messages.name'), ['class' => 'label']) }} 14 |
15 |
16 |
17 | {{ Form::text('name', null, ['class' => 'input', 'placeholder' => 'name']) }} 18 | @if($errors->has('name')) 19 |

20 | {{ $errors->first('name') }} 21 |

22 | @endif 23 |
24 |
25 | {{ Form::submit(trans('SimpleMenu::messages.save'), ['class' => 'button is-success']) }} 26 |
27 |
28 | 29 | {{ Form::close() }} 30 | @endsection 31 | -------------------------------------------------------------------------------- /src/resources/views/admin/menus/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends("SimpleMenu::admin.shared") 2 | @section('title'){{ trans('SimpleMenu::messages.edit') }} "{{ $menu->name }}"@endsection 3 | 4 | @section('sub') 5 |

6 |
7 | 12 |
13 | {{-- create new --}} 14 | 20 | 21 | {{-- delete --}} 22 |
23 | {{ Form::open(['method' => 'DELETE', 'route' => [$crud_prefix.'.menus.destroy', $menu->id]]) }} 24 | 25 | {{ Form::close() }} 26 |
27 |
28 |
29 |

30 | 31 | 37 |
38 | {{ Form::model($menu, ['method' => 'PUT', 'route' => [$crud_prefix.'.menus.update', $menu->id]]) }} 39 | 40 | {{-- name --}} 41 |
42 | {{ Form::label('name', trans('SimpleMenu::messages.name'), ['class' => 'label']) }} 43 |
44 |
45 |
46 | {{ Form::text('name', $menu->name, ['class' => 'input']) }} 47 | @if($errors->has('name')) 48 |

49 | {{ $errors->first('name') }} 50 |

51 | @endif 52 |
53 |
54 | {{ Form::submit(trans('SimpleMenu::messages.update'), ['class' => 'button is-warning']) }} 55 |
56 |
57 | 58 |
59 | {{-- pages --}} 60 | 68 |
  • 69 | {{-- main --}} 70 | 96 | 97 | {{-- childs --}} 98 | 109 | 110 |
  • 111 |
    112 | 113 | {{-- all_pages --}} 114 | 120 | 130 | 131 |
    132 | 133 | 134 | {{ Form::close() }} 135 |
    136 |
    137 | @endsection 138 | -------------------------------------------------------------------------------- /src/resources/views/admin/menus/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends("SimpleMenu::admin.shared") 2 | @section('title', trans('SimpleMenu::messages.menus')) 3 | 4 | @section('sub') 5 | 6 |
    7 |
    8 |
    9 |
    10 | {{-- delete multi --}} 11 |
    12 | 20 |
    21 | 22 | {{-- add new --}} 23 | 29 |
    30 |
    31 | 32 |
    33 |
    34 |

    35 | {{ trans('SimpleMenu::messages.menus') }} "@{{ itemsCount }}" 36 |

    37 |
    38 | 39 | {{-- search --}} 40 |
    41 |
    42 |

    43 | 47 | 48 | 49 | 50 |

    51 |

    52 | 56 |

    57 |
    58 |
    59 |
    60 | 61 | 62 | 63 | 64 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | @foreach ($menus as $menu) 76 | 77 | 88 | 89 | 104 | 105 | @endforeach 106 | 107 | 108 | 109 | 110 | 111 |
    {{ trans('SimpleMenu::messages.name') }}{{ trans('SimpleMenu::messages.ops') }}
    {{ trans('SimpleMenu::messages.no_entries') }}
    112 |
    113 |
    114 | @endsection 115 | -------------------------------------------------------------------------------- /src/resources/views/admin/pages/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends("SimpleMenu::admin.shared") 2 | @section('title', trans('SimpleMenu::messages.pages')) 3 | 4 | @section('sub') 5 | 6 |
    7 |
    8 |
    9 |
    10 | {{-- delete multi --}} 11 |
    12 | 20 |
    21 | 22 | {{-- add new --}} 23 | 29 |
    30 |
    31 | 32 |
    33 |
    34 |

    35 | {{ trans('SimpleMenu::messages.pages') }} "@{{ itemsCount }}" 36 |

    37 |
    38 | 39 | {{-- search --}} 40 |
    41 |
    42 |

    43 | 47 | 48 | 49 | 50 |

    51 |

    52 | 56 |

    57 |
    58 |
    59 |
    60 | 61 | 62 | 63 | 64 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | @foreach ($pages as $page) 84 | @include('SimpleMenu::menu.partials.r_params') 85 | 86 | 87 | 98 | 105 | 106 | 107 | 112 | 119 | 126 | 133 | 138 | 143 | 182 | 183 | @endforeach 184 | 185 | 186 | 187 | 188 | 189 |
    {{ trans('SimpleMenu::messages.title') }}{{ trans('SimpleMenu::messages.route') }}{{ trans('SimpleMenu::messages.url') }}{{ trans('SimpleMenu::messages.middlewares') }}{{ trans('SimpleMenu::messages.roles') }}{{ trans('SimpleMenu::messages.permissions') }}{{ trans('SimpleMenu::messages.menus') }}{{ trans('SimpleMenu::messages.locals') }}{{ trans('SimpleMenu::messages.template') }}{{ trans('SimpleMenu::messages.ops') }}
    99 | @if (in_array(LaravelLocalization::getCurrentLocale(), $page->getTranslatedLocales('title'))) 100 | {{ $page->title }} 101 | @else 102 | {{ empty($page->title) ? collect($page->getTranslations('title'))->first() : $page->title }} 103 | @endif 104 | {{ $page->route_name }}{{ $page->prefix ? "$page->prefix/$page->url" : $page->url }} 108 | @if ($page->middlewares) 109 | {{ $page->middlewares }} 110 | @endif 111 | 113 | @foreach ($page->roles as $role) 114 | 115 | {{ $role->name }} 116 | 117 | @endforeach 118 | 120 | @foreach ($page->permissions as $perm) 121 | 122 | {{ $perm->name }} 123 | 124 | @endforeach 125 | 127 | @foreach ($page->menus as $menu) 128 | 129 | {{ $menu->name }} 130 | 131 | @endforeach 132 | 134 | @foreach ($page->getTranslatedLocales('title') as $locale) 135 | {{ $locale }} 136 | @endforeach 137 | 139 | @if ($page->template) 140 | {{ $page->template }} 141 | @endif 142 | 144 | 146 | {{ trans('SimpleMenu::messages.edit') }} 147 | 148 | 149 | {{-- soft delete --}} 150 | @if ($page->trashed()) 151 | 152 | {{ Form::open(['method' => 'PUT', 'route' => [$crud_prefix.'.pages.restore', $page->id]]) }} 153 | 156 | {{ Form::close() }} 157 | 158 | 159 | 160 | {{ Form::open(['method' => 'DELETE', 'route' => [$crud_prefix.'.pages.destroy_force', $page->id]]) }} 161 | 164 | {{ Form::close() }} 165 | 166 | 167 | {{-- delete --}} 168 | @else 169 | @php 170 | $check = $page->route_name == $crud_prefix ? 'disabled' : ''; 171 | @endphp 172 | 173 | 174 | {{ Form::open(['method' => 'DELETE', 'route' => [$crud_prefix.'.pages.destroy', $page->id]]) }} 175 | 178 | {{ Form::close() }} 179 | 180 | @endif 181 |
    {{ trans('SimpleMenu::messages.no_entries') }}
    190 |
    191 |
    192 | @endsection 193 | -------------------------------------------------------------------------------- /src/resources/views/admin/permissions/create.blade.php: -------------------------------------------------------------------------------- 1 | @extends("SimpleMenu::admin.shared") 2 | @section('title'){{ trans('SimpleMenu::messages.create_new') }} {{ trans('SimpleMenu::messages.permissions') }}@endsection 3 | 4 | @section('sub') 5 |

    6 | {{ trans('SimpleMenu::messages.go_back') }} 7 |

    8 | 9 | {{ Form::open(['method' => 'POST', 'route' => $crud_prefix.'.permissions.store']) }} 10 | 11 | {{-- name --}} 12 |
    13 | {{ Form::label('name', trans('SimpleMenu::messages.name'), ['class' => 'label']) }} 14 |
    15 |
    16 |
    17 | {{ Form::text('name', null, ['class' => 'input']) }} 18 | @if($errors->has('name')) 19 |

    20 | {{ $errors->first('name') }} 21 |

    22 | @endif 23 |
    24 |
    25 | {{ Form::submit(trans('SimpleMenu::messages.save'), ['class' => 'button is-success']) }} 26 |
    27 |
    28 | 29 | {{ Form::close() }} 30 | @endsection 31 | -------------------------------------------------------------------------------- /src/resources/views/admin/permissions/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends("SimpleMenu::admin.shared") 2 | @section('title'){{ trans('SimpleMenu::messages.edit') }} "{{ $permission->name }}"@endsection 3 | 4 | @section('sub') 5 |
    6 |
    7 |

    8 | {{ trans('SimpleMenu::messages.go_back') }} 9 |

    10 |
    11 |
    12 | {{-- create new --}} 13 | 19 | 20 | {{-- delete --}} 21 |
    22 | @php 23 | $check = in_array($permission->name, auth()->user()->permissions->pluck('name')->toArray()) 24 | ? 'disabled' 25 | : ''; 26 | @endphp 27 | 28 | {{ Form::open(['method' => 'DELETE', 'route' => [$crud_prefix.'.permissions.destroy', $permission->id]]) }} 29 | 32 | {{ Form::close() }} 33 |
    34 |
    35 |
    36 | 37 | {{ Form::model($permission, ['method' => 'PUT', 'route' => [$crud_prefix.'.permissions.update', $permission->id]]) }} 38 | 39 | {{-- name --}} 40 |
    41 | {{ Form::label('name', trans('SimpleMenu::messages.name'), ['class' => 'label']) }} 42 |
    43 |
    44 |
    45 | {{ Form::text('name', $permission->name, ['class' => 'input']) }} 46 | @if($errors->has('name')) 47 |

    48 | {{ $errors->first('name') }} 49 |

    50 | @endif 51 |
    52 |
    53 | {{ Form::submit(trans('SimpleMenu::messages.update'), ['class' => 'button is-warning']) }} 54 |
    55 |
    56 | 57 | {{ Form::close() }} 58 | @endsection 59 | -------------------------------------------------------------------------------- /src/resources/views/admin/permissions/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends("SimpleMenu::admin.shared") 2 | @section('title', trans('SimpleMenu::messages.permissions')) 3 | 4 | @section('sub') 5 | 6 |
    7 |
    8 |
    9 |
    10 | {{-- delete multi --}} 11 |
    12 | 20 |
    21 | 22 | {{-- add new --}} 23 | 29 |
    30 |
    31 |
    32 |
    33 |

    34 | {{ trans('SimpleMenu::messages.permissions') }} "@{{ itemsCount }}" 35 |

    36 |
    37 | 38 | {{-- search --}} 39 |
    40 |
    41 |

    42 | 46 | 47 | 48 | 49 |

    50 |

    51 | 55 |

    56 |
    57 |
    58 |
    59 | 60 | 61 | 62 | 63 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | @foreach ($permissions as $permission) 75 | 76 | 87 | 88 | 113 | 114 | @endforeach 115 | 116 | 117 | 118 | 119 | 120 |
    {{ trans('SimpleMenu::messages.name') }}{{ trans('SimpleMenu::messages.ops') }}
    {{ $permission->name }} 89 | 91 | {{ trans('SimpleMenu::messages.edit') }} 92 | 93 | 94 | @php 95 | $check = in_array($permission->name, auth()->user()->permissions->pluck('name')->toArray()) 96 | ? 'disabled' 97 | : ''; 98 | @endphp 99 | 100 | 101 | {{ Form::open([ 102 | 'method' => 'DELETE', 103 | 'route' => [$crud_prefix.'.permissions.destroy', $permission->id], 104 | 'data-id' => 'item-'.$permission->id, 105 | '@submit.prevent' => 'DelItem($event, "'.$permission->name.'")' 106 | ]) }} 107 | 110 | {{ Form::close() }} 111 | 112 |
    {{ trans('SimpleMenu::messages.no_entries') }}
    121 |
    122 |
    123 | @endsection 124 | -------------------------------------------------------------------------------- /src/resources/views/admin/roles/create.blade.php: -------------------------------------------------------------------------------- 1 | @extends("SimpleMenu::admin.shared") 2 | @section('title'){{ trans('SimpleMenu::messages.create_new') }} {{ trans('SimpleMenu::messages.roles') }}@endsection 3 | 4 | @section('sub') 5 |

    6 | {{ trans('SimpleMenu::messages.go_back') }} 7 |

    8 | 9 | 10 | {{ Form::open(['method' => 'POST', 'route' => $crud_prefix.'.roles.store']) }} 11 | 12 | {{-- name --}} 13 |
    14 | {{ Form::label('name', trans('SimpleMenu::messages.name'), ['class' => 'label']) }} 15 |
    16 | {{ Form::text('name', null, ['class' => 'input']) }} 17 |
    18 | @if($errors->has('name')) 19 | 20 | {{ $errors->first('name') }} 21 | 22 | @endif 23 |
    24 | 25 | {{-- permissions --}} 26 |
    27 | {{ Form::label('permissions', trans('SimpleMenu::messages.permissions'), ['class' => 'label']) }} 28 |
    29 | {{ Form::select('permissions[]', $permissions, null, ['class' => 'select2', 'multiple' => 'multiple']) }} 30 |
    31 | @if($errors->has('permissions')) 32 | 33 | {{ $errors->first('permissions') }} 34 | 35 | @endif 36 |
    37 | 38 | {{ Form::submit(trans('SimpleMenu::messages.save'), ['class' => 'button is-success']) }} 39 | {{ Form::close() }} 40 |
    41 | @endsection 42 | -------------------------------------------------------------------------------- /src/resources/views/admin/roles/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends("SimpleMenu::admin.shared") 2 | @section('title'){{ trans('SimpleMenu::messages.edit') }} "{{ $role->name }}"@endsection 3 | 4 | @section('sub') 5 |
    6 |
    7 |

    8 | {{ trans('SimpleMenu::messages.go_back') }} 9 |

    10 |
    11 |
    12 | {{-- create new --}} 13 | 19 | {{-- delete --}} 20 |
    21 | @php 22 | $check = in_array($role->name, auth()->user()->roles->pluck('name')->toArray()) 23 | ? 'disabled' 24 | : ''; 25 | @endphp 26 | 27 | {{ Form::open(['method' => 'DELETE', 'route' => [$crud_prefix.'.roles.destroy', $role->id]]) }} 28 | 31 | {{ Form::close() }} 32 |
    33 |
    34 |
    35 | 36 | 37 | {{ Form::model($role, ['method' => 'PUT', 'route' => [$crud_prefix.'.roles.update', $role->id]]) }} 38 | 39 | {{-- name --}} 40 |
    41 | {{ Form::label('name', trans('SimpleMenu::messages.name'), ['class' => 'label']) }} 42 |
    43 | {{ Form::text('name', $role->name, ['class' => 'input']) }} 44 |
    45 | @if($errors->has('name')) 46 |

    47 | {{ $errors->first('name') }} 48 |

    49 | @endif 50 |
    51 | 52 | {{-- permissions --}} 53 |
    54 | {{ Form::label('permissions', trans('SimpleMenu::messages.permissions'), ['class' => 'label']) }} 55 |
    56 | {{ Form::select( 57 | 'permissions[]', 58 | $permissions, 59 | $role->permissions->pluck('name', 'name'), 60 | ['class' => 'select2', 'multiple' => 'multiple'] 61 | ) }} 62 |
    63 | @if($errors->has('permissions')) 64 |

    65 | {{ $errors->first('permissions') }} 66 |

    67 | @endif 68 |
    69 | 70 | {{ Form::submit(trans('SimpleMenu::messages.update'), ['class' => 'button is-warning']) }} 71 | {{ Form::close() }} 72 |
    73 | @endsection 74 | -------------------------------------------------------------------------------- /src/resources/views/admin/roles/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends("SimpleMenu::admin.shared") 2 | @section('title', trans('SimpleMenu::messages.roles')) 3 | 4 | @section('sub') 5 | 6 |
    7 |
    8 |
    9 |
    10 | {{-- delete multi --}} 11 |
    12 | 20 |
    21 | 22 | {{-- add new --}} 23 | 29 |
    30 |
    31 | 32 |
    33 |
    34 |

    35 | {{ trans('SimpleMenu::messages.roles') }} "@{{ itemsCount }}" 36 |

    37 |
    38 | 39 | {{-- search --}} 40 |
    41 |
    42 |

    43 | 47 | 48 | 49 | 50 |

    51 |

    52 | 56 |

    57 |
    58 |
    59 |
    60 | 61 | 62 | 63 | 64 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | @foreach ($roles as $role) 77 | 78 | 89 | 90 | 97 | 122 | 123 | @endforeach 124 | 125 | 126 | 127 | 128 | 129 |
    {{ trans('SimpleMenu::messages.name') }}{{ trans('SimpleMenu::messages.permissions') }}{{ trans('SimpleMenu::messages.ops') }}
    {{ $role->name }} 91 | @foreach ($role->permissions as $perm) 92 | 93 | {{ $perm->name }} 94 | 95 | @endforeach 96 | 98 | 100 | {{ trans('SimpleMenu::messages.edit') }} 101 | 102 | 103 | @php 104 | $check = in_array($role->name, auth()->user()->roles->pluck('name')->toArray()) 105 | ? 'disabled' 106 | : ''; 107 | @endphp 108 | 109 | 110 | {{ Form::open([ 111 | 'method' => 'DELETE', 112 | 'route' => [$crud_prefix.'.roles.destroy', $role->id], 113 | 'data-id' => 'item-'.$role->id, 114 | '@submit.prevent' => 'DelItem($event, "'.$role->name.'")' 115 | ]) }} 116 | 119 | {{ Form::close() }} 120 | 121 |
    {{ trans('SimpleMenu::messages.no_entries') }}
    130 |
    131 |
    132 | @endsection 133 | -------------------------------------------------------------------------------- /src/resources/views/admin/shared.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | @yield('title', '') 10 | 11 | {{-- styles --}} 12 | 13 | 14 | 15 | 16 | 17 | 18 |
    19 | 20 | {{-- notif --}} 21 |
    22 | {{-- Status --}} 23 | @if (session('status')) 24 | 29 | 30 | @endif 31 | 32 | 33 |
    34 | 35 | {{-- Body --}} 36 |
    37 |
    38 | {{-- Sidebar --}} 39 |
    40 | 76 |
    77 | 78 | {{-- Pages --}} 79 |
    80 | @yield('sub') 81 |
    82 |
    83 |
    84 |
    85 | 86 | {{-- Footer --}} 87 | @include("SimpleMenu::admin.editors") 88 | {{-- app --}} 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /src/resources/views/admin/users/create.blade.php: -------------------------------------------------------------------------------- 1 | @extends("SimpleMenu::admin.shared") 2 | @section('title'){{ trans('SimpleMenu::messages.create_new') }} {{ trans('SimpleMenu::messages.users') }}@endsection 3 | 4 | @section('sub') 5 |

    6 | {{ trans('SimpleMenu::messages.go_back') }} 7 |

    8 | 9 | 10 | {{ Form::open(['method' => 'POST', 'route' => $crud_prefix.'.users.store', 'files' => true]) }} 11 | 12 | {{-- avatar --}} 13 |
    14 |
    15 |

    {{ trans('SimpleMenu::messages.avatar') }}

    16 |
    17 |
    18 | 19 |
    20 |
    21 | 22 | {{-- Account --}} 23 |
    24 | {{-- data --}} 25 |
    26 |

    {{ trans('SimpleMenu::messages.account') }}

    27 |
    28 |
    29 | {{-- name --}} 30 |
    31 | {{ Form::label('name', trans('SimpleMenu::messages.name'), ['class' => 'label']) }} 32 |
    33 | {{ Form::text('name', null, ['class' => 'input']) }} 34 |
    35 | @if($errors->has('name')) 36 |

    37 | {{ $errors->first('name') }} 38 |

    39 | @endif 40 |
    41 | 42 | {{-- email --}} 43 |
    44 | {{ Form::label('email', trans('SimpleMenu::messages.email'), ['class' => 'label']) }} 45 |
    46 | {{ Form::email('email', null, ['class' => 'input']) }} 47 |
    48 | @if($errors->has('email')) 49 |

    50 | {{ $errors->first('email') }} 51 |

    52 | @endif 53 |
    54 | 55 | {{-- password --}} 56 |
    57 | {{ Form::label('password', trans('SimpleMenu::messages.password'), ['class' => 'label']) }} 58 |
    59 | {{ Form::password('password', ['class' => 'input', 'placeholder' => '******']) }} 60 |
    61 | @if($errors->has('password')) 62 |

    63 | {{ $errors->first('password') }} 64 |

    65 | @endif 66 |
    67 |
    68 |
    69 |
    70 | 71 | {{-- Guards --}} 72 |
    73 |
    74 |

    75 | {{ trans('SimpleMenu::messages.guards') }} 76 |

    77 |
    78 |
    79 | {{-- roles --}} 80 |
    81 | {{ Form::label('roles', trans('SimpleMenu::messages.roles'), ['class' => 'label']) }} 82 |
    83 | {{ Form::select( 84 | 'roles[]', 85 | $roles, 86 | null, 87 | ['class' => 'select2', 'multiple' => 'multiple'] 88 | ) }} 89 |
    90 | @if($errors->has('roles')) 91 |

    92 | {{ $errors->first('roles') }} 93 |

    94 | @endif 95 |
    96 | 97 | {{-- permissions --}} 98 |
    99 | {{ Form::label('permissions', trans('SimpleMenu::messages.permissions'), ['class' => 'label']) }} 100 |
    101 | {{ Form::select( 102 | 'permissions[]', 103 | $permissions, 104 | null, 105 | ['class' => 'select2', 'multiple' => 'multiple'] 106 | ) }} 107 |
    108 | @if($errors->has('permissions')) 109 |

    110 | {{ $errors->first('permissions') }} 111 |

    112 | @endif 113 |
    114 |
    115 |
    116 | 117 | {{-- Submit --}} 118 |
    119 |
    120 |
    121 | {{ Form::submit(trans('SimpleMenu::messages.save'), ['class' => 'button is-success is-fullwidth']) }} 122 |
    123 |
    124 | {{ Form::close() }} 125 |
    126 | @endsection 127 | -------------------------------------------------------------------------------- /src/resources/views/admin/users/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends("SimpleMenu::admin.shared") 2 | @section('title'){{ trans('SimpleMenu::messages.edit') }} "{{ $user->name }}"@endsection 3 | 4 | @section('sub') 5 |
    6 |
    7 |

    8 | {{ trans('SimpleMenu::messages.go_back') }} 9 |

    10 |
    11 |
    12 | {{-- create new --}} 13 | 19 | {{-- delete --}} 20 |
    21 | @php 22 | $check = $user->id == auth()->user()->id ? 'disabled' : ''; 23 | @endphp 24 | 25 | {{ Form::open(['method' => 'DELETE', 'route' => [$crud_prefix.'.users.destroy', $user->id]]) }} 26 | 29 | {{ Form::close() }} 30 |
    31 |
    32 |
    33 | 34 | 35 | {{ Form::model($user, ['method' => 'PUT', 'route' => [$crud_prefix.'.users.update', $user->id], 'files' => true]) }} 36 | 37 | {{-- avatar --}} 38 |
    39 |
    40 |

    {{ trans('SimpleMenu::messages.avatar') }}

    41 |
    42 |
    43 | {{-- preview --}} 44 | @if ($user->avatar) 45 | 46 | @endif 47 | {{-- upload --}} 48 |
    49 | 50 |
    51 |
    52 |
    53 | 54 | {{-- Account --}} 55 |
    56 | {{-- data --}} 57 |
    58 |

    {{ trans('SimpleMenu::messages.account') }}

    59 |
    60 |
    61 | {{-- name --}} 62 |
    63 | {{ Form::label('name', trans('SimpleMenu::messages.name'), ['class' => 'label']) }} 64 |
    65 | {{ Form::text('name', $user->name, ['class' => 'input']) }} 66 |
    67 | @if($errors->has('name')) 68 |

    69 | {{ $errors->first('name') }} 70 |

    71 | @endif 72 |
    73 | 74 | {{-- email --}} 75 |
    76 | {{ Form::label('email', trans('SimpleMenu::messages.email'), ['class' => 'label']) }} 77 |
    78 | {{ Form::email('email', $user->email, ['class' => 'input']) }} 79 |
    80 | @if($errors->has('email')) 81 |

    82 | {{ $errors->first('email') }} 83 |

    84 | @endif 85 |
    86 | 87 | {{-- password --}} 88 |
    89 | {{ Form::label('password', trans('SimpleMenu::messages.password'), ['class' => 'label']) }} 90 |
    91 | {{ Form::password('password', ['class' => 'input', 'placeholder' => '******']) }} 92 |
    93 | @if($errors->has('password')) 94 |

    95 | {{ $errors->first('password') }} 96 |

    97 | @endif 98 |
    99 |
    100 |
    101 |
    102 | 103 | {{-- Guards --}} 104 |
    105 |
    106 |

    {{ trans('SimpleMenu::messages.guards') }}

    107 |
    108 |
    109 | {{-- roles --}} 110 |
    111 | {{ Form::label('roles', trans('SimpleMenu::messages.roles'), ['class' => 'label']) }} 112 |
    113 | {{ Form::select( 114 | 'roles[]', 115 | $roles, 116 | $user->roles->pluck('name', 'name'), 117 | ['class' => 'select2', 'multiple' => 'multiple'] 118 | ) }} 119 |
    120 | @if($errors->has('roles')) 121 |

    122 | {{ $errors->first('roles') }} 123 |

    124 | @endif 125 |
    126 | 127 | {{-- permissions --}} 128 |
    129 | {{ Form::label('permissions', trans('SimpleMenu::messages.permissions'), ['class' => 'label']) }} 130 |
    131 | {{ Form::select( 132 | 'permissions[]', 133 | $permissions, 134 | $user->permissions->pluck('name', 'name'), 135 | ['class' => 'select2', 'multiple' => 'multiple'] 136 | ) }} 137 |
    138 | @if($errors->has('permissions')) 139 |

    140 | {{ $errors->first('permissions') }} 141 |

    142 | @endif 143 |
    144 |
    145 |
    146 | 147 | {{-- Submit --}} 148 |
    149 |
    150 |
    151 | {{ Form::submit(trans('SimpleMenu::messages.update'), ['class' => 'button is-warning is-fullwidth']) }} 152 |
    153 |
    154 | 155 | {{ Form::close() }} 156 |
    157 | @endsection 158 | -------------------------------------------------------------------------------- /src/resources/views/admin/users/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends("SimpleMenu::admin.shared") 2 | @section('title', trans('SimpleMenu::messages.users')) 3 | 4 | @section('sub') 5 | 6 |
    7 |
    8 |
    9 |
    10 | {{-- delete multi --}} 11 |
    12 | 20 |
    21 | 22 | {{-- add new --}} 23 | 29 |
    30 |
    31 | 32 |
    33 |
    34 |

    35 | {{ trans('SimpleMenu::messages.users') }} "@{{ itemsCount }}" 36 |

    37 |
    38 | 39 | {{-- search --}} 40 |
    41 |
    42 |

    43 | 47 | 48 | 49 | 50 |

    51 |

    52 | 56 |

    57 |
    58 |
    59 |
    60 | 61 | 62 | 63 | 64 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | @foreach ($users as $user) 79 | 80 | 91 | 92 | 93 | 100 | 107 | 130 | 131 | @endforeach 132 | 133 | 134 | 135 | 136 | 137 |
    {{ trans('SimpleMenu::messages.name') }}{{ trans('SimpleMenu::messages.email') }}{{ trans('SimpleMenu::messages.roles') }}{{ trans('SimpleMenu::messages.permissions') }}{{ trans('SimpleMenu::messages.ops') }}
    {{ $user->name }}{{ $user->email }} 94 | @foreach ($user->roles as $role) 95 | 96 | {{ $role->name }} 97 | 98 | @endforeach 99 | 101 | @foreach ($user->permissions as $perm) 102 | 103 | {{ $perm->name }} 104 | 105 | @endforeach 106 | 108 | 110 | {{ trans('SimpleMenu::messages.edit') }} 111 | 112 | 113 | @php 114 | $check = $user->id == auth()->user()->id ? 'disabled' : ''; 115 | @endphp 116 | 117 | 118 | {{ Form::open([ 119 | 'method' => 'DELETE', 120 | 'route' => [$crud_prefix.'.users.destroy', $user->id], 121 | 'data-id' => 'item-'.$user->id, 122 | '@submit.prevent' => 'DelItem($event, "'.$user->name.'")' 123 | ]) }} 124 | 127 | {{ Form::close() }} 128 | 129 |
    {{ trans('SimpleMenu::messages.no_entries') }}
    138 |
    139 |
    140 | @endsection 141 | -------------------------------------------------------------------------------- /src/resources/views/breadCrumb.blade.php: -------------------------------------------------------------------------------- 1 | @if ($breadCrumb = SimpleMenu::getBC()) 2 | 15 |
    16 | @endif 17 | -------------------------------------------------------------------------------- /src/resources/views/langSwitcher.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/resources/views/menu/example.blade.php: -------------------------------------------------------------------------------- 1 | @if (isset($PAGES)) 2 | 16 | @endif 17 | -------------------------------------------------------------------------------- /src/resources/views/menu/partials/nested.blade.php: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /src/resources/views/menu/partials/r_params.blade.php: -------------------------------------------------------------------------------- 1 | {{-- simple --}} 2 | @php 3 | SimpleMenu::getRoute($page->route_name); 4 | @endphp 5 | 6 | {{-- advanced --}} 7 | {{-- @php 8 | SimpleMenu::getRoute($page->route_name, [ 9 | 'about' => ['name'=> isset($var) ? $var : 'default'], 10 | 'contact-us' => ['name'=>'other'], 11 | ]) 12 | @endphp --}} -------------------------------------------------------------------------------- /src/resources/views/template-example.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | {{ $title }} 11 | 12 | {{-- styles --}} 13 | 14 | 15 | 16 |
    17 | 22 | 23 |
    24 |
    25 |
    26 |

    {!! $title !!}

    27 |

    {!! $desc !!}

    28 |
    {!! $body !!}
    29 |
    30 |
    31 |
    32 |
    33 | 34 | 35 | --------------------------------------------------------------------------------