64. 测试头像上传(二)
- 本系列文章为
laracasts.com的系列视频教程——Let's Build A Forum with Laravel and TDD 的学习笔记。若喜欢该系列视频,可去该网站订阅后下载该系列视频, 支持正版 ;- 视频源码地址:github.com/laracasts/Lets-Build-a-...;
- 本项目为一个 forum(论坛)项目,与本站的第二本实战教程 《Laravel 教程 - Web 开发实战进阶》 类似,可互相参照。
本节说明
- 对应视频教程第 64 小节:Testing Avatar Uploads: Part 2
本节内容
本节我们继续头像上传的功能。首先我们运行迁移,添加avatar_path字段:
$ php artisan migrate:refresh进入Tinker环境:
$ php artisan tinker填充数据:
>>> factory('App\Thread',30)->create();注册用户 NoNo1,并新建话题:
我们使用授权策略来进行上传头像的权限控制。首先我们新建授权策略:
$  php artisan make:policy UserPolicy接着注册策略:
app/Providers/AuthServiceProvider.php
.
.
protected $policies = [
    'App\Thread' => 'App\Policies\ThreadPolicy',
    'App\Reply' => 'App\Policies\ReplyPolicy',
    'App\User' => 'App\Policies\UserPolicy',
];
    .
    .然后修改内容:
forum\app\Policies\UserPolicy.php
<?php
namespace App\Policies;
use App\User;
use Illuminate\Auth\Access\HandlesAuthorization;
class UserPolicy
{
    use HandlesAuthorization;
    public function update(User $signedInUser, User $user)
    {
        return $signedInUser->id === $user->id;
    }
}接下来我们增加上传文件的表单,并选择一张图片上传:
forum\resources\views\profiles\show.blade.php
    .
    .
    <div class="page-header">
        <h1>
            {{ $profileUser->name }}
        </h1>
        @can('update',$profileUser)
            <form method="POST" action="{{ route('avatar',$profileUser) }}" enctype="multipart/form-data">
                {{ csrf_field() }}
                <input type="file" name="avatar">
                <button type="submit" class="btn btn-primary">Add Avatar</button>
            </form>
        @endcan
    </div>
    .
    .我们在数据库进行查看:
头像路径已经存到数据库中,但是我们的文件存放在 forum\storage\app\public\avatars 目录下,我们想在 public\avatars 目录下使用头像。我们运行以下命令:
$ php artisan storage:link接着我们将头像显示出来:
    .
    .
    <div class="page-header">
        <h1>
            {{ $profileUser->name }}
        </h1>
        @can('update',$profileUser)
            <form method="POST" action="{{ route('avatar',$profileUser) }}" enctype="multipart/form-data">
                {{ csrf_field() }}
                <input type="file" name="avatar">
                <button type="submit" class="btn btn-primary">Add Avatar</button>
            </form>
        @endcan
        <img src="/{{ $profileUser->avatar_path }}" width="200" height="200">
    </div>
    .
    .注:以上代码对我未生效,所以我使用的是以下代码:
<img src="/storage/{{ $profileUser->avatar_path }}" width="200" height="200">
我们在刷新页面:
我们在话题详情页面显示头像:
forum\resources\views\threads\show.blade.php
    .
    .
    <div class="panel-heading">
        <div class="level">
            <img src="/storage/{{ $thread->creator->avatar_path }}" alt="{{ $thread->creator->name }}" width="25" height="25" class="mr-1">
            <span class="flex">
                <a href="{{ route('profile',$thread->creator) }}">{{ $thread->creator->name }}</a> posted:
                {{ $thread->title }}
            </span>
            @can('update',$thread)
                <form action="{{ $thread->path() }}" method="POST">
                    {{ csrf_field() }}
                    {{ method_field('DELETE') }}
                    <button type="submit" class="btn btn-link">Delete Thread</button>
                </form>
            @endcan
        </div>
    </div>
    .
    .页面效果:
但是与此同时,如果没有上传头像的用户无法显示头像:
我们更改一下处理逻辑,如果用户没有上传头像,我们就使用默认头像。如下:
$thread->creator->avatar();为此我们先来新建一个测试:
forum\tests\Unit\UserTest.php
    .
    .
    /** @test */
    public function a_user_can_determine_their_avatar_path()
    {
        $user = create('App\User');
        $this->assertEquals('avatars/default.jpg',$user->avatar());
        $user->avatar_path = 'avatars/me.jpg';
        $this->assertEquals('avatars/me.jpg',$user->avatar());
    }
}添加avatar()方法:
forum\app\User.php
    .
    .
    public function avatar()
    {
        return $this->avatar_path ?: 'avatars/default.jpg';
    }
    public function visitedThreadCacheKey($thread)
    {
        return $key = sprintf("users.%s.visits.%s",$this->id,$thread->id);
    }
}运行测试:
现在我们可以有默认的头像,如果用户没有上传头像的话。我们在个人页面和话题详情页面应用:
forum\resources\views\profiles\show.blade.php
    .
    .
    <div class="page-header">
        <h1>
            {{ $profileUser->name }}
        </h1>
        @can('update',$profileUser)
            <form method="POST" action="{{ route('avatar',$profileUser) }}" enctype="multipart/form-data">
                {{ csrf_field() }}
                <input type="file" name="avatar">
                <button type="submit" class="btn btn-primary">Add Avatar</button>
            </form>
        @endcan
        <img src="/storage/{{ $profileUser->avatar() }}" width="200" height="200">
    </div>
    .
    .forum\resources\views\threads\show.blade.php*
    .
    .
    <div class="panel-heading">
        <div class="level">
            <img src="/storage/{{ $thread->creator->avatar() }}" alt="{{ $thread->creator->name }}" width="25" height="25" class="mr-1">
            <span class="flex">
                <a href="{{ route('profile',$thread->creator) }}">{{ $thread->creator->name }}</a> posted:
                {{ $thread->title }}
            </span>
            .
            .页面效果:
 
           TDD 构建 Laravel 论坛笔记
TDD 构建 Laravel 论坛笔记 
         
                     
                     
             
             关于 LearnKu
                关于 LearnKu
               
                     
                     
                     粤公网安备 44030502004330号
 粤公网安备 44030502004330号 
 
推荐文章: