前回までの記事
- ニュースサイト概要
- 環境構築
- 総合トップ画面の作成
- マイページの作成
- ユーザー新規登録・ログイン・ログアウト
- マイページの投稿リスト
- 記事投稿
- 記事の詳細
- 記事の編集・更新
- ゴミ箱・削除
- 下書き・公開中・予約公開一覧
- 予約公開機能①-登録処理
- 予約公開機能②-更新処理
開発環境
環境 | バージョン |
---|---|
MacBook Air | Monterey 12.2.1 |
Docker | 20.10.7 |
PHP | 8.1 |
composer | 2.2.9 |
Laravel | 9.5.1 |
apache | 2.4 |
MySQL | 8.0 |
phpmyadmin | – |
npm | 8.5 |
node | 12.22.11 |
React | 17 |
TailwindCSS | 3 |
Laravel/breeze | ログイン認証機能で使用 ※Laravel8以降の場合に使用可。 Laravel6や7系はreact –authとか使います。 |
開発+α
◆dockerコンテナの情報を確認する
→docker ps
◆dockerのphpコンテナに入る
→docker exec -it コンテナIDまたはNAMES bash
◆var/www# はphpコンテナ内を表します。php artisanやnpm run devなどはphpコンテナ内で実行しましょう。
◆tailwindcssでスタイルを変更する前に
→npm run watchを実行していると開発が楽。
※ある程度スタイルが整ったら、npm run devでビルドしましょう。
すると、不要なcssを削除してくれるのでcssファイルが軽くなります。
◆スタイルが適用されないときは….
npm run devで一旦ビルドしてみるか、スーパーリロードでキャッシュの削除をしてみましょう。
- 予約公開コマンドを作成
最終的なゴール
php artisan command:reservationPostUpとコマンドを叩いて、予約公開記事をアップする。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
予約公開コマンドの作成方法
予約公開コマンドについて説明します。
これから作成する予約公開コマンドとは、予約公開設定した記事の予約日時が現在日付と日時を過ぎた場合、記事のステータスを予約公開から公開にするといったものになります。
動作としては、以下の流れです。
- 予約日時がすぎている記事を取得
- 記事のステータスを予約公開→公開にする
- reservation_postsテーブルから該当する予約記事データは削除する
Laravelでコマンドを作成する知識が必要になってくるので、以下を参考にしてください。
当ブログでも実例つきでわかりやすく解説しています。
>>>Laravelでコマンドを作成する方法
(コマンドを自作で作成して、試しに本のデータを登録する処理を解説しています。)
予約公開コマンドを作成する
予約コマンドを作成しましょう。
/var/www# php artisan make:command reservationPostUp
/app/Console/Commands/reservationPostUp.phpが作成されます。
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class reservationPostUp extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'command:name';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
return 0;
}
}
$signatureにコマンド名を$descriptionにコマンドの説明をhandle()に処理を書きます。
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
class reservationPostUp extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'command:reservationPostUp';
/**
* The console command description.
*
* @var string
*/
protected $description = '予約公開設定した記事で予約日時を過ぎた記事をアップする';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
// ログ開始
Log::info('予約公開コマンドの実行開始');
// ログ終わり
Log::info('予約公開コマンドの実行終了');
}
}
こんな感じで、ざっくりと設定してみました。
$signatureにコマンド名を設定したので、ここでphp artisan listと打つと、コマンド一覧が表示されるので、予約公開コマンドがコマンドリストにあるか確認してみましょう。
↓こんな感じで、他のコマンドもバーっと出てきてその中にあると思います。
/var/www# php artisan list
...
...
command
command:reservationPostUp 予約公開設定した記事で予約日時を過ぎた記事をアップする
...
...
コマンドがあったら、実行してhandleのログが実行できるかまずは確認します。
コマンドを実行
/var/www# php artisan command:reservationPostUp
ログが表示されるか
[2022-05-28 11:20:53] local.INFO: 予約公開コマンドの実行開始
[2022-05-28 11:20:53] local.INFO: 予約公開コマンドの実行終了
挙動として問題ないですね。
それでは、実際の処理を書いていきます。
予約公開コマンドの処理をかく
まずは完成コードです。
後ほど処理について解説します。
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Carbon\Carbon;
use App\Models\Post;
use App\Models\ReservationPost;
use Illuminate\Support\Facades\Log;
class reservationPostUp extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'command:reservationPostUp';
/**
* The console command description.
*
* @var string
*/
protected $description = '予約公開設定した記事のアップ';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
// ログ開始
Log::info('予約公開コマンドの実行開始');
// 今日の日付を取得
$now = Carbon::now();
// 年を取得
$year = $now->year;
// 月を取得
$month = $now->month;
// 一桁の月なら05のように先頭に0をつける
if ($month >= 0 && $month < 10) {
$month = '0'.$month;
}
// 一桁の日なら05のように先頭に0をつける
$day = $now->day;
if ($day >= 0 && $day < 10) {
$day = '0'.$day;
}
// 一桁の時なら05のように先頭に0をつける
$hour = $now->hour;
if ($hour >= 0 && $hour < 10) {
$hour = '0'.$hour;
}
// 一桁の分なら05のように先頭に0をつける
$minute = $now->minute;
if ($minute >= 0 && $minute < 10) {
$minute = '0'.$minute;
}
// データベースと比較できるように20220504のように整形する
$date = $year.$month.$day;
// データベースと比較できるように053200のように整形する
$time = $hour.$minute.'00';
// 予約公開設定(reservation_postsテーブル)から日付が今日を含んだ前のデータを取得
$reservation_posts = ReservationPost::where([
['reservation_date', '<=', $date],
])
->get();
// 予約記事を公開する
foreach ($reservation_posts as $reservation_post) {
$r_date = $reservation_post->reservation_date;
$r_time = $reservation_post->reservation_time;
// 今日よりも前の日付なら公開
// 今日と日付が同じで、時間が現在より前なら公開
// 上記以外は公開しない
if ($r_date < $date ||
$r_date === $date && $r_time < $time) {
// 予約公開設定する記事のidを取得
$post_id = $reservation_post->post_id;
// 上記のidをもとに、postsテーブルから該当の記事を取得
$post = Post::find($post_id);
Log::debug('公開する記事'.$post);
// 該当記事の公開設定フラグを1に更新(ステータス:公開)
$update_post = $post->fill(['publish_flg' => 1])->save();
Log::debug('記事のステータスを更新'.$update_post);
// 予約公開設定データは不要なので削除
$delete_reservation_post = $reservation_post->delete($post_id);
Log::debug('予約記事の削除'.$delete_reservation_post);
} else {
return;
}
}
Log::info('予約公開コマンドの実行終了');
}
}
こちらのコードで、予約日時をすぎている記事があれば、
解説します。
use Carbon\Carbon; // 日付を扱うために追加
use App\Models\Post; // postsテーブル使うのでモデル追加
use App\Models\ReservationPost; // reservation_postsテーブル使うので、モデル追加
use Illuminate\Support\Facades\Log; // ログを表示するため追加
Carbonについては、以下の記事で説明しています。
>>>Laravelで日付をマスター
// 一桁の月なら05のように先頭に0をつける
if ($month >= 0 && $month < 10) {
$month = '0'.$month;
}
これについてですが、carbonで月や日を取得してきた場合、例えば今日の日付が5月28日だったら、それぞれ月は5,日は28と取得してくれます。
ただ、reservation_postsテーブルでは1月から9月は01や09など先頭に0をつける仕様にしているため、もし桁数が1桁の月であれば5→05のように先頭に0をつけるという処理になります。
// データベースと比較できるように20220504のように整形する
$date = $year.$month.$day;
// データベースと比較できるように053200のように整形する
$time = $hour.$minute.'00';
最終的に、reservation_postsテーブルにある、reservation_dateとCarbonで取得した今日の年月日、reservation_timeとCarbonで取得した今日の時間を比較します。
なので、reservation_postsのデータと比較できるように、$dateという変数に今日の年月日を、$timeという変数に今日の時間を格納します。
// 予約公開設定(reservation_postsテーブル)から日付が今日を含んだ前のデータを取得
$reservation_posts = ReservationPost::where([
['reservation_date', '<=', $date],
])
->get();
この処理では、reservation_postsテーブルにある今日の日付を含む前の日付のデータをwhereを使って全て取得しています。
// 予約記事を公開する
foreach ($reservation_posts as $reservation_post) {
$r_date = $reservation_post->reservation_date;
$r_time = $reservation_post->reservation_time;
ここの処理では、$r_dateの変数に、reservation_postsテーブルにある予約日付を代入し、$r_timeに予約日時を代入しています。
ちなみに、r_と命名したのは、reservationの略で、rにしました。
後の処理については、コメントで書いているので問題ないかと思いますが、もし付け足す処理があれば自分で付け足してみてください。
$post = Post::find($post_id);
Log::debug('公開する記事'.$post);
このようにdebugを入れているのは、単純に処理の実行がログに残ってわかりやすいからです。
入れていないと、どこかでコケた時に、どこでコケたのかわからないのでこのようにしています。
これで、実際に今日の日付以前だったり、今日の日付で時間は現在日時より前などの予約記事のデータをreservation_postsテーブルに作り、php artisan command:reservationPostUpを叩いてみるといいでしょう。
これで予約公開機能は全て終わりです。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
コメント