Laravelのvalidation機能で画像比率を指定する方法

Laravelはvalidation機能が独自に組み込まれております。
様々な種類のvalidationを設定することが可能です。

今回は、画像比率を指定する方法をご紹介します。
プロフィール画像は1:1の画像に制限したい。などといったvalidationが可能です。

やりかたは非常にシンプルです。

 public function post(Request $request)
{
    $validatedData = $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
        'image' => 'required|dimensions:ratio=1/1',
    ]);

    /post内容/

} 
dimensions:ratio=1/1

のように、dimensions:ratio=〇〇
〇〇に指定したい比率を追加して下さい。

Laravelからs3に画像をUP~画像からUP編~

Laravelからs3へ画像ファイルをアップロードする情報はqiitaなどで沢山あるので、そちらを参考に頂けると良いと思います。

今回は、画像からs3へアップロードする方法を紹介します。
画像から??という方もいるかと思います。
一般的にs3のアップロードで使用する方法は、HTMLのFormからファイルをPostして、そのファイルデータ(画像が多いと思いますが)をs3へアップする方法だと思います。

この場合、 <画像>ではなくて<画像ファイル>に変換しております。

つまり、今回ご紹介するのは、
画像を一度画像ファイルへ変換して、s3にアップロードする方法です。

まずは、画像ファイルをそのままアップロードする、最小コードです。

$filename = Storage::disk('s3')->putFile('s3のファイルディレクトリ', $request->file('image'), 'public'); 

※下記実行済みが前提
・$request->file(‘image’)で、画像ファイルがpostされてくること
・.envの処理、composerでライブラリインストールなどは実行済み

上記と同じように画像をアップロードしようとします。

$filename = Storage::disk('s3')->putFile('s3のファイルディレクトリ', $image, 'public'); 

$imageは画像です。
こうすると下記のerrorが発生します。

 Command (HashName) is not available for driver (Gd). 

errorの内容は、
ファイルの形式が扱えない形式であるということです。

画像を、画像ファイル形式へ変換してあげます。

$filename = Storage::disk('s3')->putFile( 's3のファイルディレクトリ' , new File($save_path), 'public');  

$save_path は、storage上のpathです。
storageにある画像を指定しております。

AWSで作成したRDSの設定を.envの設定で接続/DB_HOST,DB_DATABASE…

AWSで作成したRDSを、Laravelの.envに正しく設定する方法を解説致します。

Laravelでローカルで使っている人でも、.envでデータベースの設定はしていると思います。
どんな設定項目があるでしょうか。

DB_CONNECTION=
DB_HOST=
DB_PORT=
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD= 

こちらを正しく設定していくことで、LaravelからRDSとの接続が可能です。
(通常のアーキテクトでは、Webサーバー(EC2)から、RDSへ接続をしていると思いますが)

DB_CONNECTION
 → RDSで選択した、RDSのアプリケーション
   mysqlを選択したので、mysql

DB_HOST
 → RDSで作成したエンドポイントを設定

DB_PORT
 → RDSで設定したPORT番号を設定します。
   DBサーバーの場合は、主に3306が設定されます。

DB_DATABASE
 → RDSで作成したDatabaseの名称を設定します。

DB_USERNAME
DB_PASSWORD
 → データベースに接続可能なユーザー、パスワードを設定します。
   RDS作成時にマスターユーザー名とパスワードを設定することになるので、そちらを設定してください。

以上です。

LaravelのEloquentでwithを使う方法

Laravelでwithを使う方法を解説していきます。

Eloquentでwithを使う目的

まず、withは何のために使うかというと
リレーションを用いて、Eloquentからデータ抽出したいときに使います。
(n + 1 問題の解決もできます。)

withの使い方

前提として、下記のリレーションが設定されていることとします。
チャットルームとチャットメッセージが、chat_room_idで接続されています。
チャットルームとチャットユーザーが、chat_room_idで接続されています。

class ChatRoom extends Model
{ 

public function chatMessages()
{
return $this->hasMany('App\Models\ChatMessage', 'chat_room_id', 'id' );
}

public function chatRoomUsers()
{
return $this->hasMany('App\Models\ChatRoomUser', 'chat_room_id','id' );
} 
} 

controller上で、どのように使うのかみていきましょう。

 $chatRooms = ChatRoom::with('chatMessages')
    ->get(); 

こうすることによって、chatroomの取得と同時に、chatMessagesもリレーションして取得することが出来ます。

withを複数使うことはできるのか。

結論:はい。できます。

どのように使うのかというと非常にシンプルです。

$chatRooms = ChatRoom::with('chatMessages')
    ->with('chatRoomUsers'); 
    ->get(); 

これで、チャットルームに、チャットメッセージとチャットルームユーザーがリレーションしたデータを抽出することが可能です。

withで抽出したデータを操作したい

withでリレーションしたデータを操作したい方法です。

例えば、withでリレーションしたデータを降順にしたい、昇順にしたいといった並べ替えの変更などあると思います。

 $myApplyChatRooms = ChatRoom::with('chatRoomUsers')
    ->with(['chatMessages' => function ($query) {
        $query->orderBy('created_at', 'desc');
    }])
    ->get(); 

withの中に、Queryを追加してあげることで、自由に操作することが可能です。

Internal GD font () not available. Use only 1-5.

Laravelで intervention/image を利用した中での文字描画をする際にエラーが発生しました。

原因はフォントのパス指定です。

 $img->text('こんにちわ!', $x, $y, function($font){
    $font->file('assets\fonts\SawarabiGothic-Regular.ttf');
    $font->size(25);
    $font->color('#333333');
    $font->align('center');
    $font->valign('top');
    $font->angle(30);
}); 
$font->file('assets\fonts\SawarabiGothic-Regular.ttf');

このように指定してあげると大丈夫です。

public\assets\fontsフォルダの配下に SawarabiGothic-Regular.ttf というwebフォントを格納しております。

Laravelで intervention/image を用いて、文字を描画するために全工程を下記にて紹介しているので、参考にしてみてください。

【Intervention Image】Laravelで画像を生成(文字追加)を導入する流れ(Error対処事例多数)

Laravelを使って画像生成したい(文章を追加した画像生成)ときの流れを解説します。導入するまでに、数々のerrorを対処してきたので記録して残したいと思います。
ライブラリの導入は正しく把握していないと苦労が多いですね…!!

環境:
Laravel 7
dokcer
docker-compose

必要な要素:

1:intervention/imageのインストール
2:開発環境へGDのインストール
3: intervention/image で画像を生成
4: intervention/image で画像 に文字を描画する

こちらの流れです。

1:intervention/imageのインストール

まずは、ライブラリのインストールです。
composerでインストールしていきます。

composer require intervention/image 

intervention/imageをファザードで活用するために設定を追加していきます。

> config/app.php
の中に2か所追加していきます。

 'providers' => [     
// 省略 
Intervention\Image\ImageServiceProvider::class ]


'aliases' => [ 
// 省略
'Image' => Intervention\Image\Facades\Image::class ] 

これにて基本の設定は完了です。
しかし、これだけで使用してみようとすると、errorがでます。

たとえば、
簡単に intervention/image を使うように下記を実行してみてください。

 use Intervention\Image\Facades\Image; 

//省略

public function imagerotate()
{
$path = storage_path('app/public/profile/profiledefault.png');
$img = Image::make($path);
$img->rotate(-45);
$save_path = storage_path('app/public/profile/profiledefault222.png');
$img->save($save_path); 
}

storage>app/public/profile/ フォルダを作成して、その中にprofiledefault.png を格納

これだと、下記のようなエラーがでると思います。
(正しくGDがインストールされている場合は問題ないです。)

GD Library extension not available with this PHP installation.

intervention/image を使うには、GDというライブラリも必要だということですね。

2:開発環境へGDのインストール

それでは、GDを開発環境にインストールしていきます。
dockerを使っているので、そちらへインストールしていきます。

RUN apt-get install -y zlib1g-dev \ 
    libzip-dev \
    libjpeg-dev \
    libpng-dev \
    libfreetype6-dev \
    libjpeg62-turbo-dev
RUN docker-php-ext-configure \
    gd --with-freetype-dir=/usr/include --with-png-dir=/usr/include --with-jpeg-dir=/usr/include
RUN docker-php-ext-install pdo_mysql zip gd 

関係している部分のみ記述しています。

RUN docker-php-ext-install でgdをインストールしているのですが、
gdをインストールするために
・RUN apt-get install
・RUN docker-php-ext-configure
を使って必要なものを準備しています。

--with-freetype-dir=/usr/include

こちらが無くても、画像の処理は可能です。
ただし、これが無いと画像に文字を描画することができません。

正しく動いたdockerfileのみ記述しましたが、こちらを整えるまでに幾つかのerrorがありました….

configure: error: jpeglib.h not found.
ERROR: Service 'php' failed to build: The command '/bin/sh -c docker-php-ext-configure  gd --with-png-dir=/usr/include --with-jpeg-dir=/usr/include' returned a non-zero code: 1 

errorの原因と対処法 ↓ ↓ ↓ ↓

 Call to undefined function Intervention\Image\Gd\imagettfbbox() 

errorの原因と対処法 ↓ ↓ ↓ ↓

それぞれ個別にerrorの原因と対処法を記述しましたので、そちらも参考にしてみ下さい。

3: intervention/image で画像を生成

ここまでくれば、画像を生成することができると思います。

前述した、下記を実行して確認してみてください。

use Intervention\Image\Facades\Image; 

//省略

public function imagerotate()
{
$path = storage_path('app/public/profile/profiledefault.png');
$img = Image::make($path);
$img->rotate(-45);
$save_path = storage_path('app/public/profile/profiledefault222.png');
$img->save($save_path); 
} 
// storage>app/public/profile/ フォルダを作成して、その中にprofiledefault.png を格納 

4: intervention/image で画像 に文字を描画する

いよいよ最後です。
画像に文字を描画していきます。

文字を描画する方法は、下記です。
canvasの作り方は他にもあります。例えば、既存の画像を使用することも可能です。

$x = 40;
$y = 20;
$img = Image::canvas(120, 60, '#fff');
$img->text('こんにちわ!', $x, $y, function($font){
    $font->file('assets\fonts\SawarabiGothic-Regular.ttf');
    $font->size(25);
    $font->color('#333333');
    $font->align('center');
    $font->valign('top');
    $font->angle(30);
});
$save_path = storage_path('app/public/profile/profiledefault222.png');
$img->save($save_path); 

public\assets\fontsフォルダの配下に SawarabiGothic-Regular.ttf というwebフォントを格納しております。

このフォントのパス指定も色々あるようです。
パス指定を間違えると、下記errorがでましたの注意して下さい。

 Internal GD font () not available. Use only 1-5. 

Call to undefined function Intervention\Image\Gd\imagettfbbox()

Laravelで intervention/image を利用した中でのerror解決方法を解説します。

環境:
Laravel 7
dokcer
docker-compose

errorの原因

intervention/image で文字を描画するためのライブラリが入っていない

解決方法

freetype を追加することです。

dockerfile
error時:

RUN apt-get install -y zlib1g-dev \ 
    libzip-dev \
    libjpeg-dev \
    libpng-dev \
RUN docker-php-ext-configure \
    gd --with-png-dir=/usr/include --with-jpeg-dir=/usr/include
RUN docker-php-ext-install pdo_mysql zip gd 

dockerfile
解決後:

RUN apt-get install -y zlib1g-dev \ 
    libzip-dev \
    libjpeg-dev \
    libpng-dev \
    libfreetype6-dev \
    libjpeg62-turbo-dev
RUN docker-php-ext-configure \
    gd --with-freetype-dir=/usr/include --with-png-dir=/usr/include --with-jpeg-dir=/usr/include
RUN docker-php-ext-install pdo_mysql zip gd

こちらを追加して完了です。

Laravelで intervention/image を用いて、文字を描画するために全工程を下記にて紹介しているので、参考にしてみてください。

configure: error: jpeglib.h not found. ERROR: Service ‘php’ failed to build:

Laravelで intervention/image を利用した中でのerror解決方法を解説します。

環境:
Laravel 7
dokcer
docker-compose

errorの原因

GDをインストールする際に他にもインストール必須のものがあり、そちらもインストールしてね~。ということです。

解決方法

dockerfile
error時:

RUN docker-php-ext-configure \
    gd --with-png-dir=/usr/include --with-jpeg-dir=/usr/include
    # gd --with-png-dir=/usr/include --with-jpeg-dir=/usr/include
RUN docker-php-ext-install pdo_mysql zip gd  

dockerfile
解決後:

RUN apt-get install -y zlib1g-dev \ 
    libzip-dev \
    libjpeg-dev \
    libpng-dev \
RUN docker-php-ext-configure \
    gd --with-png-dir=/usr/include --with-jpeg-dir=/usr/include
RUN docker-php-ext-install pdo_mysql zip gd 

    libzip-dev \
    libjpeg-dev \
    libpng-dev \

こちらをapt-get install していく必要があります。

Laravelで intervention/image を用いて、文字を描画するために全工程を下記にて紹介しているので、参考にしてみてください。

Laravelの認証確認メール・パスワードリセットメールを日本語化する方法

Laravel 7での、取り組みです。

Laravelは、メール送付機能を持っていますが、デフォルト設定は勿論英語の状態です。今回は、認証確認メール・パスワードリセットメール送付における日本語化を紹介していきます。

bladeを直接日本語へ変換するやり方もあるかと思いますが、お勧めしません。
というのも、Laravelでは、email送付の雛形を定めておいて、中身を認証確認メール・パスワードリセットメールと状況に応じて使い分けているので直接編集してしまうと、上手く切り替えが難しくなってしまうと思います。
あくまで、Laravelの設計に沿って日本語化していく方法を進めていきます。

ポイント:
1:メールの雛形を作っている php
2:メールの中身を作っている php
3:英語から日本語へ変換する設定

1:メールの雛形を作っている php

まずは、メールの雛形を作っている部分を紹介します。

vendor/laravel/framework/src/Illuminate/Notifications/resources/views/email.blade.php 

こちらのbladeがemail内容の雛形です。

{{ $line }} 、 {{ $actionText }}  などが後から紹介する「 2:メールの中身を作っている php 」部分で生成されて流れてきます。
ここの部分が、認証確認メール・パスワードリセットメールでは切り替えられています。

ここの「vendor」配下のbladeをいじっても内容を変更することは可能ですが、避けましょう。というのもバージョン変更などがあった際に上書きされてしまう場所だからです。

このbladeを編集できるように、オーバーライドするカタチで複製する方法があります。
それが下記のコマンドです。

 php artisan vendor:publish --tag=laravel-notifications 

こちらを実行すると、先ほどのbladeと同じ内容が、

resources/views/vendor/Notifications /email.blade.php 

に複製されます。
ここを編集したものが、メールの雛形として反映されます。
(オーバーライドされます。)

このemail.blade.php 日本語に変換しても、日本語文章を送ることは出来ますが、冒頭に言及した通りオススメは出来ません。
どうやって、日本語化していくは後述していきます。

その前に、2:メールの中身を作っている php を見ていきます。

2:メールの中身を作っている php

認証確認メール・パスワードリセットメールでファイルが違います。

パスワードリセットメール:

vendor/laravel/framework/src/Illuminate/Auth/Notifications/ResetPassword.php 

認証確認メール:

vendor/laravel/framework/src/Illuminate/Auth/Notifications/VerifyEmail.php

こちらで、色々な処理が行われています。

今回は文章の内容だけに注目していきます。

認証確認メール: の方で確認していきます。

return (new MailMessage)     
->subject(Lang::get(‘Verify Email Address’))    
 ->line(Lang::get(‘Please click the button below to verify your email address.’))     
->action(Lang::get(‘Verify Email Address’), $verificationUrl)     
->line(Lang::get(‘If you did not create an account, no further action is required.’));

この、 subject 、line、actionなどが、先ほどの、メールの雛形に送られます。
このままだと、英語がそのまんまおくられています。
・Verify Email Address  
・ Please click the button below to verify your email address.
などです。

これを、日本語に変換していきます。

3:英語から日本語へ変換する設定

2つの処理をしていきます。
・ config/app.php で日本語入力へ反映する指示
・英語文章から変換される日本語を指示

config/app.php で日本語入力へ反映する指示

 config/app.php

-'timezone' => 'UTC', 
+'timezone' => 'Asia/Tokyo', 


-'locale' => 'en', 
+'locale' => 'ja', 

-'faker_locale' => 'en_US', 
+'faker_locale' => 'ja_JP', 

上記、3箇所変更して下さい。

英語文章から変換される日本語を指示

resources/lang/ja.json

下記の位置に、ja.jsonというjsonファイルを作成してください。

 {
 "Thank you.": "ご利用頂きまして誠にありがとうございます。",
 "Verify Email Address": "メール認証をして登録を完了して下さい。",
 "Please click the button below to verify your email address.": "下のボタンをクリックしてメールアドレスの認証を完了してください。",
 "If you did not create an account, no further action is required.": "アカウントを作成していない場合は、何もしなくて大丈夫です。",
 "If you’re having trouble clicking the,": "もしもボタンをクリックしてもサイトへ遷移しない場合は、",
 "copy and paste the URL below": "下記のURLをコピーして",
 "into your web browser:": "ブラウザで反映して下さい。"
}

 

jsonファイルは上記のように、英語から日本語に変換したい対応を記述していきましょう。

先ほど紹介した

vendor/laravel/framework/src/Illuminate/Auth/Notifications/VerifyEmail.php ( ResetPassword.php  )

の中の、英語に対応する部分を日本語化していくこともできますし

return (new MailMessage)     
->subject(Lang::get(‘Verify Email Address’))    
 ->line(Lang::get(‘Please click the button below to verify your email address.’))     
->action(Lang::get(‘Verify Email Address’), $verificationUrl)     
->line(Lang::get(‘If you did not create an account, no further action is required.’));

雛形に存在している英語の中で

resources/views/vendor/Notifications /email.blade.php 

@lang( )で囲まれている部分も、日本語に変換できます。

たとえば、

@lang(‘Regards’)

@lang(‘Hello’)

などありますよね。
これに対応する日本語をjsonファイルに反映すれば、英語ではなくて日本語が反映されます。

Laravelで画像をアップロードするディレクトリを指定する方法

今回の記事は、Laravelでの画像アップロードの流れをある程度理解している方を対象としています。

画像アップロードについて、全体の流れは書きません。
ポイントは、
・画像アップロードのディレクト指定方法
・シンボリックリンクの方法
・画像の呼び出し方

この3点です。

画像アップロードのディレクト指定方法

画像をアップロードするディレクトリを指定する方法は
controller中で storeにディレクトリを指定します。

$fileImage = $request->file('image')->store('public/profile');
$user->image_path = basename($fileImage);

今回指定したのは、public/profile ディレクトリです。

store('public/profile');

これが実行されると
storage/appの配下にディレクトリが作成されます。
今回ので言うと
storage/app/public/profile ディレクトリが作成されて、
その配下に、画像がアップロードされます。

シンボリックリンクの方法

シンボリック方法です。

php artisan storage:link 

こちらのコマンドでpublic と storageが連携されるのは分かっているが、ディレクトを追加した際に、どうなるのか分からないという方もいるかと思います。

心配いりません。
こちらのコマンドを実行すると、publicディレクトリに、storageがリンクされます。

画像の呼び出し方

では、このリンクさせた画像を呼び出してみましょう。

 <img src="{{ asset('storage/profile/' . $user->image_path) }}" 
 ※$user->image_path storeする際に、保存していたファイル名 

これで、指定したディレクトリからファイルを呼び出すことが可能です。