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. 99
      app/Entities/Users/User.php
  3. 21
      app/Entities/Users/UserRole.php
  4. 31
      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. 8
      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. 52
      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;
}
}

99
app/Entities/Users/User.php

@ -21,4 +21,103 @@ class User extends Authenticatable
{ {
return link_to_route('users.show', $this->name, [$this->id], ['target' => '_blank']); 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);
}
}

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

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

8
resources/lang/id/user.php

@ -29,4 +29,12 @@ return [
'email' => 'Alamat Email', 'email' => 'Alamat Email',
'api_token' => 'API Token', 'api_token' => 'API Token',
'registered_at' => 'Terdaftar sejak', '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') @extends('layouts.dashboard')
@section('title', trans('user.create')) @section('title', trans('user.create'))
@ -11,6 +12,7 @@
<div class="panel-body"> <div class="panel-body">
{!! FormField::text('name', ['label' => trans('app.name')]) !!} {!! FormField::text('name', ['label' => trans('app.name')]) !!}
{!! FormField::email('email', ['label' => trans('user.email')]) !!} {!! FormField::email('email', ['label' => trans('user.email')]) !!}
{!! FormField::checkboxes('role', $roles::toArray(), ['label' => trans('user.role')]) !!}
{!! FormField::password('password', [ {!! FormField::password('password', [
'label' => trans('auth.password'), 'label' => trans('auth.password'),
@ -19,10 +21,6 @@
'class' => 'info', 'class' => 'info',
], ],
]) !!} ]) !!}
{!! FormField::password('password_confirmation', [
'label' => trans('auth.password_confirmation')
]) !!}
</div> </div>
<div class="panel-footer"> <div class="panel-footer">
{!! Form::submit(trans('user.create'), ['class'=>'btn btn-primary']) !!} {!! 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') @extends('layouts.dashboard')
@section('title', trans('user.edit')) @section('title', trans('user.edit'))
@ -11,6 +12,7 @@
<div class="panel-body"> <div class="panel-body">
{!! FormField::text('name', ['label' => trans('app.name')]) !!} {!! FormField::text('name', ['label' => trans('app.name')]) !!}
{!! FormField::email('email', ['label' => trans('user.email')]) !!} {!! FormField::email('email', ['label' => trans('user.email')]) !!}
{!! FormField::checkboxes('role', $roles::toArray(), ['label' => trans('user.role')]) !!}
{!! FormField::password('password', [ {!! FormField::password('password', [
'label' => trans('auth.password'), 'label' => trans('auth.password'),
@ -19,10 +21,6 @@
'class' => 'info', 'class' => 'info',
], ],
]) !!} ]) !!}
{!! FormField::password('password_confirmation', [
'label' => trans('auth.password_confirmation')
]) !!}
</div> </div>
<div class="panel-footer"> <div class="panel-footer">
{!! Form::submit(trans('user.update'), ['class'=>'btn btn-warning']) !!} {!! 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.table_no') }}</th>
<th>{{ trans('app.name') }}</th> <th>{{ trans('app.name') }}</th>
<th>{{ trans('user.email') }}</th> <th>{{ trans('user.email') }}</th>
<th>{{ trans('user.role') }}</th>
<th>{{ trans('app.action') }}</th> <th>{{ trans('app.action') }}</th>
</thead> </thead>
<tbody> <tbody>
@ -26,6 +27,7 @@
<td>{{ 1 + $key }}</td> <td>{{ 1 + $key }}</td>
<td>{{ $user->name }}</td> <td>{{ $user->name }}</td>
<td>{{ $user->email }}</td> <td>{{ $user->email }}</td>
<td>{!! $user->roleList() !!}</td>
<td> <td>
{!! link_to_route('users.show',trans('user.show'),[$user->id],['class'=>'btn btn-info btn-xs']) !!} {!! link_to_route('users.show',trans('user.show'),[$user->id],['class'=>'btn btn-info btn-xs']) !!}
</td> </td>

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

@ -12,6 +12,7 @@
<tbody> <tbody>
<tr><th>{{ trans('app.name') }}</th><td>{{ $user->name }}</td></tr> <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.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> <tr><th>{{ trans('user.registered_at') }}</th><td>{{ $user->created_at }}</td></tr>
</tbody> </tbody>
</table> </table>

52
tests/Feature/Users/ManageUsersTest.php

@ -38,7 +38,7 @@ class ManageUsersTest extends TestCase
'name' => 'Nama User', 'name' => 'Nama User',
'email' => 'user@mail.com', 'email' => 'user@mail.com',
'password' => 'password', 'password' => 'password',
'password_confirmation' => 'password',
'role' => [1, 2], // Administrator, Worker
]); ]);
$this->seePageIs(route('users.index')); $this->seePageIs(route('users.index'));
@ -46,10 +46,30 @@ class ManageUsersTest extends TestCase
$this->see('Nama User'); $this->see('Nama User');
$this->see('user@mail.com'); $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 */ /** @test */
@ -57,24 +77,36 @@ class ManageUsersTest extends TestCase
{ {
$admin = $this->adminUserSigningIn(); $admin = $this->adminUserSigningIn();
$user2 = factory(User::class)->create(); $user2 = factory(User::class)->create();
$user2->assignRole('worker');
$this->visit(route('users.edit', $user2->id)); $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->seePageIs(route('users.edit', $user2->id));
$this->see(trans('user.updated')); $this->see(trans('user.updated'));
$this->see('Ganti nama User');
$this->see('member@mail.dev');
$this->seeInDatabase('users', [ $this->seeInDatabase('users', [
'id' => $user2->id, 'id' => $user2->id,
'name' => 'Ganti nama User', 'name' => 'Ganti nama User',
'email' => 'member@mail.dev', '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 */ /** @test */

74
tests/Unit/Models/UserTest.php

@ -5,6 +5,11 @@ namespace Tests\Unit\Models;
use App\Entities\Users\User; use App\Entities\Users\User;
use Tests\TestCase; use Tests\TestCase;
/**
* User Model Unit Test
*
* @author Nafies Luthfi <nafiesL@gmail.com>
*/
class UserTest extends TestCase class UserTest extends TestCase
{ {
/** @test */ /** @test */
@ -16,4 +21,73 @@ class UserTest extends TestCase
'target' => '_blank', 'target' => '_blank',
]), $user->nameLink()); ]), $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