Task Schedulerでユーザーごとに、データベースに保存した時間にコマンドを実行する

プログラミング初心者です。

##開発環境
Laravel 5.8
PHP 7.3.24
MAMP

##やりたいこと
Kernel.phpに、ユーザーごとに「毎日」、かつ「データベースに保存した時間」にコマンドを実行させるように実装したい。
参考サイト[こちら](https://qiita.com/nicopinpin/items/29dbdd666433253839ce)

##1　Migrate
まずユーザー側から設定された時間を保存するための、migrateファイルを作成します。

```create_samples_table.php
class CreatePushesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('samples', function (Blueprint $table) {
            $table->bigIncrements('id');
            //UserTableのidを保存するカラム
            $table->unsignedBigInteger('user_id');
            //時間を保存するカラム。型は時間なのでtime。時間を設定しない場合もあるためNULLで保存できるようにしています。
            $table->time('sample_time')->nullable(true);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('samples');
    }
}
```

##2 Model
Modelを作成します。

```Sample.php
class Push extends Model
{
    protected $guarded = array('id');
    public static $rules = array(
        'user_id' => 'required',
        'sample_time' => 'required',
    );

    //user_idカラムにUser Modelのidを保存したいため、リレーションします。
    public function user()
{
    //User.phpにもSample.phpとhasOneでリレーションしています。
    return $this->belongsTo('App\User');
}
}
```

##3 Kernel.php
Kernel.phpはLaravelには二つありますが、```app/Console/Kernel.php```を開いてください。
そしてすでにSample Modelのsample_timeに時間が保存されたとします。

```Kernel.php
namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
//Sample.phpデータを使いたいため
use App\Sample;


class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    //自分で作成したコマンドの登録をします。
    protected $commands = [
        Commands\SampleCommand::Class,
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    //タスクをスケジュールする
    protected function schedule(Schedule $schedule)
    {
        //ここでは毎日、ユーザーが設定した時間に実行するというスケジュールにします。
        $samples = Sample::all();
        foreach($samples as $sample) {
            //時間を文字列にしています
            $sampletime = date('H:i',strtotime($sample->sample_time));
            $schedule->command("SampleCommand {$sample->user_id}")->dailyAt($sampletime);
        }
    }
```
###解説
```protected function schedule```の中身を解説します。
<dl>
 <dt>```$samples = Sample::all();```</dt>
  <dd>Sample Modelの全てを取得し、$samplesに代入します。</dd>
 <dt>```foreach($samples as $sample)```</dt>
  <dd>foreachでsamples を $sampleとして繰り返します。</dd>
 <dt>```$sampletime = date('H:i',strtotime($sample->sample_time));```</dt>
  <dd>時間をdateメソッドとstrtotimeメソッド使って文字列に変えています。
なぜならdailyAtメソッドの型は文字列でなければなりません。そのためtime型からstring型に変える必要があります。
参考サイト[こちら](https://tetechi.com/php-strtotime/)</dd>
 <dt>```$schedule->command("SampleCommand {$sample->user_id}")->dailyAt($sampletime);```</dt>
  <dd>・　```$schedule```はprotected function scheduleの引数です。
・　commandメソッドに実行したいコマンド名を入力します。そして今回は”ユーザーごとにコマンド実行”なので引数を設定していて、$sampleからuser_idカラムを取得しています。引数の設定は作成したコマンドファイルの中で実装しています。
・　dailyAtメソッドですが、毎日実行という意味です。メソッド内には文字列型に変えた```$sampletime```が入ります。Task Scheduleにはスケジュールオプションがあり[Document](https://readouble.com/laravel/5.7/ja/scheduling.html)に載っておりますので、参考にどうぞ。
</dl>

##4 Cronの設定
- Kernel.phpのタスクを実行するには、cronの設定が必要です。
（laravelのversion 8.xからだと設定は必要がないみたいです。）
- Vimで編集するのですが、文面だけでは説明が難しいため、[こちら](https://tektektech.com/laravel-taskscheduling-with-cron/)のサイトがわかりやすいため、参考にどうぞ。
- 米印の部分は```*****```5個のままで大丈夫です！
- 実行するコマンドファイルにLogを記載するように実装すると実行されたかどうか分かりやすいです。そして設定した時間に実行されたら成功です！

もし、cronがそもそもちゃんと動くのかを確認したい場合、私がした実装はコメントアウトして、参考サイトのようにeveryMinuteメソッドで毎分実行されるように実装すれば早く確認できます。
あと、cronは設定すると動き続けてしまうので、当分使わないなと思ったら消してもいいと思います。

ここまでお疲れ様でした！