#3: Users can now be assigned to groups

This commit is contained in:
Andy Heathershaw 2017-02-14 11:03:58 +00:00
parent f70a80ca19
commit 4e2e66f2f2
6 changed files with 179 additions and 74 deletions

View File

@ -4,6 +4,7 @@ namespace App\Http\Controllers\Admin;
use App\Facade\Theme; use App\Facade\Theme;
use App\Facade\UserConfig; use App\Facade\UserConfig;
use App\Group;
use App\User; use App\User;
use App\Http\Requests; use App\Http\Requests;
@ -119,7 +120,14 @@ class UserController extends Controller
App::abort(404); App::abort(404);
} }
return Theme::render('admin.edit_user', ['user' => $user]); $groups = Group::orderBy('name')->get();
$usersGroups = [];
foreach ($user->groups()->get() as $group)
{
$usersGroups[] = $group->id;
}
return Theme::render('admin.edit_user', ['user' => $user, 'groups' => $groups, 'users_groups' => $usersGroups]);
} }
/** /**
@ -167,6 +175,24 @@ class UserController extends Controller
$user->activation_token = null; $user->activation_token = null;
} }
// Sync the group memberships
$data = $request->all();
$syncData = [];
if (isset($data['user_group_id']))
{
foreach ($data['user_group_id'] as $groupID)
{
$syncData[$groupID] = ['created_at' => new \DateTime(), 'updated_at' => new \DateTime()];
}
$user->groups()->sync($syncData);
}
else
{
$user->groups()->detach();
}
$user->save(); $user->save();
return redirect(route('users.index')); return redirect(route('users.index'));

View File

@ -40,4 +40,9 @@ class User extends Authenticatable
return $user; return $user;
} }
public function groups()
{
return $this->belongsToMany(Group::class, 'user_groups');
}
} }

View File

@ -0,0 +1,40 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUserGroupsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('user_groups', function ($table) {
$table->unsignedInteger('user_id');
$table->unsignedInteger('group_id');
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
$table->foreign('group_id')
->references('id')->on('groups')
->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('user_groups');
}
}

View File

@ -24,7 +24,7 @@ $ignoredFiles = [
]; ];
echo 'Blue Twilight Packaging Script' . PHP_EOL; echo 'Blue Twilight Packaging Script' . PHP_EOL;
echo '(c) Andy Heathershaw 2016' . PHP_EOL; echo '(c) Andy Heathershaw 2016-2017' . PHP_EOL;
echo '------------------------------' . PHP_EOL . PHP_EOL; echo '------------------------------' . PHP_EOL . PHP_EOL;
if ($argc != 2) if ($argc != 2)
@ -34,7 +34,7 @@ if ($argc != 2)
} }
echo 'Checking current folder...' . PHP_EOL . PHP_EOL; echo 'Checking current folder...' . PHP_EOL . PHP_EOL;
$appRoot = __DIR__; $appRoot = dirname(dirname(__DIR__));
if (getcwd() != $appRoot) if (getcwd() != $appRoot)
{ {
echo sprintf('The build script must be run in the application root - %s', $appRoot) . PHP_EOL; echo sprintf('The build script must be run in the application root - %s', $appRoot) . PHP_EOL;
@ -45,7 +45,7 @@ echo 'Updating app.version config value...' . PHP_EOL . PHP_EOL;
$appConfigFile = sprintf('%s/config/app.php', $appRoot); $appConfigFile = sprintf('%s/config/app.php', $appRoot);
file_put_contents($appConfigFile, str_replace('**DEV**', $argv[1], file_get_contents($appConfigFile))); file_put_contents($appConfigFile, str_replace('**DEV**', $argv[1], file_get_contents($appConfigFile)));
echo 'Downloading Composer...' . PHP_EOL . PHP_EOL; /*echo 'Downloading Composer...' . PHP_EOL . PHP_EOL;
copy('https://getcomposer.org/installer', 'composer-setup.php'); copy('https://getcomposer.org/installer', 'composer-setup.php');
if (hash_file('SHA384', 'composer-setup.php') === trim(file_get_contents('https://composer.github.io/installer.sig'))) { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); exit; } echo PHP_EOL; if (hash_file('SHA384', 'composer-setup.php') === trim(file_get_contents('https://composer.github.io/installer.sig'))) { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); exit; } echo PHP_EOL;
@ -66,7 +66,7 @@ $sgCommand = sprintf(
PROJECT_ID, PROJECT_ID,
PROJECT_KEY PROJECT_KEY
); );
system($sgCommand); system($sgCommand);*/
echo 'Creating the release archive...' . PHP_EOL . PHP_EOL; echo 'Creating the release archive...' . PHP_EOL . PHP_EOL;

View File

@ -160,6 +160,9 @@ return [
'upload_single_file_text2' => 'Your web server is configured to allow files up to :file_size. If you browser does not support HTML 5 (most modern browsers do), the combined size of all selected files must be less than :max_upload_size.', 'upload_single_file_text2' => 'Your web server is configured to allow files up to :file_size. If you browser does not support HTML 5 (most modern browsers do), the combined size of all selected files must be less than :max_upload_size.',
'user_deletion_failed' => 'An error occurred while removing :name\'s user account: :error_message', 'user_deletion_failed' => 'An error occurred while removing :name\'s user account: :error_message',
'user_deletion_successful' => 'The user account for :name was removed successfully.', 'user_deletion_successful' => 'The user account for :name was removed successfully.',
'user_details_tab' => 'Details',
'user_groups_list_select' => 'Select the group(s) this user will belong to. :name will then inherit all permissions from these groups.',
'user_groups_tab' => 'Groups',
'user_pending' => 'Pending activation', 'user_pending' => 'Pending activation',
'users_title' => 'User accounts', 'users_title' => 'User accounts',
'visitor_analytics_heading' => 'Visitor analytics', 'visitor_analytics_heading' => 'Visitor analytics',

View File

@ -23,82 +23,113 @@
<hr/> <hr/>
{!! Form::model($user, ['route' => ['users.update', $user->id], 'method' => 'PUT']) !!} {!! Form::model($user, ['route' => ['users.update', $user->id], 'method' => 'PUT']) !!}
<div class="row"> <div>
<div class="col-sm-6"> {{-- Nav tabs --}}
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}"> <ul class="nav nav-tabs" role="tablist">
{!! Form::label('name', trans('forms.name_label'), ['class' => 'control-label']) !!} <li role="presentation" class="active"><a href="#details-tab" aria-controls="details-tab" role="tab" data-toggle="tab"><i class="fa fa-fw fa-info-circle"></i> @lang('admin.user_details_tab')</a></li>
{!! Form::text('name', old('name'), ['class' => 'form-control']) !!} <li role="presentation"><a href="#groups-tab" aria-controls="groups-tab" role="tab" data-toggle="tab"><i class="fa fa-fw fa-users"></i> @lang('admin.user_groups_tab')</a></li>
</ul>
@if ($errors->has('name')) {{-- Tab panes --}}
<span class="help-block"> <div class="tab-content">
<strong>{{ $errors->first('name') }}</strong> {{-- Details --}}
</span> <div role="tabpanel" class="tab-pane active" id="details-tab">
<div class="row">
<div class="col-sm-6">
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
{!! Form::label('name', trans('forms.name_label'), ['class' => 'control-label']) !!}
{!! Form::text('name', old('name'), ['class' => 'form-control']) !!}
@if ($errors->has('name'))
<span class="help-block">
<strong>{{ $errors->first('name') }}</strong>
</span>
@endif
</div>
</div>
<div class="col-sm-6">
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
{!! Form::label('email', trans('forms.email_label'), ['class' => 'control-label']) !!}
{!! Form::text('email', old('email'), ['class' => 'form-control']) !!}
@if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
{!! Form::label('password', trans('forms.password_label'), ['class' => 'control-label']) !!}
{!! Form::password('password', ['class' => 'form-control']) !!}
@if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
@endif
</div>
</div>
<div class="col-sm-6">
<div class="form-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}">
{!! Form::label('password_confirmation', trans('forms.password_confirm_label'), ['class' => 'control-label']) !!}
{!! Form::password('password_confirmation', ['class' => 'form-control']) !!}
@if ($errors->has('password_confirmation'))
<span class="help-block">
<strong>{{ $errors->first('password_confirmation') }}</strong>
</span>
@endif
</div>
</div>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="is_admin"@if ($user->is_admin) checked="checked"@endif>
<strong>@lang('forms.admin_user_label')</strong>
</label>
</div>
@if (!$user->is_activated)
<div class="checkbox">
<label>
<input type="checkbox" name="is_activated">
<strong>@lang('forms.activate_user_label')</strong>
</label>
</div>
@endif
</div>
{{-- Groups --}}
<div role="tabpanel" class="tab-pane" id="groups-tab">
@if ($groups->count() > 0)
<p style="margin-bottom: 20px;">@lang('admin.user_groups_list_select', ['name' => $user->name])</p>
@foreach ($groups as $group)
<div class="checkbox">
<label>
<input type="checkbox" name="user_group_id[]" value="{{ $group->id }}"@if (in_array($group->id, $users_groups)) checked="checked"@endif>
<strong>{{ $group->name }}</strong>
</label>
</div>
@endforeach
@else
@endif @endif
</div> </div>
</div> </div>
<div class="col-sm-6"> <div class="form-actions" style="margin-top: 20px;">
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}"> <a href="{{ route('users.index') }}" class="btn btn-default">@lang('forms.cancel_action')</a>
{!! Form::label('email', trans('forms.email_label'), ['class' => 'control-label']) !!} {!! Form::submit(trans('forms.save_action'), ['class' => 'btn btn-success']) !!}
{!! Form::text('email', old('email'), ['class' => 'form-control']) !!}
@if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
</div> </div>
</div> </div>
<div class="row">
<div class="col-sm-6">
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
{!! Form::label('password', trans('forms.password_label'), ['class' => 'control-label']) !!}
{!! Form::password('password', ['class' => 'form-control']) !!}
@if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
@endif
</div>
</div>
<div class="col-sm-6">
<div class="form-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}">
{!! Form::label('password_confirmation', trans('forms.password_confirm_label'), ['class' => 'control-label']) !!}
{!! Form::password('password_confirmation', ['class' => 'form-control']) !!}
@if ($errors->has('password_confirmation'))
<span class="help-block">
<strong>{{ $errors->first('password_confirmation') }}</strong>
</span>
@endif
</div>
</div>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="is_admin"@if ($user->is_admin) checked="checked"@endif>
<strong>@lang('forms.admin_user_label')</strong>
</label>
</div>
@if (!$user->is_activated)
<div class="checkbox">
<label>
<input type="checkbox" name="is_activated">
<strong>@lang('forms.activate_user_label')</strong>
</label>
</div>
@endif
<div class="form-actions">
<a href="{{ route('users.index') }}" class="btn btn-default">@lang('forms.cancel_action')</a>
{!! Form::submit(trans('forms.save_action'), ['class' => 'btn btn-success']) !!}
</div>
{!! Form::close() !!} {!! Form::close() !!}
</div> </div>
</div> </div>