Simplified implementation of user roles for Laravel applications: User has role_id field, and corresponding roles lookup table exists.
Install the saritasa/roles-simple
package:
$ composer require saritasa/roles-simple
If you use Laravel 5.4 or less,
or 5.5+ with package discovery disabled,
add the RolesServiceProvider service provider in config/app.php
:
'providers' => array(
// ...
Saritasa\Roles\RolesServiceProvider::class,
)
Then publish DB migrations:
php artisan vendor:publish --provider=Saritasa\\Roles\\RolesServiceProvider
Provides hasRole method;
Example:
class User extends Model implements IHasRoles
{
uses HasRoles
}
then somewere in code:
if ($user->hasRole(Roles::ADMIN)) { ... }}
$user->role->name;
hasRole($role) method can accept either role ID (integer) or role slug (string). Using role ID is a bit faster, because does not require reading role record from lookup table.
You can use built-in class Saritasa\Roles\Models\Role to list of models or create new roles in migrations or in code.
Role model contains 3 fields:
- id (integer) - primary key
- name (string) - supposed to be visible to user and may change, as needed. May contain any characters (including spaces), in any case. Do not use role name as identifier (ex. to search by it).
- slug (string) - human-readable role identifier, supposed to be constant, while name can be changed. You can reference role by slug in code (ex. in hasRole() method). It's recommended to keep slugs in lowercase, use underscore or dash instead of spaces.
class AddRoles extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Role::firstOrCreate(['name' => 'User', 'slug' => 'user']);
Role::firstOrCreate(['name' => 'Admin', 'slug' => 'admin']);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Role::whereSlug('user')->delete();
Role::whereSlug('admin')->delete();
}
}
Package contains enum Saritasa\Roles\Enums\Roles, which has 2 predefined roles: User and Admin, which is suitable for many applications.
But you are not limited to these roles, you can define your own enum (extending this one or create new from scratch) and use it.
class Roles extends Enum
{
const USER = 1;
const SUPER_ADMIN = 2;
const SCHOOL_ADMIN = 3;
}
You can use middleware in routes to limit access to certain pages:
Router::get('/admin', [
'as' => 'admin.dashboard',
'middlware' => 'role:admin'
]
Middleware with alias is registered by service provider, no need to register it manually.
Format is role:role_slug1,role_slug2,role_slug3.
If user does not have any of required roles, AccessDeniedHttpException will be thrown
- Create fork, checkout it
- Develop locally as usual. Code must follow PSR-1, PSR-2 - run PHP_CodeSniffer to ensure, that code follows style guides
- Cover added functionality with unit tests and run PHPUnit to make sure, that all tests pass
- Update README.md to describe new or changed functionality
- Add changes description to CHANGES.md file. Use Semantic Versioning convention to determine next version number.
- When ready, create pull request
If you have GNU Make installed, you can use following shortcuts:
make cs
(instead ofphp vendor/bin/phpcs
) - run static code analysis with PHP_CodeSniffer to check code stylemake csfix
(instead ofphp vendor/bin/phpcbf
) - fix code style violations with PHP_CodeSniffer automatically, where possible (ex. PSR-2 code formatting violations)make test
(instead ofphp vendor/bin/phpunit
) - run tests with PHPUnitmake install
- instead ofcomposer install
make all
or justmake
without parameters - invokes described above install, cs, test tasks sequentially - project will be assembled, checked with linter and tested with one single command