【市場価値がわかる】エンジニア転職におすすめなサイト

Laravel9ニュースサイト14予約公開機能③【Laravel9×TailwindCSS】

Larattoサムネ

前回までの記事

  1. ニュースサイト概要
  2. 環境構築
  3. 総合トップ画面の作成
  4. マイページの作成
  5. ユーザー新規登録・ログイン・ログアウト
  6. マイページの投稿リスト
  7. 記事投稿
  8. 記事の詳細
  9. 記事の編集・更新
  10. ゴミ箱・削除
  11. 下書き・公開中・予約公開一覧
  12. 予約公開機能①-登録処理
  13. 予約公開機能②-更新処理

開発環境

環境バージョン
MacBook AirMonterey 12.2.1
Docker20.10.7
PHP8.1
composer2.2.9
Laravel9.5.1
apache2.4
MySQL8.0
phpmyadmin
npm8.5
node12.22.11
React17
TailwindCSS3
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とコマンドを叩いて、予約公開記事をアップする。

Contents

予約公開コマンドの作成方法

予約公開コマンドについて説明します。

これから作成する予約公開コマンドとは、予約公開設定した記事の予約日時が現在日付と日時を過ぎた場合、記事のステータスを予約公開から公開にするといったものになります。

動作としては、以下の流れです。

  • 予約日時がすぎている記事を取得
  • 記事のステータスを予約公開→公開にする
  • reservation_postsテーブルから該当する予約記事データは削除する

Laravelでコマンドを作成する知識が必要になってくるので、以下を参考にしてください。

>>>Laravel公式-Artisanコンソール

当ブログでも実例つきでわかりやすく解説しています。
>>>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を叩いてみるといいでしょう。

これで予約公開機能は全て終わりです。


スキルを売り買いするならココナラ

オンライン動画学習ならUdemy

コメント

コメントする

CAPTCHA


Contents
閉じる