Published on

Programar una tarea en Laravel

Authors

Aprende a crear una tarea en Laravel con envío de correo incluido, y deja la tarea programada de forma permanente en tu servidor.

Laravel cuenta con Task Scheduling para el trabajo de tareas programadas, con esta funcionalidad podemos automatizar nuestro proyecto para que haga una serie de funciones en el intervalo de tiempo que queramos.

En este artículo, vamos a aprender a automatizar  nuestra aplicación Laravel con scheduling. Para crear la tarea vamos a dividir el proceso en tres fases:

1 - Creación del comando

2 - Configuración del envío de email

3 - Programación del comando

CREACIÓN COMANDO

Paso 1: Crear el comando

php artisan make:command RegisteredVisits --command=registered:visits

El comando anterior creará una clase llamada RegisteredVisits en un archivo con el mismo nombre en la carpeta app/Console/Commands. Al ejecutar el comando Artisan, también le hemos dado un nombre al comando que ejecutará la tarea. 

Paso 2: Modificamos el archivo creado

Entramos al archivo que hemos creado en la ruta "app/Console/Commands/RegisteredVisits.php" y modificamos la descripción del comando:


    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Envía un correo con las visitas diaria del blog';


Paso 3: Registramos el comando

Accedemos al archivo "app/Console/Kernel.php" y registramos nuestro archivo:

    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        'App\Console\Commands\RegisteredVisits',
    ];


Si ejecutamos el comando "php artisan list" desde la terminal, deberíamos poder ver el comando registrado en el listado, más en concreto en registered.

Paso 4: Creamos el código

Dentro del archivo RegisteredVisits, creamos la consulta que nos dará las visitas diarias.

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $date_now = now()->format('Y-m-d');
        $visits = \DB::table('logs')->whereDate('created_at',$date_now)->get();
    }


CONFIGURACIÓN MAIL

Paso 1: Crear clase Mailable para el envío de email

php artisan make:mail SendMail

Esto creará el archivo dentro de app/Mail/SendMail.php .

class SendMail extends Mailable
{
    use Queueable, SerializesModels;

    public $visits;
    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($visits)
    {
        $this->visits = $visits;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('mails.daily-visits');
    }
}


Dentro del archivo, creamos una propiedad $visitis, y la inicializamos en el constructor con el parámetro $visits que pasamos al instanciar la clase SandMail. Por último, enviamos los datos desde el método build a la vista.

En mi caso,  yo dentro de  resources\views tengo creada una carpeta mails, y ahí dentro voy creando las plantillas de correo que voy generando. En este caso la ruta sería :

resources\views\mails\daily-visits.blade.php 

Paso 2: Configurar el contenido del correo

En este caso, como es un reporte propio solo voy a incluir un titulo, un par de párrafos y una tabla

<h1><strong> Reporte díario con la visita del blog </strong> </h1>

<p>Hoy, {{now()->format('d-m-Y')}} se han registrado un total de {{count($visits)}} visitas en la web.</p>

<p>Las páginas visitas han sido:</p>
<div>
    <table>
        <tr class="bg-indigo-400 bg-opacity-100 text-white">
                <th class="text-left">Página</th>
                <th class="text-left">Fecha</th>

        </tr>
        <tbody>
            @forelse ($visits as $visit)
                <tr class="border-b-2">
                    <td>  {{$visit->page}}   </td>
                    <td>  {{$visit->created_at}}   </td>
                </tr>
            @endforeach
        </tbody>
    </table>
</div>


Paso 3: Registramos el mail

Accedemos al fichero "app/Console/Commands/RegisteredVisits.php" y agregamos la clase  

use Illuminate\Support\Facades\Mail; use App\Mail\SendMail;

Y en el método handler lo completamos así:

   /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $date_now = now()->format('Y-m-d');
        $visits = \DB::table('logs')->whereDate('created_at',$date_now)->get();
       
        Mail::to('blognotasdesarrolloweb@gmail.com')->send(new SendMail($visits));
    }


PROGRAMACIÓN DEL COMANDO

Como la tarea la ejecutaremos una  vez al día, usaremos el método "daily()". Para eso debemos registrarlo en el archivo "app/Console/Kernel.php"  dentro de la función schedule.

   /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('registered:visits')->daily();
     
    }


Al método daily()  se ejecutará a medianoche. Si quisiéramos que se ejecutará la tarea una vez al día pero en otra hora distinta, habría que usar el método dailyAt pasándole un parámetro de tipo string, con la hora en la que queremos que se ejecute. Ejemplo:  ->dailyAt('13:00') .

Si quieres saber más sobre los tramos que existen, aquí te dejo el enlace a la documentación de scheduling de Laravel.

Finalmente, desde la consola de comandos de nuestro servidor, ejecutamos el siguiente comando

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

Si lo quieres probar en local (localhost), debes escribir el siguiente comando:

php artisan schedule:run

Si quieres ver si funciona en el momento, puedes cambiar el método daily por everyMinute, así podrás ver si has configurado todo el proceso correctamente. Quedando algo así:


Si te gustó está entrada y crees que puede ser de utilidad o interés,  comparte este artículo en tus redes sociales 😉 👍


3259