Writing Commands and Scheduling in Laravel 5.1

Posted: 2015-05-29 11:24:49

Wow, writing Artisan Commands just become even easier. And plugging it into Scheduler makes for a great combination.

For example we need to clean out a folder every so many minutes. The example below I also for fun play around with progress and table output.

Note too protected $signature = 'approve:cleanuploads {--minutes=10}'; simplifies theargument and options features.

<?php namespace App\Console\Commands;

use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;

class CleanUploadsCommands extends Command
{
    protected $rootPath     = 'public/storage';
    protected $maxMinutes   = 10;
    protected $deleted      = [];
    protected $signature    = 'approve:cleanuploads {--minutes=10}';
    protected $description  = 'Clean all the uploads in the storage folder for security reasons';
    protected $pdfFiles     = [];
    protected $files        = [];

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        $this->maxMinutes = $this->option('minutes');
        $this->anyPdfFilesHere();
        $this->deletePdfFiles();
        $this->outputResults();
    }

    protected function anyPdfFilesHere()
    {
        $this->files = File::allFiles(base_path($this->rootPath));

        foreach($this->files as $file)
        {
            if (File::mimeType($file) == 'application/pdf')
            {
                $this->pdfFiles[] = $file;
            }
        }
    }

    private function deletePdfFiles()
    {
        if(count($this->pdfFiles) > 0)
        {
            $this->output->progressStart(count($this->pdfFiles));

            foreach($this->pdfFiles as $file)
            {
                $modified = File::lastModified($file);

                $minutes = Carbon::createFromTimestamp($modified)->diffInMinutes();

                if($minutes > $this->maxMinutes)
                {
                    $this->setDeleted(['filename' => $file]);
                    File::delete($file);
                    $this->output->progressAdvance();
                }
            }
        }
    }

    private function outputResults()
    {
        if(count($this->deleted) > 0)
        {
            $this->output->progressFinish();
            $headers = ['File Name and Path'];
            $this->table($headers, $this->getDeleted());
        }
        else
        {
            $this->comment(sprintf("No files older than %d minutes", $this->maxMinutes));
        }
    }

    public function getDeleted()
    {
        return $this->deleted;
    }

    public function setDeleted($deleted)
    {
        $this->deleted[] = $deleted;
    }


}

Then in the Kernel.php I enter

<?php namespace Approve\Console;


use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

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

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('approve:cleanuploads --minutes=10')
                 ->everyMinute();
    }
}

And that is it.

One big thing about Commands is the power of Asynchronous processing that libraries like Symfony Process gives us the ability to run numerous commands at once!

running