副業におすすめなサイトを見る→

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

アプリリリースのお知らせ

予定を探すアプリyoteipickerをリリースしました。

アプリの利用用途:暇だから何か予定入れたいけど今週の土日は何しようかな〜?ってときに使えるアプリです。

前回までの記事

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

開発環境

環境バージョン
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で一旦ビルドしてみるか、スーパーリロードでキャッシュの削除をしてみましょう。

この記事でやること
  • 予約編集画面を作成する
  • 予約日時を表示する

最終的なゴール

予約編集画面

予約日時の表示

>>ココナラと似てるおすすめの副業サイトを確認する

>>リモートワークもあるおすすめの転職サイトを確認する

休日で空いた時間の暇つぶしを探せるアプリを公開しています。

Contents

予約公開設定の編集画面を作成する

完成図

ルーティングを追加する

予約公開設定の編集画面のためにルーティングを追加します。

// 予約公開
Route::controller(ReservationPostController::class)->group(function() {
    // 公開予約設定画面
    Route::get('/reservation/post/setting', 'reservationSetting')
        ->name('reservation.post');
    // 公開予約設定処理
    Route::post('/reservation/post/store', 'reservationStore')
        ->name('reservation.post.store');
    // 公開予約設定編集画面
    Route::get('/reservation/post/edit/{post_id}', 'reservationEdit')
        ->name('reservation.post.edit');
});

ルーティングを追加したので、記事の編集画面から予約日時を変更をクリックした時に予約設定の編集画面に遷移できるようにします。

予約公開のところは、登録処理みたいにtype=”submit”ではなくてformactionとformmethodに修正が必要です。

        <div>
            {{-- ステータスによって、表示するボタンや文言を変更 --}}
            @if ($post->publish_flg === 0)
                <button type="submit" name="save_draft" class="px-4 py-2 text-white text-lg transition-colors duration-200 transform bg-blue-500 rounded-md hover:bg-blue-400">下書き保存</button>
                <button type="submit" name="release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-green-500 rounded-md hover:bg-green-400">更新して公開</button>
                <button formaction="{{ route('reservation.post.edit', ['post_id' => $post->id]) }}" formmethod="GET" name="reservation_release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-amber-500 rounded-md hover:bg-amber-400">予約公開</button>
            @elseif ($post->publish_flg === 1)
                <button type="submit" name="save_draft" class="px-4 py-2 text-white text-lg transition-colors duration-200 transform bg-blue-500 rounded-md hover:bg-blue-400">下書きに戻す</button>
                <button type="submit" name="release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-green-500 rounded-md hover:bg-green-400">更新して公開</button>
            @elseif ($post->publish_flg === 2)
                <button type="submit" name="save_draft" class="px-4 py-2 text-white text-lg transition-colors duration-200 transform bg-blue-500 rounded-md hover:bg-blue-400">下書きに戻す</button>
                <button type="submit" name="release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-green-500 rounded-md hover:bg-green-400">今すぐ公開</button>
                <button formaction="{{ route('reservation.post.edit', ['post_id' => $post->id]) }}" formmethod="GET" name="reservation_release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-amber-500 rounded-md hover:bg-amber-400">予約日時を変更</button>
            @else
                <button type="submit" name="save_draft" class="px-4 py-2 text-white text-lg transition-colors duration-200 transform bg-blue-500 rounded-md hover:bg-blue-400">下書き保存</button>
                <button type="submit" name="release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-green-500 rounded-md hover:bg-green-400">更新して公開</button>
                <button formaction="{{ route('reservation.post.edit', ['post_id' => $post->id]) }}" formmethod="GET" name="reservation_release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-amber-500 rounded-md hover:bg-amber-400">予約公開</button>
            @endif
        </div>

現時点では、コントローラーに予約公開編集画面の処理を書いていないので、ボタンクリックしてもエラーになるかと思います。

なので、予約日時を変更するをクリックした時に、予約公開編集画面に遷移するように、コントローラーに処理を追加したり画面を作成したりしましょう。

コントローラーに予約編集画面を返すアクションを追加する

ReservationPostコントローラーに予約編集画面を返すアクションを追加します。

<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Post;
use App\Models\Category;
use App\Models\ReservationPost;
use Illuminate\Support\Facades\Auth;

class ReservationPostController extends Controller
{
    private $post;
    private $category;
    private $reservationPost;

    public function __construct()
    {
        $this->post = new Post();
        $this->category = new Category();
        $this->reservationPost = new ReservationPost();
    }

    /**
     * 予約公開設定画面
     *
     * @param int $post_id 投稿ID
     */
    public function reservationSetting(Request $request)
    {
        // ログインユーザー情報を取得
        $user = Auth::user();
        // ログインユーザーIDを取得
        $user_id = $user->id;

        // 取得したリクエストデータを変数にセット
        $title = $request->title;
        $body  = $request->body;
        $category = $request->category;

        // 15分リスト
        $minuteList = ['00', '15', '30', '45'];

        // 予約設定画面を返す
        return view('user.list.reservationSetting', compact(
            'user_id',
            'title',
            'body',
            'category',
            'minuteList'
        ));
    }

    /**
     * 予約公開設定
     *
     * @param $request リクエストデータ
     */
    public function reservationStore(Request $request)
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;

        // 投稿データをpostsテーブルにinsert
        $post = $this->post->insertPostToReservationRelease($user_id, $request);

        // 画面で入力した予約設定_日付を取得
        $date = $request->reservation_date;
        // リクエストが2022-04-30とくるので、20220430に整形
        $reservation_date = str_replace('-', '', $date);
        // 画面で入力した予約時間_時を取得
        $hour = $request->reservation_hour;
        // 画面で入力した予約時間_分を取得
        $minute = $request->reservation_minute;
        // 予約時間_時と予約時間_分を合体し、末尾に00をつけてデータを整形。ex.173100
        $reservation_time = $hour.$minute.'00';
        // 予約公開設定内容をreservation_postsテーブルにinsert
        $reservationPost = $this->reservationPost->insertReservationPostData(
            $post,
            $reservation_date,
            $reservation_time
        );

        // セッションにフラッシュメッセージを保存
        $request->session()->flash('reservationRelease', '記事を予約公開しました。');

        // 記事一覧画面にリダイレクト
        return to_route('user.index', ['id' => $user_id]);
    }

    /**
     * 予約公開編集画面
     *
     * @param $request リクエストデータ
     * @param $post_id 投稿ID
     */
    public function reservationEdit(Request $request, $post_id)
    {
        // ログインユーザー情報を取得
        $user = Auth::user();
        // ログインユーザーIDを取得
        $user_id = $user->id;

        // 投稿の編集画面で入力していた内容を取得
        $title = $request->title;
        $body  = $request->body;
        $category = $request->category;

        // 15分リスト
        $minuteList = ['00', '15', '30', '45'];

        // 投稿IDをもとに特定の投稿データを取得
        $post = $this->post->feachPostDateByPostId($post_id);

        // ユーザーIDと投稿IDをもとに、予約公開する投稿データを取得
        $reservationPost = $this->reservationPost->getReservationPostByUserIdAndPostId($user_id, $post_id);

        // 予約公開設定テーブルにユーザーIDと投稿IDで条件を絞ったデータが存在しない場合、エラーになるので、日付や時間は空にして画面に渡す
        if (!isset($reservationPost)) {
            $date = '';
            $hour = '';
            $minute = '';
            return view('user.list.reservationEdit', compact(
                'user_id',
                'post_id',
                'title',
                'body',
                'category',
                'minuteList',
                'date',
                'hour',
                'minute'
            ));
        }

        // 予約公開設定データがある場合は以下の処理を実行
        // ①先頭から4文字目にハイフンをつける(ex.20220430→2022-0430)一度で二箇所にハイフンつけられないので2回に分けた
        $date = substr_replace($reservationPost->reservation_date, '-', 4, 0);
        // ②先頭から7文字目にハイフンをつける(ex.2022-0430→2022-04-30)
        $date = substr_replace($date, '-', 7, 0);

        // reservation_timeから時を切り出し(ex.174500→17)
        $hour = substr($reservationPost->reservation_time, 0, 2);
        // reservation_timeから分を切り出し(ex.174500→45)
        $minute = substr($reservationPost->reservation_time, 2, 2);

        // 予約設定編集画面に遷移
        return view('user.list.reservationEdit', compact(
            'user_id',
            'post_id',
            'title',
            'body',
            'category',
            'minuteList',
            'reservationPost',
            'date',
            'hour',
            'minute'
        ));
    }
}

特定の投稿データを取得するfeachPostDateByPostIdはすでにPostモデルに定義済みですが、予約公開する投稿データを取得するgetReservationPostByUserIdAndPostIdはまだReservationPostモデルに定義していないので、追加しましょう。

モデルに予約公開する投稿データを取得するロジックを追加する

ReservationPostモデルに予約公開する投稿データを取得するgetReservationPostByUserIdAndPostIdを定義していきます。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class ReservationPost extends Model
{
    /**
     * モデルに関連付けるテーブル
     *
     * @var string
     */
    protected $table = 'reservation_posts';

    /**
     * 複数代入可能な属性
     *
     * @var array
     */
    protected $fillable = [
        'user_id',
        'post_id',
        'reservation_date',
        'reservation_time',
        'created_at',
        'updated_at'
    ];

    /**
     * 予約公開設定データをDBにinsert
     *
     * @param $post 投稿データ
     * @param $reservation_date 予約公開_日付
     * @param $reservation_time 予約公開_時間
     */
    public function insertReservationPostData($post, $reservation_date, $reservation_time)
    {
        return $this->create([
            'user_id' => $post->user_id,
            'post_id' => $post->id,
            'reservation_date' => $reservation_date,
            'reservation_time' => $reservation_time
        ]);
    }

    /**
     * ユーザーIDと投稿IDをもとに予約公開予定の投稿データを取得
     *
     * @param int $user_id ユーザーID
     * @param int $post_id 投稿ID
     */
    public function getReservationPostByUserIdAndPostId($user_id, $post_id)
    {
        return $this->where([
            ['user_id', $user_id],
            ['post_id', $post_id]
        ])
        ->first();
    }
}

firstを使うことで、単一のレコードを取得できます。

ちなみに特定のレコードを取得するのは、他にもfind、firstWhereだったり、特定のレコードが見つからない場合はfirstOfやfirstOrFailで制御したりなんかもできます。
参考:Laravel公式Eloquentの準備_単一モデル

予約公開編集画面を作成する

完成図

予約編集画面を作成するために、/resources/views/user/list/reservationEdit.blade.phpを新規作成しましょう。

  • 後で更新処理を追加するので、form action=”” method=””と今は空で大丈夫
  • $i < 10 ? ‘0’.$i: $iは、三項演算子で10より小さかったら頭に0をつけ、10より大きかったらつけないって処理
  • @selectedなどを使って予約編集画面に渡したDBのデータと一致する時間を初期状態にしておく
  • input hiddenを使って、更新ボタン押した時に記事のタイトルなどの情報を渡す
{{-- src/resources/views/layouts/common.blade.php継承 --}}
@extends('layouts.common')

@include('user.parts.sidebar_user')
@section('content')
<div class="p-5">
    <div class="font-bold text-2xl text-center">予約公開編集</div>
    <form action="" method="" class="pt-12 text-center">
    @csrf
        <div class="pb-5 text-2xl underline decoration-dashed decoration-amber-500">予約公開日を変更する</div>
        <label for="reservation_date">日付を選択:</label>
        <input type="date" name="reservation_date" value="{{ old('reservation_date', $date) }}">
        <div class="pt-12 pb-5 text-2xl underline decoration-dashed decoration-amber-500">予約公開時間を変更する</div>
        <label for="reservation_hour">時:</label>
        <select name="reservation_hour">
            @for ($i=0; $i<=23; $i++)
                @if ($i == $hour)
                    <option value="{{ $i < 10 ? '0'.$i: $i }}" @selected($hour)>{{ $i < 10 ? '0'.$i: $i }}</option>
                @else
                    <option value="{{ $i < 10 ? '0'.$i: $i }}">{{ $i < 10 ? '0'.$i: $i }}</option>
                @endif
            @endfor
        </select>
        <label for="reservation_minute">分:</label>
        <select name="reservation_minute">
            @foreach ($minuteList as $m)
                @if ($m == $minute)
                    <option value="{{ $m }}" @selected($minute)>{{ $m }}</option>
                @else
                    <option value="{{ $m }}">{{ $m }}</option>
                @endif
            @endforeach
        </select>
        <input type="hidden" name="title" value="{{ $title }}">
        <input type="hidden" name="body" value="{{ $body }}">
        <input type="hidden" name="category" value="{{ $category }}">
        <div class="pt-12">
            <button type="submit" name="reservation" class="inline-block px-6 py-2.5 bg-amber-500 text-white font-medium text-lg leading-tight uppercase rounded-full shadow-md hover:bg-amber-600 hover:shadow-lg focus:bg-amber-600 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-amber-700 active:shadow-lg transition duration-150 ease-in-out">
                予約公開設定の更新をする
            </button>
        </div>
    </form>
</div>
@endsection

予約公開設定の更新処理を実装する

予約設定の編集画面までできたので、今度は更新処理などをモデルやコントローラーに書いていってDBの更新ができるようにしていきましょう。

予約公開の更新処理をするためのルーティングを追加する

予約公開の更新処理をするルーティングを追加します。

// 予約公開
Route::controller(ReservationPostController::class)->group(function() {
    // 公開予約設定画面
    Route::get('/reservation/post/setting', 'reservationSetting')
        ->name('reservation.post');
    // 公開予約設定処理
    Route::post('/reservation/post/store', 'reservationStore')
        ->name('reservation.post.store');
    // 公開予約設定編集画面
    Route::get('/reservation/post/edit/{post_id}', 'reservationEdit')
        ->name('reservation.post.edit');
    // 公開予約設定更新
    Route::post('/reservation/post/edit/{post_id}', 'reservationUpdate')
        ->name('reservation.post.update');
});

ルーティングを追加したので、予約公開編集画面のformにアクションを追加します。

 <form action="{{ route('reservation.post.update', ['post_id' => $post_id]) }}" method="POST" class="pt-12 text-center">

前回の記事同様に、Postコントローラーのupdateの予約公開クリック時の処理は不要になったので削除します。

// 以下の処理は不要になったため削除
// 予約公開クリック時の処理
case $request->has('reservation_release'):
  $this->post->updatePostToReservationRelease($request, $post);
  $request->session()->flash('updateReservationRelease', '記事を予約公開で更新しました。');
break;

コントローラーに予約設定の更新処理を書く

次にコントローラーに予約設定の更新処理であるreservationUpdateを書いていきましょう。

  • 記事のステータスが下書きである場合、投稿IDに紐づく予約公開データがreservation_postsテーブルにはないので、制御する必要あり
  • リクエストから取得した日付や時間はDB登録や更新用に整形する必要あり
<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Post;
use App\Models\Category;
use App\Models\ReservationPost;
use Illuminate\Support\Facades\Auth;

class ReservationPostController extends Controller
{
    private $post;
    private $category;
    private $reservationPost;

    public function __construct()
    {
        $this->post = new Post();
        $this->category = new Category();
        $this->reservationPost = new ReservationPost();
    }

    /**
     * 予約公開設定画面
     *
     * @param int $post_id 投稿ID
     */
    public function reservationSetting(Request $request)
    {
        // ログインユーザー情報を取得
        $user = Auth::user();
        // ログインユーザーIDを取得
        $user_id = $user->id;

        // 取得したリクエストデータを変数にセット
        $title = $request->title;
        $body  = $request->body;
        $category = $request->category;

        // 15分リスト
        $minuteList = ['00', '15', '30', '45'];

        // 予約設定画面を返す
        return view('user.list.reservationSetting', compact(
            'user_id',
            'title',
            'body',
            'category',
            'minuteList'
        ));
    }

    /**
     * 予約公開設定
     *
     * @param $request リクエストデータ
     */
    public function reservationStore(Request $request)
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;

        // 投稿データをpostsテーブルにinsert
        $post = $this->post->insertPostToReservationRelease($user_id, $request);

        // 画面で入力した予約設定_日付を取得
        $date = $request->reservation_date;
        // リクエストが2022-04-30とくるので、20220430に整形
        $reservation_date = str_replace('-', '', $date);
        // 画面で入力した予約時間_時を取得
        $hour = $request->reservation_hour;
        // 画面で入力した予約時間_分を取得
        $minute = $request->reservation_minute;
        // 予約時間_時と予約時間_分を合体し、末尾に00をつけてデータを整形。ex.173100
        $reservation_time = $hour.$minute.'00';
        // 予約公開設定内容をreservation_postsテーブルにinsert
        $reservationPost = $this->reservationPost->insertReservationPostData(
            $post,
            $reservation_date,
            $reservation_time
        );

        // セッションにフラッシュメッセージを保存
        $request->session()->flash('reservationRelease', '記事を予約公開しました。');

        // 記事一覧画面にリダイレクト
        return to_route('user.index', ['id' => $user_id]);
    }

    /**
     * 予約公開編集画面
     *
     * @param $request リクエストデータ
     * @param $post_id 投稿ID
     */
    public function reservationEdit(Request $request, $post_id)
    {
        // ログインユーザー情報を取得
        $user = Auth::user();
        // ログインユーザーIDを取得
        $user_id = $user->id;

        // 投稿の編集画面で入力していた内容を取得
        $title = $request->title;
        $body  = $request->body;
        $category = $request->category;

        // 15分リスト
        $minuteList = ['00', '15', '30', '45'];

        // 投稿IDをもとに特定の投稿データを取得
        $post = $this->post->feachPostDateByPostId($post_id);

        // ユーザーIDと投稿IDをもとに、予約公開する投稿データを取得
        $reservationPost = $this->reservationPost->getReservationPostByUserIdAndPostId($user_id, $post_id);

        // 予約公開設定テーブルにユーザーIDと投稿IDで条件を絞ったデータが存在しない場合、エラーになるので、日付や時間は空にして画面に渡す
        if (!isset($reservationPost)) {
            $date = '';
            $hour = '';
            $minute = '';
            return view('user.list.reservationEdit', compact(
                'user_id',
                'post_id',
                'title',
                'body',
                'category',
                'minuteList',
                'date',
                'hour',
                'minute'
            ));
        }

        // 予約公開設定データがある場合は以下の処理を実行
        // ①先頭から4文字目にハイフンをつける(ex.20220430→2022-0430)一度で二箇所にハイフンつけられないので2回に分けた
        $date = substr_replace($reservationPost->reservation_date, '-', 4, 0);
        // ②先頭から7文字目にハイフンをつける(ex.2022-0430→2022-04-30)
        $date = substr_replace($date, '-', 7, 0);

        // reservation_timeから時を切り出し(ex.174500→17)
        $hour = substr($reservationPost->reservation_time, 0, 2);
        // reservation_timeから分を切り出し(ex.174500→45)
        $minute = substr($reservationPost->reservation_time, 2, 2);

        // 予約設定編集画面に遷移
        return view('user.list.reservationEdit', compact(
            'user_id',
            'post_id',
            'title',
            'body',
            'category',
            'minuteList',
            'reservationPost',
            'date',
            'hour',
            'minute'
        ));
    }

    /**
     * 予約公開設定更新
     *
     * @param $request リクエストデータ
     * @param $post_id 投稿ID
     */
    public function reservationUpdate(Request $request, $post_id)
    {
        // ログインユーザー情報を取得
        $user = Auth::user();
        // ログインユーザーIDを取得
        $user_id = $user->id;

        // 投稿IDをもとに特定の投稿データを取得
        $post = $this->post->feachPostDateByPostId($post_id);
        // 投稿データを更新
        $this->post->updatePostToReservationRelease($request, $post);

        // 画面で入力した予約設定_日付を取得
        $date = $request->reservation_date;
        // リクエストが2022-04-30とくるので、20220430に整形
        $reservation_date = str_replace('-', '', $date);
        // 画面で入力した予約時間_時を取得
        $hour = $request->reservation_hour;
        // 画面で入力した予約時間_分を取得
        $minute = $request->reservation_minute;
        // 予約時間_時と予約時間_分を合体し、末尾に00をつけてデータを整形。ex.173100
        $reservation_time = $hour.$minute.'00';

        // ユーザーIDと投稿IDをもとに更新する予約公開記事のデータを1件取得
        $reservationPost = $this->reservationPost->getReservationPostByUserIdAndPostId($user_id, $post_id);

        // 下書き→公開予約する際、そもそも予約公開データはないので$reservationPostはnullになり、画面でエラーになる。そのため制御
        if (!isset($reservationPost)) {
            // 予約公開設定内容をreservation_postsテーブルにinsert
            $this->reservationPost->insertReservationPostData(
                $post,
                $reservation_date,
                $reservation_time
            );

            // セッションにフラッシュメッセージを格納
            $request->session()->flash('updateReservationRelease', '記事を予約公開で更新しました。');
            // 投稿一覧画面にリダイレクト
            return to_route('user.index', ['id' => $user_id]);
        }

        // すでに投稿IDに紐づく予約公開データがあれば、その予約公開データを更新
        $this->reservationPost->updateReservationPost(
            $reservationPost,
            $reservation_date,
            $reservation_time
        );

        // セッションにフラッシュメッセージを格納
        $request->session()->flash('updateReservationRelease', '記事を予約公開で更新しました。');
        // 投稿一覧画面にリダイレクト
        return to_route('user.index', ['id' => $user_id]);
    }
}

予約公開のデータを更新するupdateReservationPostはまだ未定義かと思いますので、モデルに追加します。

予約設定更新処理をモデルに追加する

モデルに予約設定更新処理であるupdateReservationPostを定義します。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class ReservationPost extends Model
{
    /**
     * モデルに関連付けるテーブル
     *
     * @var string
     */
    protected $table = 'reservation_posts';

    /**
     * 複数代入可能な属性
     *
     * @var array
     */
    protected $fillable = [
        'user_id',
        'post_id',
        'reservation_date',
        'reservation_time',
        'created_at',
        'updated_at'
    ];

    /**
     * 予約公開設定データをDBにinsert
     *
     * @param $post 投稿データ
     * @param $reservation_date 予約公開_日付
     * @param $reservation_time 予約公開_時間
     */
    public function insertReservationPostData($post, $reservation_date, $reservation_time)
    {
        return $this->create([
            'user_id' => $post->user_id,
            'post_id' => $post->id,
            'reservation_date' => $reservation_date,
            'reservation_time' => $reservation_time
        ]);
    }

    /**
     * ユーザーIDと投稿IDをもとに予約公開予定の投稿データを取得
     *
     * @param int $user_id ユーザーID
     * @param int $post_id 投稿ID
     */
    public function getReservationPostByUserIdAndPostId($user_id, $post_id)
    {
        return $this->where([
            ['user_id', $user_id],
            ['post_id', $post_id]
        ])
        ->first();
    }

    /**
     * 予約公開データを更新
     *
     * @param $reservationPost 予約公開データ
     * @param $reservation_date 予約日付
     * @param $reservation_time 予約時間
     */
    public function updateReservationPost($reservationPost, $reservation_date, $reservation_time)
    {
        return $reservationPost->fill([
            'reservation_date' => $reservation_date,
            'reservation_time' => $reservation_time,
        ])->save();
    }
}

挙動を確認してみます。

記事の一覧画面で試しに投稿ID79のステータスが予約公開となっている記事のEditをクリック

予約日時を変更をクリック

登録してあった予約日時が表示されるので、時間などを変更して更新をクリック

記事一覧画面にリダイレクト※DBを確認すると変更した内容で更新されています。

投稿IDが78の記事を上記のように操作してみると、記事一覧にリダイレクトしたときにステータスが予約公開になっているのが確認できると思いますよ〜

予約公開機能の実装はまだ続きますよザーボンさん

ここまでで予約編集画面と更新処理できたから、やっと予約公開終わったZEと鼻をヒクヒクしているそこのあなたはどんまいです。

予約公開機能でまだ実装するべき内容として、

  • 予約編集画面にわかりやすいように公開予定の日時を表示する
  • 記事のステータスを予約公開→下書き保存に更新した時に、投稿IDに紐づく予約公開データは削除すべき
  • 記事をゴミ箱や完全に削除したときは、投稿IDに紐づく予約公開データは削除すべき

などがありますので、それを片付けていきましょう。どうですか?まだ鼻ヒクヒクしてます?

予約編集画面に公開予定の日時を表示させる

完成図

やりたいこととしては、編集する記事のステータスが予約公開であれば、編集画面で予約日時を表示させるって感じです。

そのためには、Postコントローラーのeditアクションに、投稿IDに紐づく予約公開データがあれば、そのデータを参照して予約日時を取得する
→記事の編集画面に値を渡して表示が処理としていいでしょう。

<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use App\Models\Post;
use App\Models\Category;
use App\Models\ReservationPost;
use App\Http\Requests\PostRequest;

class PostController extends Controller
{
    private $post;
    private $category;
    private $reservationPost;

    public function __construct()
    {
        $this->post = new Post();
        $this->category = new Category();
        $this->reservationPost = new ReservationPost();
    }

    /**
     * 投稿リスト
     *
     * @param int $id ユーザーID
     * @return Response src/resources/views/user/list/index.blade.phpを表示
     */
    public function index(int $id)
    {
        // ユーザーIDと一致する投稿データを取得
        $posts = $this->post->getAllPostsByUserId($id);
        return view('user.list.index', compact(
            'posts',
        ));
    }

    /**
     * 記事投稿画面
     *
     * @return Response src/resources/views/user/list/create.blade.phpを表示
     */
    public function create()
    {
        // カテゴリーデータを全件取得
        $categories = $this->category->getAllCategories();
        return view('user.list.create', compact(
            'categories',
        ));
    }

    /**
     * 記事投稿処理
     *
     * @param string $request リクエストデータ
     * @return Response src/resources/views/user/list/index.blade.phpを表示
     */
    public function store(PostRequest $request)
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;

        switch (true) {
            // 下書き保存クリック時の処理
            case $request->has('save_draft'):
                $this->post->insertPostToSaveDraft($user_id, $request);
                $request->session()->flash('saveDraft', '記事を下書きで保存しました。');
                break;
            // 公開クリック時の処理
            case $request->has('release'):
                $this->post->insertPostToRelease($user_id, $request);
                $request->session()->flash('release', '記事を公開しました。');
                break;
            // 上記以外の処理
            default:
                $this->post->insertPostToSaveDraft($user_id, $request);
                $request->session()->flash('saveDraft', '記事を下書きで保存しました。');
                break;
        }

        return to_route('user.index', ['id' => $user_id]);
    }

    /**
     * 記事詳細
     *
     * @param int $post_id 投稿ID
     * @return Response src/resources/views/user/list/show.blade.phpを表示
     */
    public function show($post_id) {
        // リクエストされた投稿IDをもとにpostsテーブルから一意のデータを取得
        $showPostData = $this->post->feachPostDateByPostId($post_id);
        return view('user.list.show', compact(
            'showPostData',
        ));
    }

    /**
     * 記事編集
     *
     * @param int $post_id 投稿ID
     * @return Response src/resources/views/user/list/edit.blade.phpを表示
     */
    public function edit($post_id)
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;

        // カテゴリーデータを全件取得
        $categories = $this->category->getAllCategories();
        // 投稿IDをもとに特定の投稿データを取得
        $post = $this->post->feachPostDateByPostId($post_id);

        // 記事のステータスが予約公開以外はそもそも予約公開データはないので初期値はnullをセット
        $date = null;
        $time = null;
        // 投稿IDをもとに予約公開データを取得
        $reservationPost = $this->reservationPost->getReservationPostByUserIdAndPostId($user_id, $post_id);
        // 予約公開データがあれば予約日時を取得
        if (isset($reservationPost)) {
            // 年・月・日にそれぞれ文字を切り出し
            // (20220530→2022)
            $year = substr($reservationPost->reservation_date, 0, 4);
            // (20220530→05)
            $month = substr($reservationPost->reservation_date, 4, 2);
            // (20220530→30)
            $day = substr($reservationPost->reservation_date, 6, 2);
            // 上記に年月日をつける(2022年05月30日)
            $date = $year.'年'.$month.'月'.$day;

            // 時・分にそれぞれ文字を切り出し
            // (083200→08)
            $hour = substr($reservationPost->reservation_time, 0, 2);
            // (083200→32)
            $minute = substr($reservationPost->reservation_time, 2, 2);
            // 上記に時・分をつける
            $time = $hour.'時'.$minute.'分';
        }

        return view('user.list.edit', compact(
            'categories',
            'post',
            'date',
            'time'
        ));
    }

    /**
     * 記事の更新
     *
     * @param int $post_id 投稿ID
     * @return Response src/resources/views/user/list/index.blade.phpを表示
     */
    public function update(PostRequest $request, $post_id)
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;

        // 投稿IDをもとに特定の投稿データを取得
        $post = $this->post->feachPostDateByPostId($post_id);

        switch (true) {
            // 下書き保存クリック時の処理
            case $request->has('save_draft'):
                $this->post->updatePostToSaveDraft($request, $post);
                $request->session()->flash('updateSaveDraft', '記事を下書き保存で更新しました。');
                break;
            // 公開クリック時の処理
            case $request->has('release'):
                $this->post->updatePostToRelease($request, $post);
                $request->session()->flash('updateRelease', '記事を更新し公開しました。');
                break;
            // 上記以外の処理
            default:
                $this->post->updatePostToSaveDraft($request, $post);
                $request->session()->flash('updateSaveDraft', '記事を下書きで保存しました。');
                break;
        }

        return to_route('user.index', ['id' => $user_id]);
    }

    /**
     * 下書き保存一覧
     *
     * @return Response src/resources/views/user/list/saveDraft.blade.phpを表示
     */
    public function saveDraft()
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;
        // 下書き保存の記事一覧を取得
        $saveDrafts = $this->post->getSaveDraftPosts($user_id);
        return view('user.list.saveDraft', compact(
            'saveDrafts',
        ));
    }

    /**
     * 公開中記事一覧
     *
     * @return Response src/resources/views/user/list/release.blade.phpを表示
     */
    public function release()
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;
        // 公開中の記事一覧を取得
        $releases = $this->post->getReleasePosts($user_id);
        return view('user.list.release', compact(
            'releases',
        ));
    }

    /**
     * 予約公開記事一覧
     *
     * @return Response src/resources/views/user/list/release.blade.phpを表示
     */
    public function reservationRelease()
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;
        // 予約公開の記事一覧を取得
        $reservationPosts = $this->post->getReservationReleasePosts($user_id);
        return view('user.list.reservationRelease', compact(
            'reservationPosts',
        ));
    }
}

記事の編集画面で予約日時を表示させるために画面を修正しましょう。

コントローラー側では、記事のステータスが予約公開であれば予約日時を取得できて値を渡せますが、予約公開以外は値はnullで渡ってきます。

つまり、記事の編集で記事のステータスが下書き保村または公開中であれば、$dateと$timeはnullなので、issetを使って制御しています。

{{-- src/resources/views/layouts/common.blade.php継承 --}}
@extends('layouts.common')

@include('user.parts.sidebar_user')
@section('content')
@if ($post->publish_flg === 0)
    <div class="bg-blue-200 text-center text-blue-700 font-bold">ステータス:下書き保存</div>
@elseif ($post->publish_flg === 1)
    <div class="bg-green-200 text-center text-green-700 font-bold">ステータス:公開中</div>
@elseif ($post->publish_flg === 2)
    <div class="bg-amber-200 text-center text-amber-700 font-bold">ステータス:予約公開</div>
@else
@endif
@if (isset($date) && isset($time))
    <div class="py-2 text-center">
        <span class="px-4">予約公開日:{{ $date }}</span>
        <span class="px-4">予約公開時間:{{ $time }}</span>
    </div>
@endif
<form action="{{ route('post.update', ['post_id' => $post->id]) }}" method="POST" class="p-5">
@csrf
    @if ($errors->any())
        <div class="flex shadow-lg rounded-sm">
            <div class="bg-red-600 py-4 px-6 rounded-l-lg flex items-center">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="fill-current text-white" width="20" height="20">
                    <path fill-rule="evenodd" d="M8.22 1.754a.25.25 0 00-.44 0L1.698 13.132a.25.25 0 00.22.368h12.164a.25.25 0 00.22-.368L8.22 1.754zm-1.763-.707c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0114.082 15H1.918a1.75 1.75 0 01-1.543-2.575L6.457 1.047zM9 11a1 1 0 11-2 0 1 1 0 012 0zm-.25-5.25a.75.75 0 00-1.5 0v2.5a.75.75 0 001.5 0v-2.5z"></path>
                </svg>
            </div>
            <div class="px-4 py-6 bg-red-50 rounded-r-lg justify-between items-center w-full border border-l-transparent border-red-50">
                <div class="text-red-600 text-md font-bold">エラー!</div>
                <ul>
                    @foreach ($errors->all() as $error)
                        <li  class="text-sm text-red-500">{{ $error }}</li>
                    @endforeach
                </ul>
            </div>
        </div>
    @endif
    <div class="flex mt-6 mr-12">
        <div class="m-auto">
            <select name="category" class="block w-64 text-gray-700 py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500">
                <option value="">カテゴリーを選択</option>
                @foreach ($categories as $category)
                    {{-- バリデーションエラー発生時、直前で選択した値を選択した状態にする --}}
                    @if (old('category'))
                        <option value="{{ $category->id }}" @selected(old('category') == $category->id)>{{ $category->category_name }}</option>
                    {{-- 編集画面で、DBに登録しているデータを選択状態にする --}}
                    @elseif ($category->id == $post->category_id)
                        <option value="{{ $category->id }}" @selected($post->category_id)>{{ $category->category_name }}</option>
                    {{-- 上記以外の場合は、選択状態にしない(記事新規作成の初期状態など) --}}
                    @else
                        <option value="{{ $category->id }}">{{ $category->category_name }}</option>
                    @endif
                @endforeach
            </select>
        </div>
        <div>
            {{-- ステータスによって、表示するボタンや文言を変更 --}}
            @if ($post->publish_flg === 0)
                <button type="submit" name="save_draft" class="px-4 py-2 text-white text-lg transition-colors duration-200 transform bg-blue-500 rounded-md hover:bg-blue-400">下書き保存</button>
                <button type="submit" name="release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-green-500 rounded-md hover:bg-green-400">更新して公開</button>
                <button formaction="{{ route('reservation.post.edit', ['post_id' => $post->id]) }}" formmethod="GET" name="reservation_release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-amber-500 rounded-md hover:bg-amber-400">予約公開</button>
            @elseif ($post->publish_flg === 1)
                <button type="submit" name="save_draft" class="px-4 py-2 text-white text-lg transition-colors duration-200 transform bg-blue-500 rounded-md hover:bg-blue-400">下書きに戻す</button>
                <button type="submit" name="release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-green-500 rounded-md hover:bg-green-400">更新して公開</button>
            @elseif ($post->publish_flg === 2)
                <button type="submit" name="save_draft" class="px-4 py-2 text-white text-lg transition-colors duration-200 transform bg-blue-500 rounded-md hover:bg-blue-400">下書きに戻す</button>
                <button type="submit" name="release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-green-500 rounded-md hover:bg-green-400">今すぐ公開</button>
                <button formaction="{{ route('reservation.post.edit', ['post_id' => $post->id]) }}" formmethod="GET" name="reservation_release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-amber-500 rounded-md hover:bg-amber-400">予約日時を変更</button>
            @else
                <button type="submit" name="save_draft" class="px-4 py-2 text-white text-lg transition-colors duration-200 transform bg-blue-500 rounded-md hover:bg-blue-400">下書き保存</button>
                <button type="submit" name="release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-green-500 rounded-md hover:bg-green-400">更新して公開</button>
                <button formaction="{{ route('reservation.post.edit', ['post_id' => $post->id]) }}" formmethod="GET" name="reservation_release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-amber-500 rounded-md hover:bg-amber-400">予約公開</button>
            @endif
        </div>
    </div>
    <div class="w-full mt-4">
        <input type="text" name="title" class="block w-full text-3xl font-bold border-none outline-none" placeholder="タイトルを追加" value="{{ old('title', $post->title) }}"/>
    </div>
    <div class="w-full mt-4">
        <textarea name="body" class="block w-full h-40 px-4 py-2 border-none resize-none text-gray-700 bg-white border rounded-md focus:outline-none focus:ring" placeholder="記事の内容を書いてください">{{ old('body', $post->body) }}</textarea>
    </div>
</form>
@endsection

これで予約公開日時が表示されました。

記事のステータスが予約公開→下書き保存or公開中に更新する場合の処理

まず現状の問題点としては、記事のステータスを予約公開から下書き保存や公開中に更新した時に、ステータスは更新されているが、その記事の予約公開データはreservation_postsテーブルに残ったままです。

投稿ID79が予約公開なのでこれを下書き保存に更新する

reservation_postsテーブルを見ると、まだデータが残ったまま…

記事のステータスは下書き保存にしたので、予約公開データがあるのはおかしいですよね。なので、記事のステータスが予約公開→下書き保存や公開中に更新した時は、reservation_postsテーブルから投稿IDに紐づく予約公開データを削除します。

<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use App\Models\Post;
use App\Models\Category;
use App\Models\ReservationPost;
use App\Http\Requests\PostRequest;

class PostController extends Controller
{
    private $post;
    private $category;
    private $reservationPost;

    public function __construct()
    {
        $this->post = new Post();
        $this->category = new Category();
        $this->reservationPost = new ReservationPost();
    }

    /**
     * 投稿リスト
     *
     * @param int $id ユーザーID
     * @return Response src/resources/views/user/list/index.blade.phpを表示
     */
    public function index(int $id)
    {
        // ユーザーIDと一致する投稿データを取得
        $posts = $this->post->getAllPostsByUserId($id);
        return view('user.list.index', compact(
            'posts',
        ));
    }

    /**
     * 記事投稿画面
     *
     * @return Response src/resources/views/user/list/create.blade.phpを表示
     */
    public function create()
    {
        // カテゴリーデータを全件取得
        $categories = $this->category->getAllCategories();
        return view('user.list.create', compact(
            'categories',
        ));
    }

    /**
     * 記事投稿処理
     *
     * @param string $request リクエストデータ
     * @return Response src/resources/views/user/list/index.blade.phpを表示
     */
    public function store(PostRequest $request)
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;

        switch (true) {
            // 下書き保存クリック時の処理
            case $request->has('save_draft'):
                $this->post->insertPostToSaveDraft($user_id, $request);
                $request->session()->flash('saveDraft', '記事を下書きで保存しました。');
                break;
            // 公開クリック時の処理
            case $request->has('release'):
                $this->post->insertPostToRelease($user_id, $request);
                $request->session()->flash('release', '記事を公開しました。');
                break;
            // 上記以外の処理
            default:
                $this->post->insertPostToSaveDraft($user_id, $request);
                $request->session()->flash('saveDraft', '記事を下書きで保存しました。');
                break;
        }

        return to_route('user.index', ['id' => $user_id]);
    }

    /**
     * 記事詳細
     *
     * @param int $post_id 投稿ID
     * @return Response src/resources/views/user/list/show.blade.phpを表示
     */
    public function show($post_id) {
        // リクエストされた投稿IDをもとにpostsテーブルから一意のデータを取得
        $showPostData = $this->post->feachPostDateByPostId($post_id);
        return view('user.list.show', compact(
            'showPostData',
        ));
    }

    /**
     * 記事編集
     *
     * @param int $post_id 投稿ID
     * @return Response src/resources/views/user/list/edit.blade.phpを表示
     */
    public function edit($post_id)
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;

        // カテゴリーデータを全件取得
        $categories = $this->category->getAllCategories();
        // 投稿IDをもとに特定の投稿データを取得
        $post = $this->post->feachPostDateByPostId($post_id);

        // 記事のステータスが予約公開以外はそもそも予約公開データはないので初期値はnullをセット
        $date = null;
        $time = null;
        // 投稿IDをもとに予約公開データを取得
        $reservationPost = $this->reservationPost->getReservationPostByUserIdAndPostId($user_id, $post_id);
        // 予約公開データがあれば予約日時を取得
        if (isset($reservationPost)) {
            // 年・月・日にそれぞれ文字を切り出し
            // (20220530→2022)
            $year = substr($reservationPost->reservation_date, 0, 4);
            // (20220530→05)
            $month = substr($reservationPost->reservation_date, 4, 2);
            // (20220530→30)
            $day = substr($reservationPost->reservation_date, 6, 2);
            // 上記に年月日をつける(2022年05月30日)
            $date = $year.'年'.$month.'月'.$day;

            // 時・分にそれぞれ文字を切り出し
            // (083200→08)
            $hour = substr($reservationPost->reservation_time, 0, 2);
            // (083200→32)
            $minute = substr($reservationPost->reservation_time, 2, 2);
            // 上記に時・分をつける
            $time = $hour.'時'.$minute.'分';
        }

        return view('user.list.edit', compact(
            'categories',
            'post',
            'date',
            'time'
        ));
    }

    /**
     * 記事の更新
     *
     * @param int $post_id 投稿ID
     * @return Response src/resources/views/user/list/index.blade.phpを表示
     */
    public function update(PostRequest $request, $post_id)
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;

        // 投稿IDをもとに特定の投稿データを取得
        $post = $this->post->feachPostDateByPostId($post_id);

        // 投稿IDをもとに予約公開データを取得
        $reservationPost = $this->reservationPost->getReservationPostByUserIdAndPostId($user_id, $post_id);

        switch (true) {
            // 下書き保存クリック時の処理
            case $request->has('save_draft'):
                // 記事のステータスを下書き(publish_flg=0)に更新
                $this->post->updatePostToSaveDraft($request, $post);
                // 上記でもしデータがあれば、ステータスを下書きに戻すため予約公開データは不要のため削除する
                if (isset($reservationPost)) {
                    // 予約公開データの削除
                    $this->reservationPost->deleteData($reservationPost);
                }
                $request->session()->flash('updateSaveDraft', '記事を下書き保存で更新しました。');
                break;
            // 公開クリック時の処理
            case $request->has('release'):
                // 記事のステータスを公開(publish_flg=1)に更新
                $this->post->updatePostToRelease($request, $post);
                // 上記でもしデータがあれば、ステータスを下書きに戻すため予約公開データは不要のため削除する
                if (isset($reservationPost)) {
                    // 予約公開データの削除
                    $this->reservationPost->deleteData($reservationPost);
                }
                $request->session()->flash('updateRelease', '記事を更新し公開しました。');
                break;
            // 上記以外の処理
            default:
                // 記事のステータスを下書き(publish_flg=0)に更新
                $this->post->updatePostToSaveDraft($request, $post);
                // 上記でもしデータがあれば、ステータスを下書きに戻すため予約公開データは不要のため削除する
                if (isset($reservationPost)) {
                    // 予約公開データの削除
                    $this->reservationPost->deleteData($reservationPost);
                }
                $request->session()->flash('updateSaveDraft', '記事を下書きで保存しました。');
                break;
        }

        return to_route('user.index', ['id' => $user_id]);
    }

    /**
     * 下書き保存一覧
     *
     * @return Response src/resources/views/user/list/saveDraft.blade.phpを表示
     */
    public function saveDraft()
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;
        // 下書き保存の記事一覧を取得
        $saveDrafts = $this->post->getSaveDraftPosts($user_id);
        return view('user.list.saveDraft', compact(
            'saveDrafts',
        ));
    }

    /**
     * 公開中記事一覧
     *
     * @return Response src/resources/views/user/list/release.blade.phpを表示
     */
    public function release()
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;
        // 公開中の記事一覧を取得
        $releases = $this->post->getReleasePosts($user_id);
        return view('user.list.release', compact(
            'releases',
        ));
    }

    /**
     * 予約公開記事一覧
     *
     * @return Response src/resources/views/user/list/release.blade.phpを表示
     */
    public function reservationRelease()
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;
        // 予約公開の記事一覧を取得
        $reservationPosts = $this->post->getReservationReleasePosts($user_id);
        return view('user.list.reservationRelease', compact(
            'reservationPosts',
        ));
    }
}

モデルに予約公開データを削除するdeleteDataを追加します。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class ReservationPost extends Model
{
    /**
     * モデルに関連付けるテーブル
     *
     * @var string
     */
    protected $table = 'reservation_posts';

    /**
     * 複数代入可能な属性
     *
     * @var array
     */
    protected $fillable = [
        'user_id',
        'post_id',
        'reservation_date',
        'reservation_time',
        'created_at',
        'updated_at'
    ];

    /**
     * 予約公開設定データをDBにinsert
     *
     * @param $post 投稿データ
     * @param $reservation_date 予約公開_日付
     * @param $reservation_time 予約公開_時間
     */
    public function insertReservationPostData($post, $reservation_date, $reservation_time)
    {
        return $this->create([
            'user_id' => $post->user_id,
            'post_id' => $post->id,
            'reservation_date' => $reservation_date,
            'reservation_time' => $reservation_time
        ]);
    }

    /**
     * ユーザーIDと投稿IDをもとに予約公開予定の投稿データを取得
     *
     * @param int $user_id ユーザーID
     * @param int $post_id 投稿ID
     */
    public function getReservationPostByUserIdAndPostId($user_id, $post_id)
    {
        return $this->where([
            ['user_id', $user_id],
            ['post_id', $post_id]
        ])
        ->first();
    }

    /**
     * 予約公開データを更新
     *
     * @param $reservationPost 予約公開データ
     * @param $reservation_date 予約日付
     * @param $reservation_time 予約時間
     */
    public function updateReservationPost($reservationPost, $reservation_date, $reservation_time)
    {
        return $reservationPost->fill([
            'reservation_date' => $reservation_date,
            'reservation_time' => $reservation_time,
        ])->save();
    }

    /**
     * 予約公開データの削除
     *
     * @param $reservationPost 予約公開データ
     */
    public function deleteData($reservationPost)
    {
        return $reservationPost->delete();
    }
}

これで予約公開→下書き保存や公開中に更新した場合は、予約公開テーブルから投稿IDに紐づくデータが削除されました。

ゴミ箱に移動、記事を完全に削除した場合も予約公開データをテーブルから削除する

今度は、ゴミ箱に移動または記事を完全に削除した場合にも予約公開データをテーブルから削除しましょう。

なぜなら、記事をゴミ箱に移動する=記事のステータスは下書き保存にする、記事を完全に削除する=そもそも記事がなくなるので、予約公開データも必要ないからです。

ゴミ箱関連は、Trashコントローラーに書いているのでそこをいじります。

<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\Post;
use App\Models\Category;
use App\Models\ReservationPost;

class TrashController extends Controller
{
    private $post;
    private $category;
    private $reservationPost;

    public function __construct()
    {
        $this->post = new Post();
        $this->category = new Category();
        $this->reservationPost = new ReservationPost();
    }

    /**
     * ゴミ箱一覧
     *
     * @return Response src/resources/views/user/list/trash.blade.phpを表示
     */
    public function trashList()
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;

        // ユーザーIDをもとに、論理削除されているdelete_flg=1のデータを取得
        $trash_posts = $this->post->getTrashPostLists($user_id);
        return view('user.list.trash', compact(
            'user_id',
            'trash_posts',
        ));
    }

    /**
     * 記事の論理削除(ゴミ箱に移動)
     *
     * @param int $post_id 投稿ID
     */
    public function moveTrash($post_id)
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;

        // 投稿IDをもとに特定の投稿データを取得
        $post = $this->post->feachPostDateByPostId($post_id);

        // ユーザーIDと投稿IDをもとに更新する予約公開記事のデータを1件取得
        $reservationPost = $this->reservationPost->getReservationPostByUserIdAndPostId($user_id, $post_id);
        // 予約公開データがあるか
        if (isset($reservationPost)) {
            // 該当する公開予約データを削除
            $this->reservationPost->deleteData($reservationPost);
        }

        // 記事を論理削除(ゴミ箱に移動)
        $trashPost = $this->post->moveTrashPostData($post);

        // マイページ投稿リストにリダイレクト
        return to_route('user.index', ['id' => $user_id])->with('moveTrash', '記事をゴミ箱に移動しました。');
    }

    /**
     * 記事の復元
     *
     * @param int $post_id 投稿ID
     */
    public function restore($post_id)
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;

        // ユーザーIDをもとに、論理削除されているdelete_flg=1のデータを取得
        $trash_posts = $this->post->getTrashPostLists($user_id);

        // 投稿IDをもとに特定の投稿データを取得
        $post = $this->post->feachPostDateByPostId($post_id);

        // 記事の復元
        $restorePost = $this->post->restorePostData($post);

        // ゴミ箱にリダイレクト
        return to_route('post.trash', compact(
            'user_id',
            'trash_posts',
        ))
        ->with('restore', '記事を復元しました。');
    }

    /**
     * 記事をゴミ箱から削除(物理削除なので、完全にデータを削除する)
     *
     * @param int $post_id 投稿ID
     */
    public function delete($post_id)
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;

        // ユーザーIDをもとに、論理削除されているdelete_flg=1のデータを取得
        $trash_posts = $this->post->getTrashPostLists($user_id);

        // 投稿IDをもとに特定の投稿データを取得
        $post = $this->post->feachPostDateByPostId($post_id);

        // ユーザーIDと投稿IDをもとに更新する予約公開記事のデータを1件取得
        $reservationPost = $this->reservationPost->getReservationPostByUserIdAndPostId($user_id, $post_id);
        // 予約公開データがあるか
        if (isset($reservationPost)) {
            // 該当する公開予約データを削除
            $this->reservationPost->deleteData($reservationPost);
        }

        // 記事を物理削除(ゴミ箱からも削除)
        $deletePost = $this->post->deletePostData($post);
        // ゴミ箱にリダイレクト
        return to_route('post.trash', compact(
            'user_id',
            'trash_posts',
        ))
        ->with('delete', '記事を完全に削除しました。');
    }
}

はい、これで予約公開機能②は終了です〜

次回は予約公開機能③でコマンドを自作で作ります。

コマンドをパーン!って1つ叩き、予約日時をすぎていれば、予約公開設定したデータを公開するみたいな処理書いていきます。

>>>予約公開機能③へ進む

>>ココナラと似てるおすすめの副業サイトを確認する

>>リモートワークもあるおすすめの転職サイトを確認する

休日で空いた時間の暇つぶしを探せるアプリを公開しています。

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

コメント

コメントする

CAPTCHA


Contents
閉じる