zoukankan      html  css  js  c++  java
  • Laravel大型项目系列教程(二)之用户管理

    Laravel大型项目系列教程(二)

    一、前言

    本节教程将大概实现用户的注册、修改个人信息、管理用户功能。

    二、Let's go

    1.创建用户注册视图

    $ php artisan generate:view users.create

    修改app/views/users/edit.blade.php

    @extends('_layouts.default')
    
    @section('main')
      <div class="am-g am-g-fixed">
        <div class="am-u-lg-6 am-u-md-8">
          <br/>
          @if (Session::has('message'))
            <div class="am-alert am-alert-{{ Session::get('message')['type'] }}" data-am-alert>
              <p>{{ Session::get('message')['content'] }}</p>
            </div>
          @endif
          @if ($errors->has())
            <div class="am-alert am-alert-danger" data-am-alert>
              <p>{{ $errors->first() }}</p>
            </div>
          @endif
          {{ Form::open(array('url' => 'register', 'class' => 'am-form')) }}
            {{ Form::label('email', 'E-mail:') }}
            {{ Form::email('email', Input::old('email')) }}
            <br/>
            {{ Form::label('nickname', 'NickName:') }}
            {{ Form::text('nickname', Input::old('nickname')) }}
            <br/>
            {{ Form::label('password', 'Password:') }}
            {{ Form::password('password') }}
            <br/>
            {{ Form::label('password_confirmation', 'ConfirmPassword:') }}
            {{ Form::password('password_confirmation') }}
            <br/>
            <div class="am-cf">
              {{ Form::submit('Register', array('class' => 'am-btn am-btn-primary am-btn-sm am-fl')) }}
            </div>
          {{ Form::close() }}
          <br/>
        </div>
      </div>
    @stop

    修改layouts/nav.blade.php中的@else部分:

    @else
      <div class="am-topbar-right">
        <a href="{{ URL::to('register') }}" class="am-btn am-btn-secondary am-topbar-btn am-btn-sm topbar-link-btn"><span class="am-icon-pencil"></span> Register</a>
      </div>
      <div class="am-topbar-right">
        <a href="{{ URL::to('login') }}" class="am-btn am-btn-primary am-topbar-btn am-btn-sm topbar-link-btn"><span class="am-icon-user"></span> Login</a>
      </div>
    @endif

    routes.php中增加:

    Route::get('register', function()
    {
        return View::make('users.create');
    });

    启动开发服务器,浏览器中访问localhost:8000,导航条中多了一个Register按钮:

    点击Register按钮,进入用户注册页面:

    2.实现用户注册

    routes.php中增加:

    Route::post('register', array('before' => 'csrf', function()
    {
        $rules = array(
            'email' => 'required|email|unique:users,email',
            'nickname' => 'required|min:4|unique:users,nickname',
            'password' => 'required|min:6|confirmed',
        );
        $validator = Validator::make(Input::all(), $rules);
        if ($validator->passes())
        {
            $user = User::create(Input::only('email', 'password', 'nickname'));
            $user->password = Hash::make(Input::get('password'));
            if ($user->save())
            {
                return Redirect::to('login')->with('message', array('type' => 'success', 'content' => 'Register successfully, please login'));
            } else {
                return Redirect::to('register')->withInput()->with('message', array('type' => 'danger', 'content' => 'Register failed'));
            }
        } else {
            return Redirect::to('register')->withInput()->withErrors($validator);
        }
    }));

    上面表单验证规则的unique:users,email能确保users表中的email字段是唯一的,切记usersemail之间不能有空格confirmed确保提交的数据必须有一个名为password_conformation的字段且与password字段的值相等。

    例如当输入已存在的email时,会出现错误提示:

    之后我们再修改两个地方,把routes.phppost login内的

    return Redirect::to('login')->withInput()->with('message', 'E-mail or password error');

    修改为:

    return Redirect::to('login')->withInput()->with('message', array('type' => 'danger', 'content' => 'E-mail or password error'));

    login.blade.php中的

    @if (Session::has('message'))
      <div class="am-alert am-alert-danger" data-am-alert>
        <p>{{ Session::get('message') }}</p>
      </div>
    @endif

    修改为:

    @if (Session::has('message'))
      <div class="am-alert am-alert-{{ Session::get('message')['type'] }}" data-am-alert>
        <p>{{ Session::get('message')['content'] }}</p>
      </div>
    @endif

    现在你就可以尝试注册,如果注册成功就会跳转到登录页面,并给出成功的提示:

    注册成功之后你可以试试是否能用刚注册的账号成功登录。

    3.修改个人信息

    用户注册之后我们还应该让他能够修改信息,在_layouts/nav.blade.php中添加修改个人信息的选项:

    <li><a href="{{ URL::to('user/'. Auth::id() . '/edit') }}"><span class="am-icon-user"></span> Information</a></li>

    添加视图users/edit.blade.php

    $ php artisan generate:view users.edit

    修改users/edit.blade.php

    @extends('_layouts.default')
    
    @section('main')
      <div class="am-g am-g-fixed">
        <div class="am-u-lg-6 am-u-md-8">
          <br/>
          @if (Session::has('message'))
            <div class="am-alert am-alert-{{ Session::get('message')['type'] }}" data-am-alert>
              <p>{{ Session::get('message')['content'] }}</p>
            </div>
          @endif
          @if ($errors->has())
            <div class="am-alert am-alert-danger" data-am-alert>
              <p>{{ $errors->first() }}</p>
            </div>
          @endif
          {{ Form::model($user, array('url' => 'user/' . $user->id, 'method' => 'PUT', 'class' => 'am-form')) }}
            {{ Form::label('email', 'E-mail:') }}
            <input id="email" name="email" type="email" readonly="readonly" value="{{ $user->email }}"/>
            <br/>
            {{ Form::label('nickname', 'NickName:') }}
            <input id="nickname" name="nickname" type="text" value="{{{ $user->nickname }}}"/>
            <br/>
            {{ Form::label('old_password', 'OldPassword:') }}
            {{ Form::password('old_password') }}
            <br/>
            {{ Form::label('password', 'NewPassword:') }}
            {{ Form::password('password') }}
            <br/>
            {{ Form::label('password_confirmation', 'ConfirmPassword:') }}
            {{ Form::password('password_confirmation') }}
            <br/>
            <div class="am-cf">
              {{ Form::submit('Modify', array('class' => 'am-btn am-btn-primary am-btn-sm am-fl')) }}
            </div>
          {{ Form::close() }}
          <br/>
        </div>
      </div>
    @stop

    routes.php中添加:

    Route::get('user/{id}/edit', array('before' => 'auth', 'as' => 'user.edit', function($id)
    {
        if (Auth::user()->is_admin or Auth::id() == $id) {
            return View::make('users.edit')->with('user', User::find($id));
        } else {
            return Redirect::to('/');
        }
    }));

    上面的as命名路由,在生成URL时也可以使用别名。例如Redirect::route('user.edit', $id)

    现在登录后在右上角会发现多了一个Information的选项,点击后会显示用户个人信息的页面:

    你是不是发现了表单中的Form::model($user),它会根据View::make('users.edit')->with('user', User::find($id))传过来的user进行自动填充。

    之后就要实现真正地修改用户信息了,在routes.php中增加:

    Route::put('user/{id}', array('before' => 'auth|csrf', function($id)
    {
        if (Auth::user()->is_admin or (Auth::id() == $id)) {
            $user = User::find($id);
            $rules = array(
                'password' => 'required_with:old_password|min:6|confirmed',
                'old_password' => 'min:6',
            );
            if (!(Input::get('nickname') == $user->nickname))
            {
                $rules['nickname'] = 'required|min:4||unique:users,nickname';
            }
            $validator = Validator::make(Input::all(), $rules);
            if ($validator->passes())
            {
                if (!(Input::get('old_password') == '')) {
                    if (!Hash::check(Input::get('old_password'), $user->password)) {
                        return Redirect::route('user.edit', $id)->with('user', $user)->with('message', array('type' => 'danger', 'content' => 'Old password error'));
                    } else {
                        $user->password = Hash::make(Input::get('password'));
                    }
                }
                $user->nickname = Input::get('nickname');
                $user->save();
                return Redirect::route('user.edit', $id)->with('user', $user)->with('message', array('type' => 'success', 'content' => 'Modify successfully'));
            } else {
                return Redirect::route('user.edit', $id)->withInput()->with('user', $user)->withErrors($validator);    
            }
        } else {
            return Redirect::to('/');
        }
    }));

    现在尝试修改信息,如果失败,就会出现错误提示就像下面这样:

    如果成功就会像下面这样:

    这样修改个人信息的功能就完成了。

    4.管理用户

    上面的完成之后,我们就需要管理员能够管理用户,例如可以修改其他用户的昵称、重置它们的密码、锁定用户等。先需要重写下_layouts/nav.blade.php@if (Auth::check())里的内容:

    @if (Auth::user()->is_admin)
    <ul class="am-nav am-nav-pills am-topbar-nav">
      <li class=""><a href="#">Users</a></li>
    </ul>
    @endif
    <div class="am-topbar-right">
      <div class="am-dropdown" data-am-dropdown="{boundary: '.am-topbar'}">
        <button class="am-btn am-btn-secondary am-topbar-btn am-btn-sm am-dropdown-toggle" data-am-dropdown-toggle><span class="am-icon-users"></span> {{{ Auth::user()->nickname }}} <span class="am-icon-caret-down"></span></button>
        <ul class="am-dropdown-content">
          <li><a href="{{ URL::to('user/'. Auth::id() . '/edit') }}"><span class="am-icon-user"></span> Information</a></li>
          <li><a href="{{ URL::to('logout') }}"><span class="am-icon-power-off"></span> Exit</a></li>
        </ul>
      </div>
    </div>

    创建用户列表视图:

    $ php artisan generate:view admin.users.list

    修改views/admin/users/list.blade.php

    @extends('_layouts.default')
    
    @section('main')
    <div class="am-g am-g-fixed">
      <div class="am-u-sm-12">
          <br/>
          @if (Session::has('message'))
        <div class="am-alert am-alert-{{ Session::get('message')['type'] }}" data-am-alert>
          <p>{{ Session::get('message')['content'] }}</p>
        </div>
        @endif
          <table class="am-table am-table-hover am-table-striped ">
          <thead>
          <tr>
            <th>ID</th>
            <th>E-mail</th>
            <th>Nickname</th>
            <th>Management</th>
          </tr>
          </thead>
          <tbody>
          @foreach ($users as $user)
            <tr>
              <td>{{ $user->id }}</td>
              <td>{{ $user->email }}</td>
              <td>{{{ $user->nickname }}}</td>
            <td>
              <a href="{{ URL::to('user/'. $user->id . '/edit') }}" class="am-btn am-btn-xs am-btn-primary">Edit</a>
              {{ Form::open(array('url' => 'user/' . $user->id . '/reset', 'method' => 'PUT', 'style' => 'display: inline;')) }}
                  <button type="button" class="am-btn am-btn-xs am-btn-warning" id="reset{{ $user->id }}">Reset</button>
              {{ Form::close() }}
              @if ($user->block)
              {{ Form::open(array('url' => 'user/' . $user->id . '/unblock', 'method' => 'PUT', 'style' => 'display: inline;')) }}
                  <button type="button" class="am-btn am-btn-xs am-btn-danger" id="unblock{{ $user->id }}">Unblock</button>
              {{ Form::close() }}
              @else
              {{ Form::open(array('url' => 'user/' . $user->id, 'method' => 'DELETE', 'style' => 'display: inline;')) }}
                  <button type="button" class="am-btn am-btn-xs am-btn-danger" id="delete{{ $user->id }}">Block</button>
              {{ Form::close() }}
              @endif
            </td>
          </tr>
          @endforeach
          </tbody>
        </table>
      </div>
    </div>
    
    <div class="am-modal am-modal-confirm" tabindex="-1" id="my-confirm">
      <div class="am-modal-dialog">
        <div class="am-modal-bd">
        </div>
        <div class="am-modal-footer">
          <span class="am-modal-btn" data-am-modal-cancel>No</span>
          <span class="am-modal-btn" data-am-modal-confirm>Yes</span>
        </div>
      </div>
    </div>
    <script>
      $(function() {
        $('[id^=reset]').on('click', function() {
          $('.am-modal-bd').text('Sure you want to reset the password for 123456?');
          $('#my-confirm').modal({
            relatedTarget: this,
            onConfirm: function(options) {
              $(this.relatedTarget).parent().submit();
            },
            onCancel: function() {
            }
          });
        });
    
        $('[id^=delete]').on('click', function() {
          $('.am-modal-bd').text('Sure you want to lock it?');
          $('#my-confirm').modal({
            relatedTarget: this,
            onConfirm: function(options) {
              $(this.relatedTarget).parent().submit();
            },
            onCancel: function() {
            }
          });
        });
    
        $('[id^=unblock]').on('click', function() {
          $('.am-modal-bd').text('Sure you want to unlock it?');
          $('#my-confirm').modal({
            relatedTarget: this,
            onConfirm: function(options) {
              $(this.relatedTarget).parent().submit();
            },
            onCancel: function() {
            }
          });
        });
      });
    </script>
    @stop

    上面的@foreach相当于for循环,可以遍历@users中的内容。

    views/_layouts/default.blade.php中的

    <script src="//cdn.bootcss.com/jquery/2.1.3/jquery.min.js"></script>
    <script src="//cdn.amazeui.org/amazeui/2.1.0/js/amazeui.min.js"></script>

    移到head中。

    为了保证只有管理员才能管理用户,我们在app/filters.php中增加一个过滤器

    Route::filter('idAdmin', function()
    {
        if (!Auth::user()->is_admin) {
            return Redirect::to('/');
        }
    });

    routes.php中增加:

    Route::model('user', 'User');
    
    Route::group(array('before' => 'auth|csrf|isAdmin'), function()
    {
        Route::put('user/{user}/reset', function(User $user)
        {
            $user->password = Hash::make('123456');
            $user->save();
            return Redirect::to('admin/users')->with('message', array('type' => 'success', 'content' => 'Reset password successfully'));
        });
    
        Route::delete('user/{user}', function(User $user)
        {
            $user->block = 1;
            $user->save();
            return Redirect::to('admin/users')->with('message', array('type' => 'success', 'content' => 'Lock user successfully'));
        });
    
        Route::put('user/{user}/unblock', function(User $user)
        {
            $user->block = 0;
            $user->save();
            return Redirect::to('admin/users')->with('message', array('type' => 'success', 'content' => 'Unlock user successfully'));
        });
    });

    上面使用了路由组Route::group路由前缀prefix路由与模型绑定Route::model,过滤器是可以有多个的用|分隔。

    现在用管理员账号登录后会发现导航条多了一个Users链接,点击Users超链接会出现下图这样:

    上面的用户数据需要自己添加,当点击Block的是否会出现确认的提示框:

    点击Yes操作成功后会像下面这样:

    5.小结

    这节完成了用户管理模块,但是还有很多不完善的地方,你可以在用户列表页面添加按昵称或Email查找用户、只显示锁定的用户等功能,还有你是不是发现了在routes.php中代码显得很零乱,那是因为我们还没有使用MVC模式中的C,在下节教程中就将讲解Laravel中的控制器。

    本文详细出处:http://www.shiyanlou.com/courses/123

  • 相关阅读:
    vs2015解决fopen、fscanf 要求替换为fopen_s、fscanf_s的办法
    ThinkPHP5.1的公共函数
    Linux禁止ping
    2019.10.17 上科大虞晶怡教授
    Minimax极大极小算法、Alpha-Beta Pruning剪枝算法
    Apache24服务无法启动,发生服务特定错误1.
    LaTeX小白安装超详细步骤(WIndows系统)||相信我看这个安装就够啦!
    Java中Comparator比较器的使用
    当我看到别人二战想法,退缩的时候,我的感受
    2019.12.3 学英语的心得;学习学习
  • 原文地址:https://www.cnblogs.com/shiyanlou/p/4245792.html
Copyright © 2011-2022 走看看