#3: It is now possible to create, edit and delete user groups.

This commit is contained in:
Andy Heathershaw 2017-02-13 12:08:16 +00:00
parent 3fad3f08cc
commit f70a80ca19
11 changed files with 459 additions and 0 deletions

17
app/Group.php Normal file
View File

@ -0,0 +1,17 @@
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Group extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name'
];
}

View File

@ -0,0 +1,160 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Facade\Theme;
use App\Facade\UserConfig;
use App\Group;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreGroupRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\View;
class GroupController extends Controller
{
public function __construct()
{
$this->middleware('auth');
View::share('is_admin', true);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$this->authorize('admin-access');
return Theme::render('admin.create_group');
}
public function delete($id)
{
$this->authorize('admin-access');
$group = Group::where('id', intval($id))->first();
if (is_null($group))
{
App::abort(404);
}
return Theme::render('admin.delete_group', ['group' => $group]);
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy(Request $request, $id)
{
$this->authorize('admin-access');
/** @var Group $group */
$group = Group::where('id', intval($id))->first();
if (is_null($group))
{
App::abort(404);
}
try
{
$group->delete();
$request->session()->flash('success', trans('admin.group_deletion_successful', [
'name' => $group->name
]));
}
catch (\Exception $ex)
{
$request->session()->flash('error', trans('admin.group_deletion_failed', [
'error_message' => $ex->getMessage(),
'name' => $group->name
]));
}
return redirect(route('groups.index'));
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$this->authorize('admin-access');
$group = Group::where('id', intval($id))->first();
if (is_null($group))
{
App::abort(404);
}
return Theme::render('admin.edit_group', ['group' => $group]);
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$this->authorize('admin-access');
$groups = Group::orderBy('name')
->paginate(UserConfig::get('items_per_page'));
return Theme::render('admin.list_groups', [
'error' => $request->session()->get('error'),
'groups' => $groups,
'success' => $request->session()->get('success'),
'warning' => $request->session()->get('warning')
]);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(StoreGroupRequest $request)
{
$this->authorize('admin-access');
$group = new Group();
$group->fill($request->only(['name']));
$group->save();
return redirect(route('groups.index'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(StoreGroupRequest $request, $id)
{
$this->authorize('admin-access');
$group = Group::where('id', intval($id))->first();
if (is_null($group))
{
App::abort(404);
}
$group->fill($request->only(['name']));
$group->save();
return redirect(route('groups.index'));
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreGroupRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
switch ($this->method())
{
case 'POST':
return ['name' => 'required:max:255|unique:groups,name'];
case 'PUT':
$groupId = intval($this->segment(3));
return ['name' => 'required:max:255|unique:groups,name,' . $groupId];
}
return [];
}
}

View File

@ -0,0 +1,33 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateGroupsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('groups', function ($table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('groups');
}
}

View File

@ -31,6 +31,8 @@ return [
'create_album_intro' => 'Photo albums contain individual photographs together in the same way as a physical photo album or memory book.',
'create_album_intro2' => 'Complete the form below to create a photo album.',
'create_album_no_storage' => 'There are currently no storage locations set up. Please create a location to store your photos before creating an album.',
'create_group' => 'Create a group',
'create_group_intro' => 'Complete the form below to create a group in which to organise your users.',
'create_storage' => 'Create storage location',
'create_storage_intro' => 'Complete the form below to create a new storage location to hold your photos. You can then select this storage location when you create an album.',
'create_user' => 'Create user',
@ -44,6 +46,9 @@ return [
'delete_album_warning' => 'This is a permanent action that cannot be undone!',
'delete_bulk_photos_message' => 'Are you sure you want to delete the selected photos? This action cannot be undone!',
'delete_bulk_photos_title' => 'Delete selected photos',
'delete_group' => 'Delete group: :name',
'delete_group_confirm' => 'Are you sure you want to permanently remove the ":name" group? Users who are members of this group may lose permissions.',
'delete_group_warning' => 'This is a permanent action that cannot be reversed!',
'delete_photo_message' => 'Are you sure you want to delete this photo? This action cannot be undone!',
'delete_photo_successful_message' => 'The photo ":name" was deleted successfully.',
'delete_photo_title' => 'Delete photo',
@ -59,15 +64,21 @@ return [
'edit_album_action' => 'Edit album details',
'edit_album_intro' => 'Photo albums contain individual photographs in the same way as a physical photo album or memory book.',
'edit_album_intro2' => 'Complete the form below to edit the properties of the album: :album_name.',
'edit_group_intro' => 'You can use the form below to edit the above group. Changes take effect immediately.',
'edit_group_title' => 'Edit group: :group_name',
'edit_storage' => 'Edit storage location: :storage_name',
'edit_storage_intro' => 'Use the form below to update the details of the :storage_name storage location.',
'edit_user_intro' => 'You can use the form below to edit the above user account. Changes take effect immediately.',
'edit_user_title' => 'Edit user account: :name',
'group_deletion_failed' => 'An error occurred while removing the ":name" group: :error_message',
'group_deletion_successful' => 'The ":name" group was removed successfully.',
'inactive_storage_legend' => 'Inactive storage location that cannot be used for new albums.',
'is_uploading' => 'Uploading in progress...',
'legend' => 'Legend/Key',
'list_albums_intro' => 'Albums contain collections of individual photographs in the same way as a physical photo album or memory book.',
'list_albums_title' => 'Albums',
'list_groups_intro' => 'Organise your users into categories or types by using groups. You can assign permissions on albums to groups of users to make administration and management easier.',
'list_groups_title' => 'Groups',
'list_storages_intro' => 'Storage locations specify the physical location where your photograph files are held. This may be on your local server\'s filesystem, or on a cloud storage provider such as Rackspace or Amazon S3.',
'list_storages_title' => 'Storage Locations',
'list_users_intro' => 'User accounts allow people to login to your gallery to manage your albums. If you have disabled self-registration, you can create user accounts here to allow people to login.',
@ -79,6 +90,8 @@ return [
'move_successful_message' => 'The photo ":name" was moved successfully to the ":album" album.',
'no_albums_text' => 'You have no photo albums yet. Click the button below to create one.',
'no_albums_title' => 'No Photo Albums',
'no_groups_text' => 'You have no groups yet. Click the button below to create one.',
'no_groups_title' => 'No Groups',
'no_photo_selected_message' => 'Please select at least one photo.',
'no_storages_text' => 'You need a storage location to store your uploaded photographs.',
'no_storages_text2' => 'This can be on your server\'s local filesystem or a cloud location such as Amazon S3 or Rackspace.',

View File

@ -4,12 +4,15 @@ return [
'admin' => 'Admin',
'albums' => 'Albums',
'create_album' => 'Create album',
'create_group' => 'Create group',
'create_storage' => 'Create storage',
'create_user' => 'Create user',
'delete_album' => 'Delete album',
'delete_group' => 'Delete group',
'delete_storage' => 'Delete storage location',
'delete_user' => 'Delete user',
'edit_album' => 'Edit album',
'edit_group' => 'Edit group',
'edit_storage' => 'Edit storage location',
'edit_user' => 'Edit user',
'groups' => 'Groups',

View File

@ -0,0 +1,49 @@
@extends('themes.base.layout')
@section('title', trans('admin.create_group'))
@section('breadcrumb')
<div class="breadcrumb">
<div class="container">
<ol class="breadcrumb">
<li><a href="{{ route('home') }}"><i class="fa fa-fw fa-home"></i></a></li>
<li><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
<li><a href="{{ route('groups.index') }}">@lang('navigation.breadcrumb.groups')</a></li>
<li class="active">@lang('navigation.breadcrumb.create_group')</li>
</ol>
</div>
</div>
@endsection
@section('content')
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>@yield('title')</h1>
<p>@lang('admin.create_group_intro')</p>
<hr/>
{!! Form::open(['route' => 'groups.store', 'method' => 'POST']) !!}
<div class="row">
<div class="col-md-6 col-md-offset-3">
<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 class="form-actions">
<a href="{{ route('groups.index') }}" class="btn btn-default">@lang('forms.cancel_action')</a>
{!! Form::submit(trans('forms.create_action'), ['class' => 'btn btn-success']) !!}
</div>
</div>
</div>
{!! Form::close() !!}
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,35 @@
@extends('themes.base.layout')
@section('title', trans('admin.delete_group', ['name' => $group->name]))
@section('breadcrumb')
<div class="breadcrumb">
<div class="container">
<ol class="breadcrumb">
<li><a href="{{ route('home') }}"><i class="fa fa-fw fa-home"></i></a></li>
<li><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
<li><a href="{{ route('groups.index') }}">@lang('navigation.breadcrumb.groups')</a></li>
<li class="active">@lang('navigation.breadcrumb.delete_group')</li>
</ol>
</div>
</div>
@endsection
@section('content')
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>@yield('title')</h1>
<p>@lang('admin.delete_group_confirm', ['name' => $group->name])</p>
<div class="alert alert-danger">
@lang('admin.delete_group_warning')
</div>
<div class="form-actions">
{!! Form::open(['route' => ['groups.destroy', $group->id], 'method' => 'DELETE']) !!}
<a href="{{ route('groups.index') }}" class="btn btn-default">@lang('forms.cancel_action')</a>
{!! Form::submit(trans('forms.delete_action'), ['class' => 'btn btn-danger']) !!}
{!! Form::close() !!}
</div>
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,49 @@
@extends('themes.base.layout')
@section('title', trans('admin.edit_group_title', ['group_name' => $group->name]))
@section('breadcrumb')
<div class="breadcrumb">
<div class="container">
<ol class="breadcrumb">
<li><a href="{{ route('home') }}"><i class="fa fa-fw fa-home"></i></a></li>
<li><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
<li><a href="{{ route('groups.index') }}">@lang('navigation.breadcrumb.groups')</a></li>
<li class="active">@lang('navigation.breadcrumb.edit_group')</li>
</ol>
</div>
</div>
@endsection
@section('content')
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>@yield('title')</h1>
<p>@lang('admin.edit_group_intro')</p>
<hr/>
{!! Form::model($group, ['route' => ['groups.update', $group->id], 'method' => 'PUT']) !!}
<div class="row">
<div class="col-md-6 col-md-offset-3">
<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 class="form-actions">
<a href="{{ route('groups.index') }}" class="btn btn-default">@lang('forms.cancel_action')</a>
{!! Form::submit(trans('forms.save_action'), ['class' => 'btn btn-success']) !!}
</div>
</div>
</div>
{!! Form::close() !!}
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,61 @@
@extends('themes.base.layout')
@section('title', trans('admin.list_groups_title'))
@section('breadcrumb')
<div class="breadcrumb">
<div class="container">
<ol class="breadcrumb">
<li><a href="{{ route('home') }}"><i class="fa fa-fw fa-home"></i></a></li>
<li><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
<li class="active">@lang('navigation.breadcrumb.groups')</li>
</ol>
</div>
</div>
@endsection
@section('content')
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>@yield('title')</h1>
<div class="alert alert-info" style="margin-bottom: 30px;">
<p><i class="fa fa-fw fa-info"></i> @lang('admin.list_groups_intro')</p>
</div>
@if (count($groups) == 0)
<div class="text-center">
<h4 class="text-danger"><b>@lang('admin.no_groups_title')</b></h4>
<p>@lang('admin.no_groups_text')</p>
<p style="margin-top: 40px;">
<a href="{{ route('groups.create') }}" class="btn btn-lg btn-success">@lang('admin.create_group')</a>
</p>
</div>
@else
<table class="table table-hover table-striped">
<tbody>
@foreach ($groups as $group)
<tr>
<td>
<span style="font-size: 1.3em;">{{ $group->name }}</span>
</td>
<td class="text-right">
<a href="{{ route('groups.edit', ['id' => $group->id]) }}" class="btn btn-default">@lang('forms.edit_action')</a>
<a href="{{ route('groups.delete', ['id' => $group->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
</td>
</tr>
@endforeach
</tbody>
</table>
<div class="text-center">
{{ $groups->links() }}
</div>
<div class="pull-right" style="margin-top: 10px;">
<a href="{{ route('groups.create') }}" class="btn btn-success"><i class="fa fa-fw fa-plus"></i> @lang('admin.create_group')</a>
</div>
@endif
</div>
</div>
</div>
@endsection

View File

@ -62,6 +62,7 @@ Route::group(['prefix' => 'admin'], function () {
Route::resource('users', 'Admin\UserController');
// Group management
Route::get('groups/{id}/delete', 'Admin\GroupController@delete')->name('groups.delete');
Route::resource('groups', 'Admin\GroupController');
});