Browse Source

Add user role for admin and worker

pull/1/head
Nafies Luthfi 8 years ago
parent
commit
7cd46bb676
  1. 36
      app/Entities/Users/Role.php
  2. 101
      app/Entities/Users/User.php
  3. 21
      app/Entities/Users/UserRole.php
  4. 35
      app/Http/Controllers/Users/UsersController.php
  5. 37
      database/migrations/2017_10_28_170121_create_agencies_table.php
  6. 33
      database/migrations/2017_11_14_061927_create_user_roles_table.php
  7. 26
      resources/lang/id/user.php
  8. 6
      resources/views/users/create.blade.php
  9. 6
      resources/views/users/edit.blade.php
  10. 2
      resources/views/users/index.blade.php
  11. 1
      resources/views/users/show.blade.php
  12. 58
      tests/Feature/Users/ManageUsersTest.php
  13. 74
      tests/Unit/Models/UserTest.php

36
app/Entities/Users/Role.php

@ -0,0 +1,36 @@
<?php
namespace App\Entities\Users;
use App\Entities\ReferenceAbstract;
/**
* Role Class
*/
class Role extends ReferenceAbstract
{
protected static $lists = [
1 => 'admin',
2 => 'worker',
];
public static function getNameById($roleId)
{
return trans('user.roles.'.static::$lists[$roleId]);
}
public static function getIdByName($roleName)
{
return array_search($roleName, static::$lists);
}
public static function toArray()
{
$lists = [];
foreach (static::$lists as $key => $value) {
$lists[$key] = trans('user.roles.'.$value);
}
return $lists;
}
}

101
app/Entities/Users/User.php

@ -10,7 +10,7 @@ class User extends Authenticatable
use Notifiable;
protected $fillable = ['name', 'email', 'password', 'api_token'];
protected $hidden = ['password', 'remember_token', 'api_token'];
protected $hidden = ['password', 'remember_token', 'api_token'];
public function setPasswordAttribute($value)
{
@ -21,4 +21,103 @@ class User extends Authenticatable
{
return link_to_route('users.show', $this->name, [$this->id], ['target' => '_blank']);
}
/**
* A user may have multiple roles.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function roles()
{
return $this->hasMany(UserRole::class);
}
/**
* Assign the given role to the user.
*
* @param string $role
* @return void
*/
public function assignRole(string $roleName)
{
$roleId = Role::getIdByName($roleName);
UserRole::create([
'user_id' => $this->id,
'role_id' => $roleId,
]);
}
/**
* Remove the given role from the user.
*
* @param string $role
* @return void
*/
public function removeRole(string $roleName)
{
$roleId = Role::getIdByName($roleName);
\DB::table('user_roles')->where([
'user_id' => $this->id,
'role_id' => $roleId,
])->delete();
}
/**
* Determine if the user has the given role.
*
* @param string $role
* @return boolean
*/
public function hasRole(string $roleName)
{
$roleId = Role::getIdByName($roleName);
return $this->roles->contains('role_id', $roleId);
}
/**
* Determine if the user has the given array of role.
*
* @param array $role
* @return boolean
*/
public function hasRoles(array $roleNameArray)
{
return $this->roles->pluck('role_id')
->contains(function ($roleId, $key) use ($roleNameArray) {
$roleIds = [];
foreach ($roleNameArray as $roleName) {
$roleIds[] = Role::getIdByName($roleName);
}
return in_array($roleId, $roleIds);
});
}
public function scopeHasRoles($query, array $roleNameArray)
{
return $query->whereHas('roles', function ($q) use ($roleNameArray) {
$roleIds = [];
foreach ($roleNameArray as $roleName) {
$roleIds[] = Role::getIdByName($roleName);
}
$q->whereIn('role_id', $roleIds);
});
}
public function roleList()
{
$roleList = '<ul>';
foreach ($this->roles as $role) {
$roleList .= '<li>'.$role->name.'</li>';
}
$roleList .= '</ul>';
return $roleList;
}
}

21
app/Entities/Users/UserRole.php

@ -0,0 +1,21 @@
<?php
namespace App\Entities\Users;
use Illuminate\Database\Eloquent\Model;
/**
* @author Nafies Luthfi <nafiesL@gmail.com>
*/
class UserRole extends Model
{
protected $table = 'user_roles';
public $timestamps = false;
protected $appends = ['name'];
protected $fillable = ['user_id', 'role_id'];
public function getNameAttribute()
{
return Role::getNameById($this->role_id);
}
}

35
app/Http/Controllers/Users/UsersController.php

@ -7,6 +7,8 @@ use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
/**
* Users Controller
*
* @author Nafies Luthfi <nafiesL@gmail.com>
*/
class UsersController extends Controller
@ -15,6 +17,7 @@ class UsersController extends Controller
{
$query = $request->get('q');
$users = User::where('name', 'like', '%'.$query.'%')
->with('roles')
->paginate(25);
return view('users.index', compact('users'));
@ -30,8 +33,8 @@ class UsersController extends Controller
$userData = $request->validate([
'name' => 'required|min:5',
'email' => 'required|email|unique:users,email',
'password' => 'nullable|between:6,15|confirmed',
// 'password_confirmation' => 'required_with:password',
'password' => 'nullable|between:6,15',
'role' => 'required|array',
]);
if (!$userData['password']) {
@ -40,6 +43,15 @@ class UsersController extends Controller
$user = User::create($userData);
$rolesData = array_map(function ($roleId) use ($user) {
return [
'user_id' => $user->id,
'role_id' => $roleId,
];
}, $userData['role']);
\DB::table('user_roles')->insert($rolesData);
flash()->success(trans('user.created'));
return redirect()->route('users.index');
@ -62,14 +74,25 @@ class UsersController extends Controller
$this->authorize('update', $user);
$userData = $request->validate([
'name' => 'required|min:5',
'email' => 'required|email|unique:users,email,'.$request->segment(2),
'password' => 'nullable|required_with:password_confirmation|between:6,15|confirmed',
'password_confirmation' => 'required_with:password',
'name' => 'required|min:5',
'email' => 'required|email|unique:users,email,'.$request->segment(2),
'password' => 'nullable|required_with:password_confirmation|between:6,15',
'role' => 'required|array',
]);
$user->update($userData);
\DB::table('user_roles')->where(['user_id' => $user->id])->delete();
$rolesData = array_map(function ($roleId) use ($user) {
return [
'user_id' => $user->id,
'role_id' => $roleId,
];
}, $userData['role']);
\DB::table('user_roles')->insert($rolesData);
flash()->success(trans('user.updated'));
return redirect()->route('users.edit', $user->id);
}

37
database/migrations/2017_10_28_170121_create_agencies_table.php

@ -1,37 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateAgenciesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('agencies', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('address')->nullable();
$table->string('phone')->nullable();
$table->string('website')->nullable();
$table->unsignedInteger('owner_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('agencies');
}
}

33
database/migrations/2017_11_14_061927_create_user_roles_table.php

@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUserRolesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('user_roles', function (Blueprint $table) {
$table->unsignedInteger('user_id');
$table->unsignedTinyInteger('role_id');
$table->unique(['user_id', 'role_id'], 'user_role_unique');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('user_roles');
}
}

26
resources/lang/id/user.php

@ -14,19 +14,27 @@ return [
'back_to_index' => 'Kembali ke Daftar User',
// Actions
'create' => 'Input User Baru',
'created' => 'Input User baru telah berhasil.',
'show' => 'Detail User',
'edit' => 'Edit Data User',
'update' => 'Update Data User',
'updated' => 'Update data User telah berhasil.',
'delete' => 'Hapus Data User',
'deleted' => 'Hapus data User telah berhasil.',
'undeleted' => 'Data User gagal dihapus.',
'create' => 'Input User Baru',
'created' => 'Input User baru telah berhasil.',
'show' => 'Detail User',
'edit' => 'Edit Data User',
'update' => 'Update Data User',
'updated' => 'Update data User telah berhasil.',
'delete' => 'Hapus Data User',
'deleted' => 'Hapus data User telah berhasil.',
'undeleted' => 'Data User gagal dihapus.',
// Attributes
'name' => 'Nama User',
'email' => 'Alamat Email',
'api_token' => 'API Token',
'registered_at' => 'Terdaftar sejak',
// Roles
'role' => 'Role',
'roles' => [
'admin' => 'Administrator',
'worker' => 'Worker',
],
];

6
resources/views/users/create.blade.php

@ -1,3 +1,4 @@
@inject('roles', 'App\Entities\Users\Role')
@extends('layouts.dashboard')
@section('title', trans('user.create'))
@ -11,6 +12,7 @@
<div class="panel-body">
{!! FormField::text('name', ['label' => trans('app.name')]) !!}
{!! FormField::email('email', ['label' => trans('user.email')]) !!}
{!! FormField::checkboxes('role', $roles::toArray(), ['label' => trans('user.role')]) !!}
{!! FormField::password('password', [
'label' => trans('auth.password'),
@ -19,10 +21,6 @@
'class' => 'info',
],
]) !!}
{!! FormField::password('password_confirmation', [
'label' => trans('auth.password_confirmation')
]) !!}
</div>
<div class="panel-footer">
{!! Form::submit(trans('user.create'), ['class'=>'btn btn-primary']) !!}

6
resources/views/users/edit.blade.php

@ -1,3 +1,4 @@
@inject('roles', 'App\Entities\Users\Role')
@extends('layouts.dashboard')
@section('title', trans('user.edit'))
@ -11,6 +12,7 @@
<div class="panel-body">
{!! FormField::text('name', ['label' => trans('app.name')]) !!}
{!! FormField::email('email', ['label' => trans('user.email')]) !!}
{!! FormField::checkboxes('role', $roles::toArray(), ['label' => trans('user.role')]) !!}
{!! FormField::password('password', [
'label' => trans('auth.password'),
@ -19,10 +21,6 @@
'class' => 'info',
],
]) !!}
{!! FormField::password('password_confirmation', [
'label' => trans('auth.password_confirmation')
]) !!}
</div>
<div class="panel-footer">
{!! Form::submit(trans('user.update'), ['class'=>'btn btn-warning']) !!}

2
resources/views/users/index.blade.php

@ -18,6 +18,7 @@
<th>{{ trans('app.table_no') }}</th>
<th>{{ trans('app.name') }}</th>
<th>{{ trans('user.email') }}</th>
<th>{{ trans('user.role') }}</th>
<th>{{ trans('app.action') }}</th>
</thead>
<tbody>
@ -26,6 +27,7 @@
<td>{{ 1 + $key }}</td>
<td>{{ $user->name }}</td>
<td>{{ $user->email }}</td>
<td>{!! $user->roleList() !!}</td>
<td>
{!! link_to_route('users.show',trans('user.show'),[$user->id],['class'=>'btn btn-info btn-xs']) !!}
</td>

1
resources/views/users/show.blade.php

@ -12,6 +12,7 @@
<tbody>
<tr><th>{{ trans('app.name') }}</th><td>{{ $user->name }}</td></tr>
<tr><th>{{ trans('user.email') }}</th><td>{{ $user->email }}</td></tr>
<tr><th>{{ trans('user.role') }}</th><td>{!! $user->roleList() !!}</td></tr>
<tr><th>{{ trans('user.registered_at') }}</th><td>{{ $user->created_at }}</td></tr>
</tbody>
</table>

58
tests/Feature/Users/ManageUsersTest.php

@ -35,10 +35,10 @@ class ManageUsersTest extends TestCase
$this->seePageIs(route('users.create'));
$this->submitForm(trans('user.create'), [
'name' => 'Nama User',
'email' => 'user@mail.com',
'password' => 'password',
'password_confirmation' => 'password',
'name' => 'Nama User',
'email' => 'user@mail.com',
'password' => 'password',
'role' => [1, 2], // Administrator, Worker
]);
$this->seePageIs(route('users.index'));
@ -46,10 +46,30 @@ class ManageUsersTest extends TestCase
$this->see('Nama User');
$this->see('user@mail.com');
$this->seeInDatabase('users', [
'name' => 'Nama User',
'email' => 'user@mail.com',
]);
$newUser = User::where('email', 'user@mail.com')->first();
$this->assertEquals('Nama User', $newUser->name);
$this->assertTrue($newUser->hasRoles(['admin', 'worker']));
$this->assertTrue($newUser->hasRole('admin'));
$this->assertTrue($newUser->hasRole('worker'));
// $this->seeInDatabase('users', [
// 'id' => $newUser->id,
// 'name' => 'Nama User',
// 'email' => 'user@mail.com',
// ]);
// $this->seeInDatabase('user_roles', [
// 'user_id' => $newUser->id,
// 'role_id' => 1,
// ]);
// $this->seeInDatabase('user_roles', [
// 'user_id' => $newUser->id,
// 'role_id' => 2,
// ]);
}
/** @test */
@ -57,24 +77,36 @@ class ManageUsersTest extends TestCase
{
$admin = $this->adminUserSigningIn();
$user2 = factory(User::class)->create();
$user2->assignRole('worker');
$this->visit(route('users.edit', $user2->id));
$this->type('Ganti nama User', 'name');
$this->type('member@mail.dev', 'email');
$this->press(trans('user.update'));
$this->submitForm(trans('user.update'), [
'name' => 'Ganti nama User',
'email' => 'member@mail.dev',
'password' => 'password',
'role' => [1, 2], // Administrator, Worker
]);
$this->seePageIs(route('users.edit', $user2->id));
$this->see(trans('user.updated'));
$this->see('Ganti nama User');
$this->see('member@mail.dev');
$this->seeInDatabase('users', [
'id' => $user2->id,
'name' => 'Ganti nama User',
'email' => 'member@mail.dev',
]);
$this->seeInDatabase('user_roles', [
'user_id' => $user2->id,
'role_id' => 1,
]);
$this->seeInDatabase('user_roles', [
'user_id' => $user2->id,
'role_id' => 2,
]);
}
/** @test */

74
tests/Unit/Models/UserTest.php

@ -5,6 +5,11 @@ namespace Tests\Unit\Models;
use App\Entities\Users\User;
use Tests\TestCase;
/**
* User Model Unit Test
*
* @author Nafies Luthfi <nafiesL@gmail.com>
*/
class UserTest extends TestCase
{
/** @test */
@ -16,4 +21,73 @@ class UserTest extends TestCase
'target' => '_blank',
]), $user->nameLink());
}
/** @test */
public function user_can_assigned_to_a_role()
{
$user = factory(User::class)->create();
$user->assignRole('admin');
$this->assertTrue($user->hasRole('admin'));
}
/** @test */
public function user_has_many_roles()
{
$user = factory(User::class)->create();
$user->assignRole('admin');
$user->assignRole('worker');
$this->assertTrue($user->hasRoles(['admin', 'worker']));
$this->assertEquals([
[
'user_id' => $user->id,
'role_id' => 1,
'name' => trans('user.roles.admin'),
],
[
'user_id' => $user->id,
'role_id' => 2,
'name' => trans('user.roles.worker'),
],
], $user->roles->toArray());
}
/** @test */
public function user_can_be_removed_from_a_role()
{
$user = factory(User::class)->create();
$user->assignRole('admin');
$user->assignRole('worker');
$this->assertTrue($user->hasRoles(['admin', 'worker']));
$user->removeRole('worker');
$this->assertFalse($user->fresh()->hasRole('worker'));
}
/** @test */
public function user_can_queried_by_roles()
{
$user = factory(User::class)->create();
$user->assignRole('worker');
$this->assertCount(1, User::orderBy('name')->hasRoles(['worker'])->get());
}
/** @test */
public function user_has_role_list_method()
{
$user = factory(User::class)->create();
$user->assignRole('admin');
$user->assignRole('worker');
$roleList = '<ul>';
$roleList .= '<li>'.trans('user.roles.admin').'</li>';
$roleList .= '<li>'.trans('user.roles.worker').'</li>';
$roleList .= '</ul>';
$this->assertEquals($roleList, $user->roleList());
}
}
Loading…
Cancel
Save