Skip to content

Instantly share code, notes, and snippets.

@kiddtang
Last active September 9, 2021 13:19
Show Gist options
  • Save kiddtang/7ba0bb0b65c4bbfe9e9cf303951077af to your computer and use it in GitHub Desktop.
Save kiddtang/7ba0bb0b65c4bbfe9e9cf303951077af to your computer and use it in GitHub Desktop.
Build Free Pro Website with me - Part #2
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Spatie\Permission\Traits\HasRoles;
class Admin extends Authenticatable
{
use Notifiable;
use CrudTrait, HasRoles;
/**
* Your Admin Model content
*/
}
<?php
namespace App\Http\Controllers\Admin;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use Backpack\PermissionManager\app\Http\Requests\UserStoreCrudRequest as StoreRequest;
use Backpack\PermissionManager\app\Http\Requests\UserUpdateCrudRequest as UpdateRequest;
use Illuminate\Support\Facades\Hash;
class AdminCrudController extends CrudController
{
use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation { store as traitStore; }
use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation { update as traitUpdate; }
use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
public function setup()
{
$this->crud->setModel(config('backpack.permissionmanager.models.user'));
$this->crud->setEntityNameStrings(trans('backpack::permissionmanager.user'), trans('backpack::permissionmanager.users'));
$this->crud->setRoute(backpack_url('admin'));
}
public function setupListOperation()
{
$this->crud->addColumns([
[
'name' => 'name',
'label' => trans('backpack::permissionmanager.name'),
'type' => 'text',
],
[
'name' => 'email',
'label' => trans('backpack::permissionmanager.email'),
'type' => 'email',
],
[ // n-n relationship (with pivot table)
'label' => trans('backpack::permissionmanager.roles'), // Table column heading
'type' => 'select_multiple',
'name' => 'roles', // the method that defines the relationship in your Model
'entity' => 'roles', // the method that defines the relationship in your Model
'attribute' => 'name', // foreign key attribute that is shown to user
'model' => config('permission.models.role'), // foreign key model
],
[ // n-n relationship (with pivot table)
'label' => trans('backpack::permissionmanager.extra_permissions'), // Table column heading
'type' => 'select_multiple',
'name' => 'permissions', // the method that defines the relationship in your Model
'entity' => 'permissions', // the method that defines the relationship in your Model
'attribute' => 'name', // foreign key attribute that is shown to user
'model' => config('permission.models.permission'), // foreign key model
],
]);
// Role Filter
$this->crud->addFilter(
[
'name' => 'role',
'type' => 'dropdown',
'label' => trans('backpack::permissionmanager.role'),
],
config('permission.models.role')::all()->pluck('name', 'id')->toArray(),
function ($value) { // if the filter is active
$this->crud->addClause('whereHas', 'roles', function ($query) use ($value) {
$query->where('role_id', '=', $value);
});
}
);
// Extra Permission Filter
$this->crud->addFilter(
[
'name' => 'permissions',
'type' => 'select2',
'label' => trans('backpack::permissionmanager.extra_permissions'),
],
config('permission.models.permission')::all()->pluck('name', 'id')->toArray(),
function ($value) { // if the filter is active
$this->crud->addClause('whereHas', 'permissions', function ($query) use ($value) {
$query->where('permission_id', '=', $value);
});
}
);
}
public function setupCreateOperation()
{
$this->addUserFields();
$this->crud->setValidation(StoreRequest::class);
}
public function setupUpdateOperation()
{
$this->addUserFields();
$this->crud->setValidation(UpdateRequest::class);
}
/**
* Store a newly created resource in the database.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function store()
{
$this->crud->setRequest($this->crud->validateRequest());
$this->crud->setRequest($this->handlePasswordInput($this->crud->getRequest()));
$this->crud->unsetValidation(); // validation has already been run
return $this->traitStore();
}
/**
* Update the specified resource in the database.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function update()
{
$this->crud->setRequest($this->crud->validateRequest());
$this->crud->setRequest($this->handlePasswordInput($this->crud->getRequest()));
$this->crud->unsetValidation(); // validation has already been run
return $this->traitUpdate();
}
/**
* Handle password input fields.
*/
protected function handlePasswordInput($request)
{
// Remove fields not present on the user.
$request->request->remove('password_confirmation');
$request->request->remove('roles_show');
$request->request->remove('permissions_show');
// Encrypt password if specified.
if ($request->input('password')) {
$request->request->set('password', Hash::make($request->input('password')));
} else {
$request->request->remove('password');
}
return $request;
}
protected function addUserFields()
{
$this->crud->addFields([
[
'name' => 'name',
'label' => trans('backpack::permissionmanager.name'),
'type' => 'text',
],
[
'name' => 'email',
'label' => trans('backpack::permissionmanager.email'),
'type' => 'email',
],
[
'name' => 'password',
'label' => trans('backpack::permissionmanager.password'),
'type' => 'password',
],
[
'name' => 'password_confirmation',
'label' => trans('backpack::permissionmanager.password_confirmation'),
'type' => 'password',
],
[
// two interconnected entities
'label' => trans('backpack::permissionmanager.user_role_permission'),
'field_unique_name' => 'user_role_permission',
'type' => 'checklist_dependency',
'name' => ['roles', 'permissions'],
'subfields' => [
'primary' => [
'label' => trans('backpack::permissionmanager.roles'),
'name' => 'roles', // the method that defines the relationship in your Model
'entity' => 'roles', // the method that defines the relationship in your Model
'entity_secondary' => 'permissions', // the method that defines the relationship in your Model
'attribute' => 'name', // foreign key attribute that is shown to user
'model' => config('permission.models.role'), // foreign key model
'pivot' => true, // on create&update, do you need to add/delete pivot table entries?]
'number_columns' => 3, //can be 1,2,3,4,6
],
'secondary' => [
'label' => ucfirst(trans('backpack::permissionmanager.permission_singular')),
'name' => 'permissions', // the method that defines the relationship in your Model
'entity' => 'permissions', // the method that defines the relationship in your Model
'entity_primary' => 'roles', // the method that defines the relationship in your Model
'attribute' => 'name', // foreign key attribute that is shown to user
'model' => config('permission.models.permission'), // foreign key model
'pivot' => true, // on create&update, do you need to add/delete pivot table entries?]
'number_columns' => 3, //can be 1,2,3,4,6
],
],
],
]);
}
}
<?php
// --------------------------
// Custom Backpack Routes
// --------------------------
// This route file is loaded automatically by Backpack\Base.
// Routes you generate using Backpack\Generators will be placed here.
Route::group([
'prefix' => config('backpack.base.route_prefix', 'admin'),
'middleware' => array_merge(
(array) config('backpack.base.web_middleware', 'web'),
(array) config('backpack.base.middleware_key', 'admin')
),
'namespace' => 'App\Http\Controllers\Admin',
], function () { // custom admin routes
Route::crud('admin', 'AdminCrudController');
}); // this should be the absolute last line of this file
<?php
namespace App;
trait PageTemplates
{
/*
|--------------------------------------------------------------------------
| Page Templates for Backpack\PageManager
|--------------------------------------------------------------------------
|
| Each page template has its own method, that define what fields should show up using the Backpack\CRUD API.
| Use snake_case for naming and PageManager will make sure it looks pretty in the create/update form
| template dropdown.
|
| Any fields defined here will show up after the standard page fields:
| - select template
| - page name (only seen by admins)
| - page title
| - page slug
*/
private function services()
{
$this->crud->addField([ // CustomHTML
'name' => 'metas_separator',
'type' => 'custom_html',
'value' => '<br><h2>'.trans('backpack::pagemanager.metas').'</h2><hr>',
]);
$this->crud->addField([
'name' => 'meta_title',
'label' => trans('backpack::pagemanager.meta_title'),
'fake' => true,
'store_in' => 'extras',
]);
$this->crud->addField([
'name' => 'meta_description',
'label' => trans('backpack::pagemanager.meta_description'),
'fake' => true,
'store_in' => 'extras',
]);
$this->crud->addField([
'name' => 'meta_keywords',
'type' => 'textarea',
'label' => trans('backpack::pagemanager.meta_keywords'),
'fake' => true,
'store_in' => 'extras',
]);
$this->crud->addField([ // CustomHTML
'name' => 'content_separator',
'type' => 'custom_html',
'value' => '<br><h2>'.trans('backpack::pagemanager.content').'</h2><hr>',
]);
$this->crud->addField([
'name' => 'content',
'label' => trans('backpack::pagemanager.content'),
'type' => 'wysiwyg',
'placeholder' => trans('backpack::pagemanager.content_placeholder'),
]);
}
private function about_us()
{
$this->crud->addField([
'name' => 'content',
'label' => trans('backpack::pagemanager.content'),
'type' => 'wysiwyg',
'placeholder' => trans('backpack::pagemanager.content_placeholder'),
]);
}
}
<?php
return [
/*
|--------------------------------------------------------------------------
| Models
|--------------------------------------------------------------------------
|
| Models used in the User, Role and Permission CRUDs.
|
*/
'models' => [
'user' => config('backpack.base.user_model_fqn', \App\Models\Admin::class),
'permission' => Backpack\PermissionManager\app\Models\Permission::class,
'role' => Backpack\PermissionManager\app\Models\Role::class,
],
/*
|--------------------------------------------------------------------------
| Disallow the user interface for creating/updating permissions or roles.
|--------------------------------------------------------------------------
| Roles and permissions are used in code by their name
| - ex: $user->hasPermissionTo('edit articles');
|
| So after the developer has entered all permissions and roles, the administrator should either:
| - not have access to the panels
| or
| - creating and updating should be disabled
*/
'allow_permission_create' => true,
'allow_permission_update' => true,
'allow_permission_delete' => true,
'allow_role_create' => true,
'allow_role_update' => true,
'allow_role_delete' => true,
/*
|--------------------------------------------------------------------------
| Multiple-guards functionality
|--------------------------------------------------------------------------
|
*/
'multiple_guards' => true,
];
<?php
return [
/*
|--------------------------------------------------------------------------
| Permission Manager Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used for Laravel Backpack - Permission Manager
| Author: Lúdio Oliveira <ludio.ao@gmail.com>
|
*/
'name' => 'Name',
'role' => 'Role',
'roles' => 'Roles',
'roles_have_permission' => 'Roles that have this permission',
'permission_singular' => 'Permission',
'permission_plural' => 'Permissions',
'user_singular' => 'Admin',
'user_plural' => 'Admins',
'email' => 'Email',
'extra_permissions' => 'Extra Permissions',
'password' => 'Password',
'password_confirmation' => 'Password Confirmation',
'user_role_permission' => 'Admin Role Permissions',
'user' => 'Admin',
'users' => 'Admins',
'guard_type' => 'Guard Type',
];
<!-- This file is used to store sidebar items, starting with Backpack\Base 0.9.0 -->
<li class="nav-item"><a class="nav-link" href="{{ backpack_url('dashboard') }}"><i class="la la-home nav-icon"></i> {{ trans('backpack::base.dashboard') }}</a></li>
<li class='nav-item'><a class='nav-link' href='{{ backpack_url('page') }}'><i class='nav-icon la la-file-o'></i> <span>Pages</span></a></li>
<li class="nav-item nav-dropdown">
<a class="nav-link nav-dropdown-toggle" href="#"><i class="nav-icon la la-newspaper-o"></i>News</a>
<ul class="nav-dropdown-items">
<li class="nav-item"><a class="nav-link" href="{{ backpack_url('article') }}"><i class="nav-icon la la-newspaper-o"></i> Articles</a></li>
<li class="nav-item"><a class="nav-link" href="{{ backpack_url('category') }}"><i class="nav-icon la la-list"></i> Categories</a></li>
<li class="nav-item"><a class="nav-link" href="{{ backpack_url('tag') }}"><i class="nav-icon la la-tag"></i> Tags</a></li>
</ul>
</li>
<li class='nav-item'><a class='nav-link' href='{{ backpack_url('user') }}'><i class='nav-icon la la-user'></i> Users</a></li>
<!-- Users, Roles, Permissions -->
<li class="nav-item nav-dropdown">
<a class="nav-link nav-dropdown-toggle" href="#"><i class="nav-icon la la-users"></i> Authentication</a>
<ul class="nav-dropdown-items">
<li class="nav-item"><a class="nav-link" href="{{ backpack_url('admin') }}"><i class="nav-icon la la-user"></i> <span>Admins</span></a></li>
<li class="nav-item"><a class="nav-link" href="{{ backpack_url('role') }}"><i class="nav-icon la la-id-badge"></i> <span>Roles</span></a></li>
<li class="nav-item"><a class="nav-link" href="{{ backpack_url('permission') }}"><i class="nav-icon la la-key"></i> <span>Permissions</span></a></li>
</ul>
</li>
<!-- This file is used to store sidebar items, starting with Backpack\Base 0.9.0 -->
<li class="nav-item"><a class="nav-link" href="{{ backpack_url('dashboard') }}"><i class="la la-home nav-icon"></i> {{ trans('backpack::base.dashboard') }}</a></li>
<!-- Users, Roles, Permissions -->
<li class="nav-item nav-dropdown">
<a class="nav-link nav-dropdown-toggle" href="#"><i class="nav-icon la la-users"></i> Authentication</a>
<ul class="nav-dropdown-items">
<li class="nav-item"><a class="nav-link" href="{{ backpack_url('admin') }}"><i class="nav-icon la la-user"></i> <span>Admins</span></a></li>
<li class="nav-item"><a class="nav-link" href="{{ backpack_url('role') }}"><i class="nav-icon la la-id-badge"></i> <span>Roles</span></a></li>
<li class="nav-item"><a class="nav-link" href="{{ backpack_url('permission') }}"><i class="nav-icon la la-key"></i> <span>Permissions</span></a></li>
</ul>
</li>
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Requests\UserStoreCrudRequest as StoreRequest;
use App\Http\Requests\UserUpdateCrudRequest as UpdateRequest;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
use Illuminate\Support\Facades\Hash;
/**
* Class UserCrudController
* @package App\Http\Controllers\Admin
* @property-read \Backpack\CRUD\app\Library\CrudPanel\CrudPanel $crud
*/
class UserCrudController extends CrudController
{
use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation { store as traitStore; }
use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation { update as traitUpdate; }
use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;
/**
* Configure the CrudPanel object. Apply settings to all operations.
*
* @return void
*/
public function setup()
{
CRUD::setModel(\App\Models\User::class);
CRUD::setRoute(config('backpack.base.route_prefix') . '/user');
CRUD::setEntityNameStrings('user', 'users');
}
/**
* Define what happens when the List operation is loaded.
*
* @see https://backpackforlaravel.com/docs/crud-operation-list-entries
* @return void
*/
protected function setupListOperation()
{
CRUD::column('name')->label('Name')->type('text');
CRUD::column('email')->label('Email')->type('email');
}
/**
* Define what happens when the Create operation is loaded.
*
* @see https://backpackforlaravel.com/docs/crud-operation-create
* @return void
*/
protected function setupCreateOperation()
{
$this->addUserFields();
CRUD::setValidation(StoreRequest::class);
}
/**
* Store a newly created resource in the database.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function store()
{
$this->crud->setRequest($this->crud->validateRequest());
$this->crud->setRequest($this->handlePasswordInput($this->crud->getRequest()));
$this->crud->unsetValidation(); // validation has already been run
return $this->traitStore();
}
/**
* Define what happens when the Update operation is loaded.
*
* @see https://backpackforlaravel.com/docs/crud-operation-update
* @return void
*/
protected function setupUpdateOperation()
{
$this->addUserFields();
CRUD::setValidation(UpdateRequest::class);
}
/**
* Update the specified resource in the database.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function update()
{
$this->crud->setRequest($this->crud->validateRequest());
$this->crud->setRequest($this->handlePasswordInput($this->crud->getRequest()));
$this->crud->unsetValidation(); // validation has already been run
return $this->traitUpdate();
}
/**
* User Create/Update Form
*/
protected function addUserFields()
{
CRUD::field('name')->label('Name')->type('text');
CRUD::field('email')->label('Email')->type('email');
CRUD::field('password')->label('Password')->type('password');
CRUD::field('password_confirmation')->label('Password Confirmation')->type('password');
}
/**
* Handle password input fields.
*/
protected function handlePasswordInput($request)
{
// Remove fields not present on the user.
$request->request->remove('password_confirmation');
// Encrypt password if specified.
if ($request->input('password')) {
$request->request->set('password', Hash::make($request->input('password')));
} else {
$request->request->remove('password');
}
return $request;
}
}
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Foundation\Http\FormRequest;
class UserStoreCrudRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
// only allow updates if the user is logged in
return backpack_auth()->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'email' => 'required|unique:users,email',
'name' => 'required',
'password' => 'required|confirmed',
];
}
/**
* Get the validation attributes that apply to the request.
*
* @return array
*/
public function attributes()
{
return [
//
];
}
/**
* Get the validation messages that apply to the request.
*
* @return array
*/
public function messages()
{
return [
//
];
}
}
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Foundation\Http\FormRequest;
class UserUpdateCrudRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
// only allow updates if the user is logged in
return backpack_auth()->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$id = $this->get('id') ?? request()->route('id');
return [
'email' => 'required|unique:users,email,'.$id,
'name' => 'required',
'password' => 'confirmed',
];
}
/**
* Get the validation attributes that apply to the request.
*
* @return array
*/
public function attributes()
{
return [
//
];
}
/**
* Get the validation messages that apply to the request.
*
* @return array
*/
public function messages()
{
return [
//
];
}
}
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware(['auth'])->name('dashboard');
require __DIR__.'/auth.php';
/*
|--------------------------------------------------------------------------
| Overriding Backpack Routes
|--------------------------------------------------------------------------
| Routes you want to override the default Backpack vendor files.
|
*/
Route::group([
'prefix' => config('backpack.base.route_prefix', 'admin'),
'middleware' => array_merge(
(array) config('backpack.base.web_middleware', 'web'),
(array) config('backpack.base.middleware_key', 'admin')
),
'namespace' => 'App\Http\Controllers\Admin',
], function () { // custom admin routes
Route::crud('user', 'UserCrudController');
}); // this should be the absolute last line of this file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment