LoginSignup
2
3

More than 5 years have passed since last update.

[Laravel]プロジェクト生成からCMS作成まで

Last updated at Posted at 2016-11-16

CMS作成の流れ

目的

プロジェクト生成時にとりあえずログイン処理をユーザーのCRUDまでをささっと作りたい

必要機能

  • データベース構築
  • 管理画面(ユーザー管理のみ)
  • ログイン処理
  • メール送信処理

仕様

Laravel 5.1
AdminLTE・・・管理画面のViewで利用

実装の流れ

  1. プロジェクトを作成
  2. .envとapp.phpファイルを編集
  3. AdminLTEをアップロード
  4. データベース準備
  5. ログイン処理を実装
  6. メール送信処理を実装
  7. ユーザー管理のCRUDを実装

1. プロジェクトを作成

  • sshでログインして対象の作業ディレクトリに移動してコマンドを実行
composer create-project laravel/laravel --prefer-dist [プロジェクト名] 5.1

2. .envとapp.phpファイルを編集

  • .envファイルを編集する
APP_ENV=local
APP_DEBUG=true
APP_KEY=[application key]

DB_HOST=localhost
DB_DATABASE=db_sandbox
DB_USERNAME=homestead
DB_PASSWORD=secret
DB_CHARSET=utf8
DB_COLLATION=utf8_general_ci

CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync

MAIL_DRIVER=smtp
MAIL_HOST=mail.example.com
MAIL_PORT=587
MAIL_USERNAME=info@example.com
MAIL_PASSWORD=xxxxxxxx
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=dummy@example.com
MAIL_FROM_NAME="Dummy"
  • config/app.phpファイルを編集
    'timezone' => 'Asia/Tokyo',

    'locale' => 'ja',

    'fallback_locale' => 'ja',

    'log' => 'daily',
    'log_max_files' => '10',

3. AdminLTEをアップロード

4. データベース準備

  • migrationファイルを準備する
php artisan make:migration [テーブル名]Table
  • 生成したファイルを編集する
<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email', 255);
            $table->char('password', 60);
            $table->string('role', 64)->default('user');
            $table->rememberToken();
            $table->string('confirmation_token')->nullable();
            $table->timestamp('confirmed_at')->nullable();
            $table->timestamp('confirmation_sent_at')->nullable();
            $table->timestamps();
            $table->softDeletes();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('users');
    }
}
  • 必要であればSeederファイルも作る

5. ログイン処理を実装

  • app/Http/Controllers/Auth/AuthController.php
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Carbon\Carbon;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Contracts\Config\Repository as Config;
class AuthController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Registration & Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users, as well as the
    | authentication of existing users. By default, this controller uses
    | a simple trait to add these behaviors. Why don't you explore it?
    |
    */
    use AuthenticatesAndRegistersUsers;
    protected $redirectTo = '/admin';
    /**
     * Create a new authentication controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest', ['except' => 'getLogout']);
        $this->middleware('confirm', ['only' => 'postLogin']);
    }
    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => 'required|max:255',
            'email' => 'required|email|max:255|unique:users',
            'password' => 'required|confirmed|min:6',
        ]);
    }
    /**
     * ユーザー登録処理
     **/
    protected function create(Mailer $mailer, array $data, $app_key, $card_type)
    {
        // ユーザー登録処理
        $user = new User;
        $user->name = $data['name'];
        $user->email = $data['email'];
        $user->password = bcrypt($data['password']);
        $user->card_type = $card_type;
        $user->makeConfirmationToken($app_key);
        $user->confirmation_sent_at = Carbon::now();
        $user->save();
        $this->sendConfirmMail($mailer, $user);
        return $user;
    }
    /**
     * ユーザー登録確認メールを送信する
     **/
    private function sendConfirmMail(Mailer $mailer, User $user)
    {
        // ユーザーを有効するためのトークンを発行してメールを送信する
        $mailer->send(
            'emails.confirm',
            ['user' => $user, 'token' => $user->confirmation_token],
            function($message) use ($user) {
//                $message->from('dummy@example.com', 'test');
                $message->to($user->email, $user->name)->subject('ユーザー登録確認');
            }
        );
    }
    /**
     * ログイン処理
     */
    public function postLogin(Request $request)
    {
        $email = $request->input('email');
        $password = $request->input('password');
        if (Auth::attempt(['email' => $email, 'password' => $password, 'deleted_at' => null])) {
            if (Auth::user()->role == 'admin') {
                // 管理画面に遷移
                return redirect(route('admin'));
            } else {
                // サイトトップに遷移
                return redirect('/');
            }
        } else {
            \Session::flash('error_message', '入力されたメールアドレスもしくはパスワードをご確認ください');
            return redirect(route('authLogin'));
        }
    }
    /**
     * パスワード再発行処理
     */
    public function reissue(Request $request, Mailer $mailer)
    {
        $user = User::where('email', '=', $request->email)->first();
        if ($user == null) {
            \Session::flash('error_message', '登録されていないメールアドレスです。');
            return redirect(route('authLogin'));
        }
        // 新しいパスワードを設定
        $new_password = str_random(15);
        $user->update([
            'password' => bcrypt($new_password),
        ]);
        $mailer->send(
            'emails.reissue',
            ['user' => $user, 'password' => $new_password],
            function($message) use ($user) {
                $message->to($user->email, $user->name)->subject('パスワード再発行のお知らせ');
            }
        );
        \Session::flash('success_message', 'パスワード再発行のメールを送信しました。');
        return redirect(route('authLogin'));
    }
    /**
     * 登録処理
     */
    public function postRegister(Request $request, Mailer $mailer, Config $config)
    {
        // バリデーション定義
        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'email' => 'required|max:255|unique:users,email,'.$request->email.',id,deleted_at,NULL',
            'password' => 'required|alpha_num|min:8|max:12|confirmed',
        ],[
            'name.required' => 'お名前は必須入力です。',
            'name.max' => 'お名前は255文字以内で入力してください。',
            'email.required' => 'メールアドレスは必須入力です。',
            'email.email' => 'メールアドレスの入力形式に誤りが御座います。',
            'email.unique' => '既に登録されているメールアドレスです。',
            'password.required' => 'パスワードは必須入力です。',
            'password.confirmed' => '入力されたパスワードが一致しません。',
            'password.min' => 'パスワードは6文字以上入力してください。',
        ]);
        // バリデーション処理
        if ($validator->fails()) {
            return redirect(route('authRegister'))->withErrors($validator)->withInput();
        }
        // ユーザー情報登録
        $this->create($mailer, $request->all(), $config->get('app.key'), 'dummy_card_type');
        \Session::flash('success_message', 'ご登録ありがとう御座います。確認メールを送信しましたのでご確認
            お願いします。');
        return redirect(route('authLogin'));
    }
    /**
     * トークン確認処理
     **/
    public function getConfirm($token) {
        $user = User::where('confirmation_token', '=', $token)->first();
        if (!$user) {
            \Session::flash('error_message', '無効なトークンです。');
            return redirect(route('authLogin'));
        }
        // 登録確認メールに付与されたトークンが一致すればユーザーを有効化
        $user->confirm();
        $user->save();
        \Session::flash('success_message', 'ユーザー登録が完了しました。');
        return redirect(route('authLogin'));
    }
    /**
     * 確認メール再送信画面を表示
     **/
    public function getResend()
    {
        return view('auth.resend');
    }
    /**
     * 確認メール再送信処理
     **/ 
    public function postResend(Request $request, Mailer $mailer, Config $config)
    {
        // 登録ユーザを確認
        $this->validate($request, ['email' => 'required|email']);
        $user = User::where('email', '=', $request->input('email'))->first();
        // 登録ユーザーでない場合はエラー画面へ遷移
        if (!$user) {
            return redirect()->back()->withInput($request->only('email'))
            ->withErrors(['email' => trans('未登録のユーザーです。')]);
        }
        // 登録確認レコード(confirmed_at)を確認
        if ($user->isConfirmed()) {
            \Session::flash('error_message', '既にユーザー登録が完了しています。フォームを入力してログインしてください。');
            return redirect(route('authLogin'));
        }
        // 確認メール再送信
        $this->sendConfirmMail($mailer, $user);
        \Session::flash('success_message', 'ユーザー登録確認メールを再送信しました。');
        return redirect()->guest(route('authLogin'));
    }
    /**
     * ログアウト処理
     */
    public function getLogout()
    {
        Auth::logout();
        return redirect('/');
    }
}
  • app/Http/Kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * @var array
     */
    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
    ];
    /**
     * The application's route middleware.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'role' => \App\Http\Middleware\RoleMiddleware::class,
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'confirm' => \App\Http\Middleware\VerifyConfirmed::class,
    ];
}
  • app/Http/Middleware/RedirectIfAuthenticated.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
class RedirectIfAuthenticated
{
    /**
     * The Guard implementation.
     *
     * @var Guard
     */
    protected $auth;
    /**
     * Create a new filter instance.
     *
     * @param  Guard  $auth
     * @return void
     */
    public function __construct(Guard $auth)
    {
        $this->auth = $auth;
    }
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($this->auth->check()) {
            return redirect('/');
        }
        return $next($request);
    }
}
  • app/Http/Middleware/RoleMiddleware.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RoleMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next, $role)
    {
        $user = Auth::user();
        if ($user->role != $role) {
            return redirect("/");
        }
        return $next($request);
    }
}

  • app/Http/Middleware/VerifyConfirmed.php
<?php
namespace App\Http\Middleware;
use Closure;
use App\User;
class VerifyConfirmed
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $user = User::where('email', '=', $request->input('email'))->first();
        if ($user) {
            // 有効化されているユーザー情報かチェック
            if (! $user->isConfirmed()) {
                \Session::flash('error_message', 'まだユーザー登録が完了していません。送信されたメールから有効化してください。');
                \Session::flash('resend_link', 1);
                return redirect()->back()->withInput($request->only('email'));
            }
        }

        return $next($request);
    }
}
  • app/Http/routes.php
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
Route::get('/', function () {
    return view('welcome');
});
// ログインページ
Route::get('/auth/login', 'Auth\AuthController@getLogin')->name('authLogin');
Route::post('/auth/login', 'Auth\AuthController@postLogin')->name('authLogin');
Route::get('/auth/logout', 'Auth\AuthController@getLogout')->name('authLogout');
// ユーザー登録ページ
Route::get('/auth/register', 'Auth\AuthController@getRegister')->name('authRegister');
Route::post('/auth/register', 'Auth\AuthController@postRegister')->name('authRegister');
Route::get('/auth/confirm/{token}', 'Auth\AuthController@getConfirm')->name('authConfirm');
Route::get('/auth/resend', 'Auth\AuthController@getResend')->name('authResend');
Route::post('/auth/resend', 'Auth\AuthController@postResend')->name('authResend');
Route::post('/auth/reissue', 'Auth\AuthController@reissue')->name('authReissue');
Route::group(['middleware' => ['auth']], function() {
    Route::group(['middleware' => ['role:admin']], function() {
        // 管理画面トップ
        Route::get('/admin', 'Admin\AdminController@index')->name('admin');
    });
});

  • app/User.php
<?php
namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
    use Authenticatable, CanResetPassword, SoftDeletes;
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 
        'email', 
        'password', 
        'role', 
        'invitation', 
        'introduction_code',
    ];
    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
        'confirmation_token',
        'confirmed_at',
        'confirmation_sent_at',
    ];
    protected $dates = [
        'confirmed_at',
        'confirmation_sent_at',
    ];
    /**
     * 全件取得処理
     */
    public function getDataAll()
    {
        return $this->all();
    }
    /**
     * 一覧取得処理
     */
    public function getListAdmin()
    {
        return $this->paginate(config('values.page'));
    }
    /**
     * 削除データ取得処理
     */
    public function getTrash()
    {
        return $this->orderBy('id', 'desc')->onlyTrashed()->paginate(config('values.page'));
    }
    /**
     * 一件取得処理
     */
    public function getDataOne($id)
    {
        return $this->find($id);
    }
    /**
     * 新規登録処理
     */
    public function addData($request)
    {
        // 紹介コード生成
        $invitation = md5(uniqid(rand(), 1));
        $invitation = substr($invitation, 0, 12);
        $this->create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => bcrypt($request->password),
            'role' => $request->role,
        ]);
        return true;
    }
    /**
     * 編集処理
     */
    public function editData($request)
    {
        $user = $this->find($request->id);
        if ($user === null) {
            return false;
        }
        $data = array(
                'name' => $request->name,
                'email' => $request->email,
                'role' => $request->role,
        );
        if ($request->edit_pass != '') {
            $data['password'] = bcrypt($request->edit_pass);
        }
        $user->update($data);
    }
    /**
     * 削除処理
     */
    public function deleteData($id)
    {
        if ($id == 1) {
            return false;
        }
        $user = $this->find($id);
        // 管理者権限のデータは削除出来ないようにする
        if ($user === null || $user->role == 'admin') {
            return false;
        }
        $user->delete();
        return true;
    }
    /**
     * 復元処理
     */
    public function restoreData($id)
    {
        $user = $this->onlyTrashed()->where('id', $id);
        if ($user === null) {
            return false;
        }
        $user->restore();
        return true;
    }
    /**
     * 完全削除処理
     */
    public function forceDeleteData()
    {
        $users = $this->orderBy('id', 'desc')->onlyTrashed();
        $users->forceDelete();
        return true;
    }
    /**
     * 有効化トークンを発行
     */
    public function makeConfirmationToken($key) {
        $this->confirmation_token = hash_hmac('sha256', str_random(40).$this->email, $key);
        return $this->confirmation_token;
    }
    /**
     * 有効化処理
     */
    public function confirm() {
        $this->confirmed_at = Carbon::now();
        $this->confirmation_token = '';
    }
    /**
     * 有効か否かをチェック
     */
    public function isConfirmed() {
        return ! empty($this->confirmed_at);
    }
}
  • resources/views/auth/layout.blade.php
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>プロジェクト名管理画面</title>
    <!-- Tell the browser to be responsive to screen width -->
    <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
    <!-- Bootstrap 3.3.6 -->
    <link rel="stylesheet" href="{{ asset('/assets/bootstrap/css/bootstrap.min.css') }}">
    <!-- Font Awesome -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
    <!-- Ionicons -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">
    <!-- Theme style -->
    <link rel="stylesheet" href="{{ asset('/assets/dist/css/AdminLTE.min.css') }}">
    <!-- AdminLTE Skins. Choose a skin from the css/skins
     folder instead of downloading all of them to reduce the load. -->
    <link rel="stylesheet" href="{{ asset('/assets/dist/css/skins/_all-skins.min.css') }}">
    <!-- iCheck -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/iCheck/flat/blue.css') }}">
    <!-- Morris chart -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/morris/morris.css') }}">
    <!-- jvectormap -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/jvectormap/jquery-jvectormap-1.2.2.css') }}">
    <!-- Date Picker -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/datepicker/datepicker3.css') }}">
    <!-- Daterange picker -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/daterangepicker/daterangepicker.css') }}">
    <!-- bootstrap wysihtml5 - text editor -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css') }}">
    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body class="hold-transition login-page">
    @yield('content')
    <!-- jQuery 2.2.3 -->
    <script src="{{ asset('/assets/plugins/jQuery/jquery-2.2.3.min.js') }}"></script>
    <!-- jQuery UI 1.11.4 -->
    <script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
    <!-- Resolve conflict in jQuery UI tooltip with Bootstrap tooltip -->
    <script>
    $.widget.bridge('uibutton', $.ui.button);
    </script>
    <!-- Bootstrap 3.3.6 -->
    <script src="{{ asset('/assets/bootstrap/js/bootstrap.min.js') }}"></script>
    <!-- Morris.js charts -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<!--
    <script src="{{ asset('/assets/plugins/morris/morris.min.js') }}"></script>
-->
    <!-- Sparkline -->
    <script src="{{ asset('/assets/plugins/sparkline/jquery.sparkline.min.js') }}"></script>
    <!-- jvectormap -->
    <script src="{{ asset('/assets/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js') }}"></script>
    <script src="{{ asset('/assets/plugins/jvectormap/jquery-jvectormap-world-mill-en.js') }}"></script>
    <!-- jQuery Knob Chart -->
    <script src="{{ asset('/assets/plugins/knob/jquery.knob.js') }}"></script>
    <!-- daterangepicker -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.2/moment.min.js"></script>
    <script src="{{ asset('/assets/plugins/daterangepicker/daterangepicker.js') }}"></script>
    <!-- datepicker -->
    <script src="{{ asset('/assets/plugins/datepicker/bootstrap-datepicker.js') }}"></script>
    <!-- Bootstrap WYSIHTML5 -->
    <script src="{{ asset('/assets/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js') }}"></script>
    <!-- Slimscroll -->
    <script src="{{ asset('/assets/plugins/slimScroll/jquery.slimscroll.min.js') }}"></script>
    <!-- FastClick -->
    <script src="{{ asset('/assets/plugins/fastclick/fastclick.js') }}"></script>
    <!-- AdminLTE App -->
    <script src="{{ asset('/assets/dist/js/app.min.js') }}"></script>
    <!-- AdminLTE dashboard demo (This is only for demo purposes) -->
<!--
    <script src="{{ asset('/assets/dist/js/pages/dashboard.js') }}"></script>
-->
    <!-- AdminLTE for demo purposes -->
    <script src="{{ asset('/assets/dist/js/demo.js') }}"></script>
  @show
  </body>
</html>
  • resources/views/auth/login.blade.php
@extends('auth.layout')

@section('content')
<div class="login-box">
  <div class="login-logo">
    <a href=""><b>プロジェクト</b></a>
  </div>
  <!-- /.login-logo -->
  <div class="login-box-body">
    <p class="login-box-msg">ログイン情報を入力してください</p>
    @if (Session::has('success_message'))
      <div class="alert alert-success">{{ Session::get('success_message') }}</div>
    @endif
    @if (Session::has('error_message'))
      <div class="alert alert-danger">{{ Session::get('error_message') }}</div>
    @endif
    <form action="{{ route('authLogin') }}" method="post">
      {!! csrf_field() !!}
      <div class="form-group has-feedback">
        <input type="email" class="form-control" name="email" value="{{ old('email') }}">
        <span class="glyphicon glyphicon-envelope form-control-feedback"></span>
      </div>
      <div class="form-group has-feedback">
        <input type="password" class="form-control" name="password">
        <span class="glyphicon glyphicon-lock form-control-feedback"></span>
      </div>
      <div class="form-group has-feedback">
        <label>
          <input type="checkbox"> ログイン状態を記憶する
        </label>
      </div>
      <div class="form-group has-feedback">
        <button type="submit" class="btn btn-primary btn-block btn-flat">ログイン</button>
      </div>
    </form>
    <a data-toggle="modal" data-target="#formModal" href="/password/email">>>パスワードをお忘れですか?</a><br>  
    <a href="/auth/register">>>新規登録はこちらから</a><br>
    <a href="/auth/resend">>>登録確認メールの再送はこちらから</a><br>
  </div>
  <!-- /.login-box-body -->
</div>
<!-- /.login-box -->
<div class="modal fade" id="formModal" tabindex="-1" role="dialog" aria-labelledby="formModal">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <form role="form" method="post" action="{{ route('authReissue') }}">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
          </button>
          <h4 class="modal-title" id="formModal">パスワードを再発行します</h4>
        </div>
        <div class="modal-body">
            {!! csrf_field() !!}
            <div class="form-group">
              <label for="recipient-name" class="control-label">メールアドレス:</label>
              <input type="email" class="form-control" name="email" value="">
            </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button>
          <button type="submit" class="btn btn-primary">再発行</button>
        </div>
      </form>
    </div>
  </div>
</div>
@endsection
@section('endbody')
@parent
<script>
jQuery(function($) {
  // jQueryの処理
});
</script>
@endsection
  • resources/views/auth/register.blade.php
@extends('auth.layout')

@section('content')
<div class="login-box">
  <div class="login-logo">
    <a href=""><b>プロジェクト</b></a>
  </div>
  <!-- /.login-logo -->
  <div class="login-box-body">
    <p class="login-box-msg">会員登録</p>
         <div class="alert alert-info">
            登録後に入力されたメールアドレスに確認メールが届きます
          </div>
          @if (Session::has('error_message'))
            <div class="alert alert-danger">{{ Session::get('error_message') }}</div>
          @endif
          @if (count($errors) > 0)
              <div class="alert alert-danger">
                  <ul>
                      @foreach ($errors->all() as $error)
                          <li>{{ $error }}</li>
                      @endforeach
                  </ul>
              </div>
          @endif
    <form role="form" method="post" action="{{ route('authRegister') }}">
      {!! csrf_field() !!}
            <div class="form-group">
              <label class="control-label">名前</label>
                <input type="text" class="form-control" name="name" value="{{ old('name') }}">
            </div>
            <div class="form-group">
              <label class="control-label">メールアドレス</label>
              @if (isset($_GET['email']))
                <input type="email" class="form-control" name="email" value="{{ $_GET['email'] }}">
              @else
                <input type="email" class="form-control" name="email" value="{{ old('email') }}">
              @endif
            </div>
            <div class="form-group">
              <label class="control-label">パスワード</label>
              <input type="password" class="form-control" name="password">
            </div>
            <div class="form-group">
                <label class="control-label">パスワード確認</label>
                <input type="password" class="form-control" name="password_confirmation">
            </div>
            <div class="form-group">
              <button type="submit" class="btn btn-primary">
                登録
              </button>
            </div>
    </form>
  </div>
  <!-- /.login-box-body -->
</div>
<!-- /.login-box -->
<div class="modal fade" id="formModal" tabindex="-1" role="dialog" aria-labelledby="formModal">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <form role="form" method="post" action="{{ route('authReissue') }}">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
          </button>
          <h4 class="modal-title" id="formModal">パスワードを再発行します</h4>
        </div>
        <div class="modal-body">
            {!! csrf_field() !!}
            <div class="form-group">
              <label for="recipient-name" class="control-label">メールアドレス:</label>
              <input type="email" class="form-control" name="email" value="">
            </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button>
          <button type="submit" class="btn btn-primary">再発行</button>
        </div>
      </form>
    </div>
  </div>
</div>
@endsection
@section('endbody')
@parent
<script>
jQuery(function($) {
  // jQueryの処理
});
</script>
@endsection

6. メール送信処理を実装

  • config/mail.php
'from' => ['address' => env('MAIL_FROM_ADDRESS'), 'name' => env('MAIL_FROM_NAME')],
  • resources/views/auth/login.blade.php
@extends('auth.layout')

@section('content')
<div class="login-box">
  <div class="login-logo">
    <a href=""><b>プロジェクト</b></a>
  </div>
  <!-- /.login-logo -->
  <div class="login-box-body">
    <p class="login-box-msg">ログイン情報を入力してください</p>
    @if (Session::has('success_message'))
      <div class="alert alert-success">{{ Session::get('success_message') }}</div>
    @endif
    @if (Session::has('error_message'))
      <div class="alert alert-danger">{{ Session::get('error_message') }}</div>
    @endif
    <form action="{{ route('authLogin') }}" method="post">
      {!! csrf_field() !!}
      <div class="form-group has-feedback">
        <input type="email" class="form-control" name="email" value="{{ old('email') }}">
        <span class="glyphicon glyphicon-envelope form-control-feedback"></span>
      </div>
      <div class="form-group has-feedback">
        <input type="password" class="form-control" name="password">
        <span class="glyphicon glyphicon-lock form-control-feedback"></span>
      </div>
      <div class="form-group has-feedback">
        <label>
          <input type="checkbox"> ログイン状態を記憶する
        </label>
      </div>
      <div class="form-group has-feedback">
        <button type="submit" class="btn btn-primary btn-block btn-flat">ログイン</button>
      </div>
    </form>
    <a data-toggle="modal" data-target="#formModalReissue">>>パスワードをお忘れですか?</a><br>  
    <a href="/auth/register">>>新規登録はこちらから</a><br>
    <a data-toggle="modal" data-target="#formModalResend">>>登録確認メールの再送はこちらから</a><br>
  </div>
  <!-- /.login-box-body -->
</div>
<!-- /.login-box -->
<div class="modal fade" id="formModalReissue" tabindex="-1" role="dialog" aria-labelledby="formModalReissue">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <form role="form" method="post" action="{{ route('authReissue') }}">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
          </button>
          <h4 class="modal-title" id="formModalReissue">パスワードを再発行します</h4>
        </div>
        <div class="modal-body">
            {!! csrf_field() !!}
            <div class="form-group">
              <label for="recipient-name" class="control-label">メールアドレス:</label>
              <input type="email" class="form-control" name="email" value="">
            </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button>
          <button type="submit" class="btn btn-primary">再発行</button>
        </div>
      </form>
    </div>
  </div>
</div>
<div class="modal fade" id="formModalResend" tabindex="-1" role="dialog" aria-labelledby="formModalResend">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <form role="form" method="post" action="{{ route('authResend') }}">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
          </button>
          <h4 class="modal-title" id="formModalResend">登録確認メール再送</h4>
        </div>
        <div class="modal-body">
            {!! csrf_field() !!}
            <div class="form-group">
              <label for="recipient-name" class="control-label">メールアドレス:</label>
              <input type="email" class="form-control" name="email" value="">
            </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button>
          <button type="submit" class="btn btn-primary">再発行</button>
        </div>
      </form>
    </div>
  </div>
</div>
@endsection
@section('endbody')
@parent
<script>
jQuery(function($) {
  // jQueryの処理
});
</script>
@endsection
  • resources/views/emails/confirm.blade.php
<p>当サイトをご利用いただき有難うございます</p>
<p>本メールに覚えがない方はお手数ですが破棄していただくようお願いします</p>
<p>ようこそ{{ $user['name'] }} さん</p>
<p><a href="{{ url('auth/confirm', [$token]) }}">会員登録する</a></p>
@include('emails.footer')
  • resources/views/emails/contact_to_admin.blade.php
<p>お問い合わせがありました</p>
<p>担当者はご対応お願いします</p>
<p>=========================================</p>
<p>お名前</p>
<p>{{ $data['name'] }}</p>
<p>メールアドレス</p>
<p>{{ $data['email'] }}</p>
<p>お問い合わせ内容</p>
<p>{!! nl2br(e($data['memo'])) !!}</p>
<p>=========================================</p>
  • resources/views/emails/contact_to_user.blade.php
<p>お問い合わせ有難うございます</p>
<p>下記内容でお問い合わせを受け付けました</p>
<p>ご返信までしばらくお待ちいただくようお願いします</p>
<p>=========================================</p>
<p>お名前</p>
<p>{{ $data['name'] }}</p>
<p>メールアドレス</p>
<p>{{ $data['email'] }}</p>
<p>お問い合わせ内容</p>
<p>{!! nl2br(e($data['memo'])) !!}</p>
<p>=========================================</p>
@include('emails.footer')
  • resources/views/emails/footer.blade.php
<br>
<p>
-------------------------------------------------------------------<br>
運営会社 <br><br>
運営担当 <br><br>
000-0000<br>
----------<br>
Phone00-0000-0000<br>
E-MAIL<br>
WebSite<br>
-------------------------------------------------------------------<br>
</p>
  • resources/views/emails/leave_to_admin.blade.php
<p>{{ $user['name'] }} さん</p>
<p>当サイトをご利用いただき有難うございました</p>
<p>誠に残念ですが退会処理が完了しました</p>
<p>またのご利用をお待ち申し上げます</p>
@include('emails.footer')
  • resources/views/emails/reissue.blade.php
<p>ようこそ{{ $user['name'] }} さん</p>
<p>パスワードを再発行しました</p>
<p>新しいパスワードは下記になります</p>
<br>
<p>{{ $password }}</p>
<br>
<p>ログイン画面より新しいパスワードをご入力いただきご利用ください</p>
@include('emails.footer')

7. ユーザー管理のCRUDを実装

  • app/Http/Requests/UserRequest.php
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
class UserRequest extends Request
{
    /**
     * 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()
    {
        $rules = [
            'name' => 'required',
            'email' => 'required|max:255|unique:users,email,'.$this->id.',id,deleted_at,NULL',
        ];
        if (is_null($this->id)) {
            $rules['password'] = 'required|alpha_num|min:8|max:12|confirmed';
        } else {
            $rules['password'] = 'alpha_num|min:8|max:12';
        }
        return $rules;
    }
    public function attributes() {
        return [
            'name' => '名前',
            'email' => 'Eメール',
            'password' => 'パスワード',
        ];
    }
    public function messages()
    {
        return [
            'required' => ':attributeの入力は必須です。',
            'unique' => 'すでに登録されている:attributeです。',
            'alpha_num' => ':attributeは半角英数で入力して下さい',
            'confirmed' => ':attributeが一致しません。',
            'email.max' => ':attributeは255文字以内で入力して下さい。',
            'password.min' => ':attributeは8文字以上入力して下さい',
        ];
    }
}
  • config/values.php
<?php
return [
    'admin' => [
        'role' => [
            'admin' => '管理者',
            'manager' => 'マネージャー',
            'user' => '一般会員',
        ],
    ],
    'valid' => [
        0 => '無効',
        1 => '有効',
    ],
];
  • resources/views/admin/footer.blade.php
        <div class="pull-right hidden-xs">
          <b>Version</b> 2.3.6
        </div>
        <strong>Copyright &copy; {{ date('Y') }} Corporate プロジェクト名.</strong> All rights reserved.
  • resources/views/admin/index.blade.php
@extends('admin.layout')
@section('content')
        <section class="content-header">
          <h1>
            トップ
            <small>Control panel</small>
          </h1>
          <ol class="breadcrumb">
            <li><a href=""><i class="fa fa-hand-o-right"></i> Home</a></li>
          </ol>
        </section>
        <!-- Main content -->
        <section class="content">
            <div class="box box-solid">
                <div class="box-header with-border">
                    <h3 class="box-title">管理メニュー</h3>
                </div>
                <!-- /.box-header -->
                <div class="box-body">
                    <div class="box-group" id="accordion">
                        <!-- we are adding the .panel class so bootstrap.js collapse plugin detects it -->
                        <div class="panel box box-primary">
                            <div class="box-header with-border">
                                <h4 class="box-title">
                                    ユーザー管理 #1
                                </h4>
                            </div>
                            <div id="collapseOne" class="panel-collapse collapse in" aria-expanded="true">
                                <div class="box-body">
                                    登録しているユーザー情報を管理します<br>
                                    <a href="{{ route('adminUser') }}">一覧</a>・・・登録されているユーザーの一覧を表示します<br>
                                    <a href="{{ route('adminUserAdd') }}">新規登録</a>・・・ユーザー情報を新規に登録します<br>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            <!-- /.box-body -->
            </div>
            <!-- /.box -->
        </section>
@endsection
@section('endbody')
@parent
<script>
jQuery(function($) {
  // jQueryの処理
});
</script>
@endsection
  • resources/views/admin/layout.blade.php
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>プロジェクト名管理画面</title>
    <!-- Tell the browser to be responsive to screen width -->
    <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
    <!-- Bootstrap 3.3.6 -->
    <link rel="stylesheet" href="{{ asset('/assets/bootstrap/css/bootstrap.min.css') }}">
    <!-- Font Awesome -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
    <!-- Ionicons -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">
    <!-- Theme style -->
    <link rel="stylesheet" href="{{ asset('/assets/dist/css/AdminLTE.min.css') }}">
    <!-- AdminLTE Skins. Choose a skin from the css/skins
     folder instead of downloading all of them to reduce the load. -->
    <link rel="stylesheet" href="{{ asset('/assets/dist/css/skins/_all-skins.min.css') }}">
    <!-- iCheck -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/iCheck/flat/blue.css') }}">
    <!-- Morris chart -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/morris/morris.css') }}">
    <!-- jvectormap -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/jvectormap/jquery-jvectormap-1.2.2.css') }}">
    <!-- Date Picker -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/datepicker/datepicker3.css') }}">
    <!-- Daterange picker -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/daterangepicker/daterangepicker.css') }}">
    <!-- bootstrap wysihtml5 - text editor -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css') }}">
    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body class="hold-transition skin-blue sidebar-mini">
    <div class="wrapper">
      <header class="main-header">
        <!-- Logo -->
        <a href="{{ route('admin') }}" class="logo">
          <!-- mini logo for sidebar mini 50x50 pixels -->
          <span class="logo-mini"><b>P</b>name</span>
          <!-- logo for regular state and mobile devices -->
          <span class="logo-lg"><b>プロジェクト</b>名</span>
        </a>
        <!-- Header Navbar: style can be found in header.less -->
        <nav class="navbar navbar-static-top">
          <!-- Sidebar toggle button-->
          <a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button">
            <span class="sr-only">Toggle navigation</span>
          </a>
          <div class="navbar-custom-menu">
            <ul class="nav navbar-nav">
              <li>
                <a href="{{ route('index') }}" target="_blank"><i class="fa  fa-tv"></i> サイト確認</a>
              </li>
              <li>
                <a href="{{ route('authLogout') }}"><i class="fa  fa-sign-out"></i> ログアウト</a>
              </li>
            </ul>
          </div>
        </nav>
      </header>
      <aside class="main-sidebar">
        @include('admin.sidebar')
      </aside>
      <div class="content-wrapper">
        @yield('content')
      </div>
      <footer class="main-footer">
          @include('admin.footer')
      </footer>
      <div class="control-sidebar-bg"></div>
    </div>
  @section('endbody')
    <!-- jQuery 2.2.3 -->
    <script src="{{ asset('/assets/plugins/jQuery/jquery-2.2.3.min.js') }}"></script>
    <!-- jQuery UI 1.11.4 -->
    <script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
    <!-- Resolve conflict in jQuery UI tooltip with Bootstrap tooltip -->
    <script>
    $.widget.bridge('uibutton', $.ui.button);
    </script>
    <!-- Bootstrap 3.3.6 -->
    <script src="{{ asset('/assets/bootstrap/js/bootstrap.min.js') }}"></script>
    <!-- Morris.js charts -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<!--
    <script src="{{ asset('/assets/plugins/morris/morris.min.js') }}"></script>
-->
    <!-- Sparkline -->
    <script src="{{ asset('/assets/plugins/sparkline/jquery.sparkline.min.js') }}"></script>
    <!-- jvectormap -->
    <script src="{{ asset('/assets/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js') }}"></script>
    <script src="{{ asset('/assets/plugins/jvectormap/jquery-jvectormap-world-mill-en.js') }}"></script>
    <!-- jQuery Knob Chart -->
    <script src="{{ asset('/assets/plugins/knob/jquery.knob.js') }}"></script>
    <!-- daterangepicker -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.2/moment.min.js"></script>
    <script src="{{ asset('/assets/plugins/daterangepicker/daterangepicker.js') }}"></script>
    <!-- datepicker -->
    <script src="{{ asset('/assets/plugins/datepicker/bootstrap-datepicker.js') }}"></script>
    <!-- Bootstrap WYSIHTML5 -->
    <script src="{{ asset('/assets/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js') }}"></script>
    <!-- Slimscroll -->
    <script src="{{ asset('/assets/plugins/slimScroll/jquery.slimscroll.min.js') }}"></script>
    <!-- FastClick -->
    <script src="{{ asset('/assets/plugins/fastclick/fastclick.js') }}"></script>
    <!-- AdminLTE App -->
    <script src="{{ asset('/assets/dist/js/app.min.js') }}"></script>
    <!-- AdminLTE dashboard demo (This is only for demo purposes) -->
<!--
    <script src="{{ asset('/assets/dist/js/pages/dashboard.js') }}"></script>
-->
    <!-- AdminLTE for demo purposes -->
    <script src="{{ asset('/assets/dist/js/demo.js') }}"></script>
  @show
  </body>
</html>
  • resources/views/admin/sidebar.blade.php
@extends('admin.layout')
@section('content')
        <section class="content-header">
          <h1>
            トップ
            <small>Control panel</small>
          </h1>
          <ol class="breadcrumb">
            <li><a href=""><i class="fa fa-hand-o-right"></i> Home</a></li>
          </ol>
        </section>
        <!-- Main content -->
        <section class="content">
            <div class="box box-solid">
                <div class="box-header with-border">
                    <h3 class="box-title">管理メニュー</h3>
                </div>
                <!-- /.box-header -->
                <div class="box-body">
                    <div class="box-group" id="accordion">
                        <!-- we are adding the .panel class so bootstrap.js collapse plugin detects it -->
                        <div class="panel box box-primary">
                            <div class="box-header with-border">
                                <h4 class="box-title">
                                    ユーザー管理 #1
                                </h4>
                            </div>
                            <div id="collapseOne" class="panel-collapse collapse in" aria-expanded="true">
                                <div class="box-body">
                                    登録しているユーザー情報を管理します<br>
                                    <a href="{{ route('adminUser') }}">一覧</a>・・・登録されているユーザーの一覧を表示します<br>
                                    <a href="{{ route('adminUserAdd') }}">新規登録</a>・・・ユーザー情報を新規に登録します<br>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            <!-- /.box-body -->
            </div>
            <!-- /.box -->
        </section>
@endsection
@section('endbody')
@parent
<script>
jQuery(function($) {
  // jQueryの処理
});
</script>
@endsection
  • resources/views/admin/layout.blade.php
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>プロジェクト名管理画面</title>
    <!-- Tell the browser to be responsive to screen width -->
    <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
    <!-- Bootstrap 3.3.6 -->
    <link rel="stylesheet" href="{{ asset('/assets/bootstrap/css/bootstrap.min.css') }}">
    <!-- Font Awesome -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
    <!-- Ionicons -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">
    <!-- Theme style -->
    <link rel="stylesheet" href="{{ asset('/assets/dist/css/AdminLTE.min.css') }}">
    <!-- AdminLTE Skins. Choose a skin from the css/skins
     folder instead of downloading all of them to reduce the load. -->
    <link rel="stylesheet" href="{{ asset('/assets/dist/css/skins/_all-skins.min.css') }}">
    <!-- iCheck -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/iCheck/flat/blue.css') }}">
    <!-- Morris chart -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/morris/morris.css') }}">
    <!-- jvectormap -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/jvectormap/jquery-jvectormap-1.2.2.css') }}">
    <!-- Date Picker -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/datepicker/datepicker3.css') }}">
    <!-- Daterange picker -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/daterangepicker/daterangepicker.css') }}">
    <!-- bootstrap wysihtml5 - text editor -->
    <link rel="stylesheet" href="{{ asset('/assets/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css') }}">
    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body class="hold-transition skin-blue sidebar-mini">
    <div class="wrapper">
      <header class="main-header">
        <!-- Logo -->
        <a href="{{ route('admin') }}" class="logo">
          <!-- mini logo for sidebar mini 50x50 pixels -->
          <span class="logo-mini"><b>P</b>name</span>
          <!-- logo for regular state and mobile devices -->
          <span class="logo-lg"><b>プロジェクト</b>名</span>
        </a>
        <!-- Header Navbar: style can be found in header.less -->
        <nav class="navbar navbar-static-top">
          <!-- Sidebar toggle button-->
          <a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button">
            <span class="sr-only">Toggle navigation</span>
          </a>
          <div class="navbar-custom-menu">
            <ul class="nav navbar-nav">
              <li>
                <a href="{{ route('index') }}" target="_blank"><i class="fa  fa-tv"></i> サイト確認</a>
              </li>
              <li>
                <a href="{{ route('authLogout') }}"><i class="fa  fa-sign-out"></i> ログアウト</a>
              </li>
            </ul>
          </div>
        </nav>
      </header>
      <aside class="main-sidebar">
        @include('admin.sidebar')
      </aside>
      <div class="content-wrapper">
        @yield('content')
      </div>
      <footer class="main-footer">
          @include('admin.footer')
      </footer>
      <div class="control-sidebar-bg"></div>
    </div>
  @section('endbody')
    <!-- jQuery 2.2.3 -->
    <script src="{{ asset('/assets/plugins/jQuery/jquery-2.2.3.min.js') }}"></script>
    <!-- jQuery UI 1.11.4 -->
    <script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
    <!-- Resolve conflict in jQuery UI tooltip with Bootstrap tooltip -->
    <script>
    $.widget.bridge('uibutton', $.ui.button);
    </script>
    <!-- Bootstrap 3.3.6 -->
    <script src="{{ asset('/assets/bootstrap/js/bootstrap.min.js') }}"></script>
    <!-- Morris.js charts -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<!--
    <script src="{{ asset('/assets/plugins/morris/morris.min.js') }}"></script>
-->
    <!-- Sparkline -->
    <script src="{{ asset('/assets/plugins/sparkline/jquery.sparkline.min.js') }}"></script>
    <!-- jvectormap -->
    <script src="{{ asset('/assets/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js') }}"></script>
    <script src="{{ asset('/assets/plugins/jvectormap/jquery-jvectormap-world-mill-en.js') }}"></script>
    <!-- jQuery Knob Chart -->
    <script src="{{ asset('/assets/plugins/knob/jquery.knob.js') }}"></script>
    <!-- daterangepicker -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.2/moment.min.js"></script>
    <script src="{{ asset('/assets/plugins/daterangepicker/daterangepicker.js') }}"></script>
    <!-- datepicker -->
    <script src="{{ asset('/assets/plugins/datepicker/bootstrap-datepicker.js') }}"></script>
    <!-- Bootstrap WYSIHTML5 -->
    <script src="{{ asset('/assets/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js') }}"></script>
    <!-- Slimscroll -->
    <script src="{{ asset('/assets/plugins/slimScroll/jquery.slimscroll.min.js') }}"></script>
    <!-- FastClick -->
    <script src="{{ asset('/assets/plugins/fastclick/fastclick.js') }}"></script>
    <!-- AdminLTE App -->
    <script src="{{ asset('/assets/dist/js/app.min.js') }}"></script>
    <!-- AdminLTE dashboard demo (This is only for demo purposes) -->
<!--
    <script src="{{ asset('/assets/dist/js/pages/dashboard.js') }}"></script>
-->
    <!-- AdminLTE for demo purposes -->
    <script src="{{ asset('/assets/dist/js/demo.js') }}"></script>
  @show
  </body>
</html>
  • resources/views/admin/sidebar.blade.php
        <!-- sidebar: style can be found in sidebar.less -->
        <section class="sidebar">
          <!-- sidebar menu: : style can be found in sidebar.less -->
          <ul class="sidebar-menu">
            <li class="header">管理メニュー</li>
            <li class="treeview active">
              <a href="#">
                <i class="fa fa-hand-o-right"></i> <span>ユーザー管理 #1</span>
                <span class="pull-right-container">
                  <i class="fa fa-angle-left pull-right"></i>
                </span>
              </a>
              <ul class="treeview-menu">
                <li><a href="{{ route('adminUser') }}"><i class="fa fa-circle-o"></i>一覧</a></li>
                <li><a href="{{ route('adminUserAdd') }}"><i class="fa fa-circle-o"></i>新規登録</a></li>
                <li><a href="{{ route('adminUserTrash') }}"><i class="fa fa-circle-o"></i>ゴミ箱</a></li>
              </ul>
            </li>
          </ul>
        </section>
        <!-- /.sidebar -->
  • resources/views/admin/user/add.blade.php
@extends('admin.layout')
@section('content')
    <section class="content-header">
      <h1>
        新規登録
        <small>{{ $params['name'] }}</small>
      </h1>
      <ol class="breadcrumb">
        <li><a href="{{ route('admin') }}"><i class="fa  fa-hand-o-right"></i> ホーム</a></li>
        <li><a href="{{ route('adminUser') }}">{{ $params['name'] }}</a></li>
        <li class="active">新規登録</li>
      </ol>
    </section>
    <section class="content">
        <hr>
        <a href="{{ route('adminUser') }}" class="btn btn-default" role="button">一覧</a>&nbsp;&nbsp;&nbsp;
        <hr>
        @if (count($errors) > 0)
            <div class="alert alert-danger">
                <ul>
                    @foreach ($errors->all() as $error)
                        <li>{{ $error }}</li>
                    @endforeach
                </ul>
            </div>
        @endif
        <div class="box box-solid">
            <div class="box-header with-border">
                <h3 class="box-title">新規登録</h3>
            </div>
            <!-- /.box-header -->
            <div class="box-body">
                <form role="form" method="post" action="{{ route('adminUserCreate') }}">
                    {!! csrf_field() !!}
                    <div class="form-group">
                        <label class="control-label">名前</label>
                        <input type="text" class="form-control" name="name" value="{{ old('name') }}">
                    </div>
                    <div class="form-group">
                        <label class="control-label">Eメール</label>
                        <input type="email" class="form-control" name="email" value="{{ old('email') }}">
                    </div>
                    <div class="form-group">
                        <label class="control-label">パスワード</label>
                        <input type="password" class="form-control" name="password">
                    </div>
                    <div class="form-group">
                        <label class="control-label">パスワード確認</label>
                        <input type="password" class="form-control" name="password_confirmation">
                    </div>
                    <div class="form-group">
                        <label class="control-label">役割</label>
                        <select class="form-control" name="role" id="">
                            @foreach (config('values.admin.role') as $key => $value)
                                <option value="{{ $key }}">{{ $value }}</option>
                            @endforeach
                        </select>
                    </div>
                    <div class="box-footer">
                        <button type="submit" class="btn btn-primary pull-right">
                        登録
                        </button>
                    </div>
                </form>
            </div>
        </div>
    </section>
@endsection
@section('endbody')
@parent
<script>
jQuery(function($) {
    $("form").submit(function(){
        var self = this;
        $(":submit", self).prop("disabled", true);
        $(":submit", self).text("処理中");
        setTimeout(function() {
            $(":submit", self).prop("disable", false);
            $(":submit", self).text("登録");
        }, 10000);
    });
});
</script>
@endsection

  • resources/views/admin/user/edit.blade.php
@extends('admin.layout')
@section('content')
    <section class="content-header">
      <h1>
        編集
        <small>{{ $params['name'] }}</small>
      </h1>
      <ol class="breadcrumb">
        <li><a href="{{ route('admin') }}"><i class="fa  fa-hand-o-right"></i> ホーム</a></li>
        <li><a href="{{ route('adminUser') }}">{{ $params['name'] }}</a></li>
        <li class="active">編集</li>
      </ol>
    </section>
    <section class="content">
        <hr>
        <a href="{{ route('adminUser') }}" class="btn btn-default" role="button">一覧</a>&nbsp;&nbsp;&nbsp;
        <a href="{{ route('adminUserAdd') }}" class="btn btn-info" role="button">新規登録</a>&nbsp;&nbsp;&nbsp;
        <a href="{{ route('adminUserShow', ['id' => $user->id]) }}" class="btn btn-default" role="button">詳細</a>&nbsp;&nbsp;&nbsp;
        <hr>
        @if (count($errors) > 0)
            <div class="alert alert-danger">
                <ul>
                    @foreach ($errors->all() as $error)
                        <li>{{ $error }}</li>
                    @endforeach
                </ul>
            </div>
        @endif
        <div class="box box-solid">
            <div class="box-header with-border">
                <h3 class="box-title">編集{{ $user->name }}</h3>
            </div>
            <!-- /.box-header -->
            <div class="box-body">
                <form role="form" method="post" action="{{ route('adminUserUpdate') }}">
                    {!! csrf_field() !!}
                    <div class="form-group">
                        <label class="control-label">名前</label>
                        <input type="text" class="form-control" name="name" value="{{ $user->name }}">
                    </div>
                    <div class="form-group">
                        <label class="control-label">Eメール</label>
                        <input type="email" class="form-control" name="email" value="{{ $user->email }}">
                    </div>
                    <div class="form-group">
                        <label class="control-label">パスワード(再設定する場合は入力して下さい)</label>
                        <input type="password" class="form-control" name="password">
                    </div>
                    <div class="form-group">
                        <label class="control-label">役割</label>
                        <select class="form-control" name="role" id="">
                            @foreach (config('values.admin.role') as $key => $value)
                                <option value="{{ $key }}"{{ ($key == $user->role) ? ' selected':''}}>{{ $value }}</option>
                            @endforeach
                        </select>
                    </div>
                    <input type="hidden" name="id" value="{{ $user->id }}">
                    <div class="box-footer">
                        <button type="submit" class="btn btn-primary pull-right">
                        編集
                        </button>
                    </div>
                </form>
            </div>
        </div>
    </section>
@endsection
@section('endbody')
@parent
<script>
jQuery(function($) {
    $("form").submit(function(){
        var self = this;
        $(":submit", self).prop("disabled", true);
        $(":submit", self).text("処理中");
        setTimeout(function() {
            $(":submit", self).prop("disable", false);
            $(":submit", self).text("編集");
        }, 10000);
    });
});
</script>
@endsection
  • resources/views/admin/user/index.blade.php
@extends('admin.layout')
@section('content')
    <section class="content-header">
      <h1>
        一覧
        <small>{{ $params['name'] }}</small>
      </h1>
      <ol class="breadcrumb">
        <li><a href="{{ route('admin') }}"><i class="fa  fa-hand-o-right"></i> ホーム</a></li>
        <li><a href="{{ route('adminUser') }}">{{ $params['name'] }}</a></li>
        <li class="active">一覧</li>
      </ol>
    </section>
    <section class="content">
        <hr>
        <a href="{{ route('adminUser') }}" class="btn btn-default" role="button">一覧</a>&nbsp;&nbsp;&nbsp;
        <a href="{{ route('adminUserAdd') }}" class="btn btn-info" role="button">新規登録</a>&nbsp;&nbsp;&nbsp;
        <hr>
        @if (Session::has('success_message'))
            <div class="alert alert-success">{{ Session::get('success_message') }}</div>
        @endif
        @if (Session::has('error_message'))
            <div class="alert alert-danger">{{ Session::get('error_message') }}</div>
        @endif
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>名前</th>
                    <th>Eメール</th>
                    <th></th>
                </tr>
            </thead>
            <tbody>
                @foreach ($users as $user)
                    <tr>
                        <th scope="row">{{ $user->name }}</th>
                        <td>{{ $user->email }}</td>
                        <td>
                            <a href="{{ route('adminUserShow', ['id' => $user->id]) }}" class="btn btn-default" role="button">詳細</a>
                            @if ($user->id != 1)
                                <a href="{{ route('adminUserEdit', ['id' => $user->id]) }}" class="btn btn-warning" role="button">編集</a>
                                <a href="{{ route('adminUserDelete', ['id' => $user->id]) }}" class="btn btn-danger delete" role="button">削除</a>
                            @endif
                        </td>
                    </tr>
                @endforeach
            </tbody>
        </table>
        {!! $users->render() !!}
    </section>
@endsection
@section('endbody')
@parent
<script type="text/javascript">
$(document).ready(function () {
    $(".delete").on("click",function(){
        if(!confirm("削除しても宜しいでしょうか?")){
            return false;
        }
    });
});
</script>
@endsection
  • resources/views/admin/user/show.blade.php
@extends('admin.layout')
@section('content')
    <section class="content-header">
      <h1>
        詳細
        <small>{{ $params['name'] }}</small>
      </h1>
      <ol class="breadcrumb">
        <li><a href="{{ route('admin') }}"><i class="fa  fa-hand-o-right"></i> ホーム</a></li>
        <li><a href="{{ route('adminUser') }}">{{ $params['name'] }}</a></li>
        <li class="active">詳細</li>
      </ol>
    </section>
    <section class="content">
        <hr>
        <a href="{{ route('adminUser') }}" class="btn btn-default" role="button">一覧</a>&nbsp;&nbsp;&nbsp;
        <a href="{{ route('adminUserAdd') }}" class="btn btn-info" role="button">新規登録</a>&nbsp;&nbsp;&nbsp;
        <a href="{{ route('adminUserEdit', ['id' => $user->id]) }}" class="btn btn-warning" role="button">編集</a>&nbsp;&nbsp;&nbsp;
        <a href="{{ route('adminUserDelete', ['id' => $user->id]) }}" class="btn btn-danger delete" role="button">削除</a>&nbsp;&nbsp;&nbsp;
        <hr>
        @if (Session::has('success_message'))
            <div class="alert alert-success">{{ Session::get('success_message') }}</div>
        @endif
        @if (Session::has('error_message'))
            <div class="alert alert-danger">{{ Session::get('error_message') }}</div>
        @endif
        <div class="box box-solid">
            <div class="box-header with-border">
                <h3 class="box-title">詳細{{ $user->name }}</h3>
            </div>
            <!-- /.box-header -->
            <div class="box-body">
                <table class="table table-striped">
                    <tbody>
                        @if ($user != null)
                            <tr>
                                <th>名前</th>
                                <td>{{ $user->name }}</td>
                            </tr>
                            <tr>
                                <th>Eメール</th>
                                <td>{{ $user->email }}</td>
                            </tr>
                            <tr>
                                <th>役割</th>
                                <td>{{ config('values.admin.role.'.$user->role) }}</td>
                            </tr>
                            <tr>
                                <th>登録日時</th>
                                <td>{{ $user->created_at}}</td>
                            </tr>
                            <tr>
                                <th>更新日時</th>
                                <td>{{ $user->updated_at }}</td>
                            </tr>
                        @endif
                    </tbody>
                </table>
            </div>
        </div>
    </section>
@endsection
@section('endbody')
@parent
<script type="text/javascript">
$(document).ready(function () {
    $(".delete").on("click",function(){
        if(!confirm("削除しても宜しいでしょうか?")){
            return false;
        }
    });
});
</script>
@endsection
  • resources/views/admin/user/trash.blade.php
@extends('admin.layout')
@section('content')
    <section class="content-header">
      <h1>
        ゴミ箱
        <small>{{ $params['name'] }}</small>
      </h1>
      <ol class="breadcrumb">
        <li><a href="{{ route('admin') }}"><i class="fa  fa-hand-o-right"></i> ホーム</a></li>
        <li><a href="{{ route('adminUser') }}">{{ $params['name'] }}</a></li>
        <li class="active">ゴミ箱</li>
      </ol>
    </section>
    <section class="content">
        <hr>
        <a href="{{ route('adminUser') }}" class="btn btn-default" role="button">一覧</a>&nbsp;&nbsp;&nbsp;
        <a href="{{ route('adminUserForceDelete') }}" class="btn btn-danger forceDelete" role="button">完全削除</a>
        <hr>
        @if (Session::has('error_message'))
            <div class="alert alert-danger" role="alert">
                {{ Session::get('error_message') }}
            </div>
        @endif
        @if (Session::has('success_message'))
            <div class="alert alert-success" role="alert">
                {{ Session::get('success_message') }}
            </div>
        @endif
        @if (count($users) > 0)
            <table class="table table-striped">
                <thead>
                    <tr>
                        <th>名前</th>
                        <th>メール</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    @foreach ($users as $user)
                        <tr>
                            <td>{{ $user->name }}</td>
                            <td>{{ $user->email }}</td>
                            <td>
                                <a href="{{ route('adminUserRestore', ['id' => $user->id]) }}" class="btn btn-warning restore" role="button">復元</a>&nbsp;&nbsp;&nbsp;
                            </td>
                        </tr>
                    @endforeach
                </tbody>
            </table>
            {!! $users->render() !!}
        @else
            <div class="alert alert-success" role="alert">
                削除データはありません
            </div>
        @endif
    </section>
@endsection
@section('endbody')
@parent
<script type="text/javascript">
$(document).ready(function () {
    $(".restore").on("click",function(){
        if(!confirm("復元しても宜しいでしょうか?")){
            return false;
        }
    });
    $(".forceDelete").on("click",function(){
        if(!confirm("完全に削除しても宜しいでしょうか?※この操作はもとに戻すことができません。")){
            return false;
        }
    });
});
</script>
@stop
2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3