Search code examples
phplaravelcron

Laravel custom command and Scheduler: how to know where the error stands


I'm developing a blog platform with Laravel 5.6 and posts' publication can be scheduled. To achieve it, I:

  1. Created the post:publish {id} command through PostPublish class, placed in Console/Commands folder.
  2. Based on what the documentation says, the command is automatically loaded because in Console/Commands, so I didn't registered into the $commands property in Console/Kernel.php (if I run php artisan list, post:publish is indeed listed).
  3. Whenever a user schedules a post, the post is inserted into the blog_posts table classified as scheduled and a new record is added into tasks table (id, command, cron). e.g. 4, post:publish 56, 17 11 18 9 2.
  4. I added the Laravel's Scheduler Cron entry on the server to run every minute, replacing >> /dev/null 2>&1 with the path of the log file: * * * * * /opt/alt/php71/usr/bin/php /home/qs266dg7/public_html && php artisan schedule:run >> /home/qs266dg7/public_html/app/Console/cron.log
  5. To set the cronjob dynamically, I decided to use this solution at the moment (although I don't think is the most efficient one). So, in the schedule() method inside the Kernel{} class I get all the entries of tasks table, running the command() method per each one.

The problem: the post's status doesn't change as it's stated in handle() method of the PostPublish class and I don't know how to understand where the problem stands, since everything is done automatically on the server. Laravel's appendOutputTo() didn't produce any output in cron.log, that's why I set >> /home/qs266dg7/public_html/app/Console/cron.log. What the log file now contains is a long list of:

Status: 404 Not Found
X-Powered-By: PHP/7.1.20
Content-type: text/html; charset=UTF-8

No input file specified.

Where does the problem lie? In the command? In the execution of it? In the cron? How can I know it?


app/Console/Commands/ PostPublish.php

class PostPublish extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'post:publish {id}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Publish posts that have been scheduled';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $post = BlogPost::find($this->argument('id'));
        $post->status = "published";
        $post->published_at = $post->scheduled_at;
        $post->scheduled_at = null;
        return $post->save();
    }
}

app/Console/ Kernel.php

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        //
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $tasks = Task::all();
        foreach ($tasks as $task) {
            $schedule->command($task->command)
                ->cron($task->cron)
                ->appendOutputTo('/home/qs266dg7/public_html/storage/app/Console/cron.log');
        }
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}

Solution

  • You can check by creating the log

    use Log;
    
    class PostPublish extends Command
    {
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'post:publish {id}';
    
    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Publish posts that have been scheduled';
    
    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }
    
    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
         try{
                $post = BlogPost::find($this->argument('id'));
                $post->status = "published";
                $post->published_at = $post->scheduled_at;
                $post->scheduled_at = null;
                return $post->save();
    
            }
            catch (Exception $e) {
                Log::alert($e);
            }
    }
    

    }

    you can check your log in this file

    storage/logs/laravel.log