LoginSignup
5
7

More than 1 year has passed since last update.

【Laravel】Laravel Breeze で「プロフィールアイコン画像」を追加する方法

Last updated at Posted at 2023-01-23

Laravel Breeze に「プロフィールアイコン画像」機能を追加する

本来、プロフィールアイコンの機能を使用する場合は Laravel の別の認証パッケージである「Laravel Jetstream」を使用すれば良いのですが、そこまで多機能な認証機能を使用しない場合、Breeze の方でも意外と簡単に実装できたので備忘録として記事にしたいと思います。

完成イメージ
Screenshot 2023-01-23 at 20-03-15 Laravel.png

プロフィール画像を追加する手順

Step 1, Laravel & Breeze のインストール

まずは 素のLaravel と Laravel Breeze をインストールするところから。Laravel をインストールするフォルダに移動して Laravel をインストールします(今回は Laravel のインストーラでインストールしています)。

laravel new project_name

インストールした Laravel のプロジェクトルートに移動します。

cd project_name

Laravel Breeze をインストール。

composer require laravel/breeze --dev

認証に必要なリソースを公開して、そのまま続けて必要な依存パッケージを npm からダウンロードしてフロント環境をビルドします。

php artisan breeze:install

マイグレーション処理を行います。

php artisan migrate

これで Breeze の認証機能を使用できるようになりました!ここで一度ブラウザで認証機能が正常に動作するかを確かめると良いでしょう。

Step 2, プロフィールページの編集

resources\views\profile\partials\update-profile-information-form.blade.php の20行目あたりに、画像をアップロードするコンポーネントを表示するための x-picture-input タグ及びエラー時の x-input-error タグを追加します。また、form タグにも画像をアップロードするために enctype="multipart/form-data" を追記します。

update-profile-information-form.blade.php
    // ...
 
+   <form method="post" action="{{ route('profile.update') }}" class="mt-6 space-y-6" enctype="multipart/form-data">
        @csrf
        @method('patch')
    
+       <div>
+           <x-picture-input />
+           <x-input-error class="mt-2" :messages="$errors->get('picture')" />
+       </div>
    
        <div>
            <x-input-label for="name" :value="__('Name')" />
            <x-text-input id="name" name="name" type="text" class="mt-1 block w-full" :value="old('name', $user->name)" required autofocus autocomplete="name" />
            <x-input-error class="mt-2" :messages="$errors->get('name')" />
        </div>

        // ...

x-picture-input タグに対応する Blade コンポーネントを作成します。以下のようにコマンドで作成しましょう。

php artisan make:component picture-input --view

すると resources\views\components\picture-input.blade.php という新しいファイルが作成されますので、このファイルを以下のように編集します。

picture-input.blade.php
<div class="flex mb-4" x-data="picturePreview()">
    <div class="mr-3">
        <img
             id="preview"
             src="{{ isset(Auth::user()->profile_photo_path) ? asset('storage/' . Auth::user()->profile_photo_path) : asset('images/user_icon.png') }}"
             alt=""
             class="w-16 h-16 rounded-full object-cover border-none bg-gray-200">
    </div>
    <div class="flex items-center">
        <button
                x-on:click="document.getElementById('picture').click()"
                type="button"
                class="inline-flex items-center uppercase rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
            SELECT A NEW PHOTO
        </button>
        <input @change="showPreview(event)" type="file" name="picture" id="picture" class="hidden">
        <script>
            function picturePreview() { 
                return {
                    showPreview: (event) =>{
                        if(event.target.files.length > 0){
                            var src = URL.createObjectURL(event.target.files[0]);
                            document.getElementById('preview').src = src;
                        }
                    }
                }
             }
        </script>
    </div>
</div>

上記を記入して保存したら、あなた好みのユーザーアイコンの素材をDLして public/images フォルダ内に入れます。上記の img タグにある src 属性のURLに則って画像のファイル名は user_icon.png としています。今回のサンプルでは、こちらのサイト からユーザーアイコンを DL しました。アイコン画像を保存したフォルダ階層は以下のような感じです。

public/
 ├ images/
 │   └ user_icon.png
 ├ ...

今の状態でブラウザで表示を確認してみると、うまく表示できていないと思います。そのときは npm run build でフロント周りのビルド作業を行ってください。

npm run build

そうするとうまくブラウザで表示できるようになったと思います。

Step 3, User モデルとマイグレーションファイルの編集

uesrs テーブルのマイグレーションファイルである database\migrations\2014_10_12_000000_create_users_table.php を編集して、プロフィールアイコンのパスを保存するカラムを追加します。profile_photo_path カラムを追加する記述 1行を追加します。

2014_10_12_000000_create_users_table.php
    // ...
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
+           $table->string('profile_photo_path')->nullable(); // この行を追加
            $table->rememberToken();
            $table->timestamps();
        });
    }
    //...

profile_photo_path カラムにデータを登録できるようにするために User モデルの app\Models\User.php ファイル protected $fillable の部分を以下のように編集します。

User.php
    // ...
    protected $fillable = [
        'name',
        'email',
        'password',
+       'profile_photo_path', // この行を追加
    ];
    // ...

ここで一度、マイグレート処理を最初からやり直してみましょう。

php artisan migrate:fresh

こうすることで users テーブルに profile_photo_path 列が新たに登録されました。(登録されていたユーザーは初期化されてしまうので再度ユーザー情報を登録し直してください)

Step 4, アイコン画像を登録する処理を記述する

まず、アップロードされる画像のバリデーション設定を app\Http\Requests\ProfileUpdateRequest.php に追記します。

app\Http\Requests\ProfileUpdateRequest.php
    // ...

    public function rules(): array
    {
        return [
            'name' => ['string', 'max:255'],
            'email' => ['email', 'max:255', Rule::unique(User::class)->ignore($this->user()->id)],
+           'picture' => ['file', 'mimes:gif,png,jpg,webp', 'max:3072'],
        ];
    }

    // ...

ユーザーアイコンを保存するための処理を app\Http\Controllers\ProfileController.php の update アクションに記述します。以下のように編集します。

app\Http\Controllers\ProfileController.php
    // ...

    public function update(ProfileUpdateRequest $request): RedirectResponse
    {
-       $request->user()->fill($request->validated());
+       $request->user()->fill($request->safe()->only(['name', 'email']));
    
        if ($request->user()->isDirty('email')) {
            $request->user()->email_verified_at = null;
        }
    
+       $path = null;
+       if ($request->hasFile('picture')) {
+           $path = $request->file('picture')->store('profile-icons', 'public');
+           $request->user()->profile_photo_path = $path;
+       }
    
        $request->user()->save();
    
        return Redirect::route('profile.edit')->with('status', 'profile-updated');
    }

    // ...

アップロードされた画像を表示するため public/storage から storage/app/public へのシンボリックリンクを張ります。以下のコマンドを実行します。

php artisan storage:link

ブラウザで確認してみましょう!

お疲れさまでした!これでプロフィールページから画像のアップロード処理を行うことができるようになっているかと思います。もう一度、会員登録をやり直してプロフィールページ上でアップロードを正常に行うことができるかご確認ください。

5
7
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
5
7