Menu Docs
Página inicial do Docs
/ /

Tutorial: Criar um Lembrete de Tarefa com Laravel e MongoDB

Neste tutorial, você aprenderá a usar o MongoDB em um aplicação Laravel criando um sistema simples de alerta de tarefas. O aplicação permite criar, ler, atualizar e excluir tarefas. Além disso, ele envia alertas por e-mail para as próximas tarefas com base em um horário agendado.

Antes de iniciar este tutorial, verifique se você tem os seguintes componentes instalados em seu ambiente de desenvolvimento:

  • PHP e a extensão PHP do MongoDB

  • Laravel

  • Composer

  • NPM

Você também deve configurar um cluster MongoDB Atlas . Para saber como configurar um cluster, consulte o guia de Introdução.

1

Use o Composer para criar um novo projeto Laravel e navegue até o diretório do projeto :

composer create-project laravel/laravel LaravelMongodbProject
cd LaravelMongodbProject
2

Para utilizar MongoDB em seu aplicação , você deve instalar o pacote Laravel MongoDB e configurá-lo no arquivo config/database.php.

Instale o pacote usando o seguinte comando:

composer require mongodb/laravel-mongodb

Dica

Se você encontrar um erro ao executar o comando anterior, certifique-se de que a extensão MongoDB PHP esteja instalada. Para saber como instalar, consulte a etapa Instalar a extensão MongoDB PHP no guia de Introdução.

3

Após a conclusão da instalação do pacote Laravel MongoDB , adicione sua conexão do banco de dados MongoDB ao arquivo config/database.php para concluir a configuração. Adicione a seguinte configuração MongoDB à array connections que contém configurações para outros tipos de banco de dados :

return [
'connections' => [
'mongodb' => [
'driver' => 'mongodb',
'dsn' => env('MONGODB_URI'),
'database' => 'task_reminder',
],
// Other connections here
],
];

Seu aplicação obtém o valor dsn do arquivo .env. Navegue até seu arquivo .env. Em seguida, crie um valor para MONGODB_URI e defina-o para o valor da sua string de conexão do MongoDB .

Dica

Para obter sua string de conexão do MongoDB , navegue até seu cluster no MongoDB Atlas. Clique no Connect botão e clique no Drivers Connect your applicationem. Selecione "PHP" no Driver menu de seleção. Copie a string de conexão da caixa de diálogo. Para obter etapas detalhadas sobre como obter sua string de conexão, consulte create-a-connection-string.

Em seu arquivo .env, defina o valor DB_CONNECTION como mongodb para torná-la a conexão padrão do seu aplicação. Edite o valor SESSION_DRIVER e defina-o para mongodb conforme mostrado no seguinte código:

MONGODB_URI=mongodb+srv://YOUR_MONGODB_CONNECTION_STRING
DB_CONNECTION=mongodb
// Other DB_ values here ...
SESSION_DRIVER=mongodb
4

Depois de instalar e configurar seu aplicação para funcionar com o MongoDB, configure a autenticação. O Laravel simplifica a implementação de autenticação fornecendo pacotes como Laravel MongoDB, Laravel Fortify e Laravel Jetstream. Este tutorial usa o Laravelbreize para autenticação.

Instale o Laravel MongoDB usando o Composer:

composer require laravel/breeze --dev

Após a conclusão da instalação, execute os seguintes comandos:

php artisan key:generate
php artisan breeze:install
php artisan migrate
php artisan db:seed
npm install
npm run dev

Isso solicitará que você escolha sua pilha preferida e pacote de teste . Para este tutorial, selecione a primeira opção, Lâmina com Alpino:

┌ Which Breeze stack would you like to install? ───────────────┐
│ > ● Blade with Alpine │
│ ○ Livewire (Volt Class API) with Alpine │
│ ○ Livewire (Volt Functional API) with Alpine │
│ ○ React with Inertia │
│ ○ Vue with Inertia │
│ ○ API only │
└──────────────────────────────────────────────────────────────┘

Este comando adiciona visualizações de autenticação, rotas, drivers e outros recursos relacionados ao seu aplicação.

5

O Laravel Acesa cria um modelo de usuário padrão para bancos de dados SQL. Você deve atualizá-lo para funcionar com o MongoDB e resolver problemas de compatibilidade de limitação de taxa.

Abra o app/Models/User.php e substitua seu conteúdo pelo seguinte:

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Notifications\Notifiable;
use MongoDB\Laravel\Auth\User as MongoUser;
class User extends MongoUser {
use HasFactory, Notifiable;
protected $connection = 'mongodb';
protected $collection = 'users';
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes to cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
}
6

Envie o projeto usando o servidor integrado do Laravel e confirme se tudo funciona corretamente. No diretório do projeto Laravel, execute o seguinte comando:

php artisan serve

O projeto atende às 127.0.0.1:8000. Se a porta 8000 já estiver em uso, o Laravel mudará para uma nova porta disponível, que imprime no terminal.

Para testar o sistema de autenticação, selecione o botão Register em seu aplicação e crie uma nova conta de usuário. Isso armazena o usuário em seu banco de dados MongoDB e permite que você faça login com essas credenciais. Para este tutorial, você pode definir o nome de usuário como test@example.com e a senha como password.

Para verificar se o pacote Laravel MongoDB foi configurado corretamente, crie uma rota para ping em seu Cluster MongoDB . Adicione o seguinte a routes/web.php:

Route::get('/ping', function (Request $request) {
$connection = DB::connection('mongodb');
try {
$connection->command(['ping' => 1]);
$msg = 'MongoDB is accessible!';
} catch (\MongoDB\Driver\Exception\ConnectionException $e) {
$msg = 'You are not connected to MongoDB. Error: ' . $e->getMessage();
}
return ['msg' => $msg];
});

Visite esta rota no seu navegador. Com a configuração correta, você verá a mensagem "O MongoDB está acessível! " no seu navegador.

7

Crie o modelo e o controlador para o recurso de agendamento de tarefas usando o seguinte comando:

php artisan make:model Task --resource --controller

Este comando cria o modelo Task no diretório app/Models e o TaskController no diretório app/Http/Controllers com métodos de recursos.

Crie uma rota para o TaskController navegando até routes/web.php e adicionando o seguinte código:

use App\Http\Controllers\TaskController;
// Other route definitions...
Route::resource('tasks', TaskController::class)->middleware('auth');
8

Navegue até app/Models/Task.php e substitua o conteúdo do arquivo pelo seguinte código:

<?php
namespace App\Models;
use MongoDB\Laravel\Eloquent\Model;
class Task extends Model {
protected $connection = 'mongodb';
protected $table = 'tasks';
protected $fillable = [
'title',
'description',
'due_date',
'email',
'reminder_time',
'last_notification_date'
];
}

Este código cria o modelo de tarefa com as seguintes especificações:

  • A declaração use MongoDB\Laravel\Eloquent\Model após o namespace é específica para os modelos do MongoDB . Ele substitui os recursos Eloquent implementados com SQL usando consultas MongoDB .

  • A propriedade protected $table = 'tasks' é opcional. Especifica o nome da collection MongoDB usada para armazenar os documentos deste modelo.

  • A propriedade protected $fillable especifica as propriedades atribuíveis em massa.

Dica

Uma das funcionalidades exclusivas do MongoDB é que ele não exige migrações como os bancos de dados relacionais. Você pode adicionar novos campos diretamente aos seus documentos sem atualizar o modelo ou criar migrações. Esta funcionalidade é útil para lidar com dados dinâmicos.

9

Navegue até app/Http/Controllers/TaskController.php e atualize o conteúdo com o seguinte código:

<?php
namespace App\Http\Controllers;
use App\Models\Task;
use Carbon\Carbon;
use Illuminate\Http\Request;
class TaskController extends Controller {
/**
* Displays a listing of the resource.
*/
public function index()
{
$tasks = Task::where('email', auth()->user()->email)->get();
return view('tasks.index', compact('tasks'));
}
/**
* Shows the form for creating a new resource.
*/
public function create()
{
return view('tasks.create');
}
/**
* Stores a newly created resource in storage.
*/
public function store(Request $request)
{
$data = $request->validate([
'title' => 'required|string|max:255',
'description' => 'nullable|string',
'due_date' => 'required|date',
'reminder_time' => 'required|date',
]);
$data['due_date'] = Carbon::parse($request->due_date);
$data['reminder_time'] = Carbon::parse($request->reminder_time);
$data['email'] = auth()->user()->email;
$data['last_notification_date'] = null;
Task::create($data);
return redirect()->route('tasks.index')->with('success', 'Task created successfully.');
}
/**
* Displays the specified resource.
*/
public function show(string $id)
{
//
}
/**
* Shows the form for editing the specified resource.
*/
public function edit(string $id)
{
$tasks = Task::where('id', $id)->get();
return view('tasks.edit', ['tasks' => $tasks]);
}
/**
* Updates the specified resource in storage.
*/
public function update(Request $request, string $id)
{
$data = $request->validate([
'title' => 'required|string|max:255',
'description' => 'nullable|string',
'due_date' => 'required|date',
'reminder_time' => 'required|date',
]);
$task = Task::findOrFail($id);
$data['due_date'] = Carbon::parse($request->due_date)->format('Y-m-d H:i:s');
$data['reminder_time'] = Carbon::parse($request->reminder_time)->format('Y-m-d H:i:s');
$task->update($data);
return redirect()->route('tasks.index')->with('success', 'Task updated successfully.');
}
/**
* Removes the specified resource from storage.
*/
public function destroy(string $id)
{
$task = Task::findOrFail($id);
$task->delete();
return redirect()->route('tasks.index')->with('success', 'Task deleted successfully.');
}
}

A classe TaskController contém código que lida com as operações CRUD do modelo de tarefa:

  • O método index() recupera todas as tarefas pertencentes ao usuário conectado e as envia para o arquivo index.blade.php para exibição.

  • O método create() retorna a visualização do formulário para criar uma nova tarefa.

  • O método store() valida a entrada, atribui o e-mail do usuário conectado à tarefa e a salva no banco de dados.

  • O método edit() recupera a tarefa específica a ser editada e a exibe em um formulário de edição.

  • O método update() salva a tarefa editada na coleção de tarefas do MongoDB .

  • O método destroy() exclui uma tarefa específica.

Cada operação redireciona de volta para a lista de tarefas com uma mensagem de sucesso para feedback do usuário.

10

No diretório resources/views, crie uma pasta denominada tasks e crie os seguintes arquivos nela:

  • create.blade.php

  • edit.blade.php

  • index.blade.php

Navegue até resources/views/tasks/create.blade.php e adicione o seguinte conteúdo:

1<x-app-layout>
2 <x-slot name="header">
3 <h2 class="font-semibold text-xl text-gray-800 leading-tight">
4 {{ __('Tasks') }}
5 </h2>
6 </x-slot>
7
8 <div class="py-12">
9 <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
10 <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
11 <div class="container mx-auto p-4">
12 <h2 class="text-2xl font-bold mb-4">Create New Task</h2>
13
14 <form action="{{ route('tasks.store') }}" method="POST">
15 @csrf
16
17 <div class="mb-4">
18 <label for="title" class="block text-gray-700">Title:</label>
19 <input type="text"
20 name="title"
21 id="title"
22 required
23 class="border border-gray-300 p-2 w-full"
24 value="{{ old('title') }}">
25 @error('title')
26 <p class="text-red-500">{{ $message }}</p>
27 @enderror
28 </div>
29
30 <div class="mb-4">
31 <label for="description" class="block text-gray-700">Description:</label>
32 <textarea name="description"
33 id="description"
34 class="border border-gray-300 p-2 w-full">{{ old('description') }}</textarea>
35 </div>
36
37 <div class="mb-4">
38 <label for="due_date" class="block text-gray-700">Due Date:</label>
39 <input type="date"
40 name="due_date"
41 id="due_date"
42 required
43 class="border border-gray-300 p-2 w-full"
44 value="{{ old('due_date') }}">
45 @error('due_date')
46 <p class="text-red-500">{{ $message }}</p>
47 @enderror
48 </div>
49
50 <div class="mb-4">
51 <label for="reminder_time" class="block text-gray-700">Reminder Time:</label>
52 <input type="datetime-local"
53 name="reminder_time"
54 id="reminder_time"
55 class="border border-gray-300 p-2 w-full"
56 value="{{ old('reminder_time') }}">
57 </div>
58
59 <button type="submit"
60 class="bg-green-600 text-white p-2 border rounded">
61 Create Task
62 </button>
63 </form>
64 </div>
65 </div>
66 </div>
67 </div>
68</x-app-layout>

O formulário contém entradas de texto para title e description e entradas de data e hora para due date e reminder time.

Navegue até resources/views/tasks/edit.blade.php e adicione o seguinte conteúdo:

1<x-app-layout>
2 <x-slot name="header">
3 <h2 class="font-semibold text-xl text-gray-800 leading-tight">
4 {{ __('Edit Task') }}
5 </h2>
6 </x-slot>
7
8 <div class="py-12">
9 <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
10 <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
11 <div class="p-6 text-gray-900">
12 @foreach($tasks as $task)
13 <form action="{{ route('tasks.update', $task->id) }}" method="POST">
14 @csrf
15 @method('PUT')
16
17 <div class="mb-4">
18 <label for="title" class="block text-gray-700">Title:</label>
19 <input type="text"
20 name="title"
21 id="title"
22 required
23 class="border border-gray-300 p-2 w-full"
24 value="{{ old('title', $task->title) }}">
25 @error('title')
26 <p class="text-red-500">{{ $message }}</p>
27 @enderror
28 </div>
29
30 <div class="mb-4">
31 <label for="description" class="block text-gray-700">Description:</label>
32 <textarea name="description"
33 id="description"
34 class="border border-gray-300 p-2 w-full">{{ old('description', $task->description) }}</textarea>
35 </div>
36
37 <div class="mb-4">
38 <label for="due_date" class="block text-gray-700">Due Date:</label>
39 <input type="date"
40 name="due_date"
41 id="due_date"
42 required
43 class="border border-gray-300 p-2 w-full"
44 value="{{ old('due_date', $task->due_date) }}">
45 @error('due_date')
46 <p class="text-red-500">{{ $message }}</p>
47 @enderror
48 </div>
49
50 <div class="mb-4">
51 <label for="reminder_time" class="block text-gray-700">Reminder Time:</label>
52 <input type="datetime-local"
53 name="reminder_time"
54 id="reminder_time"
55 class="border border-gray-300 p-2 w-full"
56 value="{{ old('reminder_time', $task->reminder_time) }}">
57 </div>
58
59 <button type="submit"
60 class="bg-blue-500 text-white p-2 rounded">
61 Update Task
62 </button>
63 </form>
64 @endforeach
65 </div>
66 </div>
67 </div>
68 </div>
69</x-app-layout>

O formulário de edição contém os mesmos campos de entrada que o formulário de criação e é carregado com os dados da tarefa que está sendo editada.

Navegue até resources/views/tasks/index.blade.php e adicione o seguinte conteúdo:

1<x-app-layout>
2 <x-slot name="header">
3 <h2 class="font-semibold text-xl text-gray-800 leading-tight">
4 {{ __('Tasks') }}
5 </h2>
6 </x-slot>
7
8 <div class="py-12">
9 <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
10 <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
11 <div class="p-6 text-gray-900">
12 <div class="mb-2">
13 <a href="{{ route('tasks.create') }}"
14 class="p-2 border mb-4">
15 Create New Task
16 </a>
17 </div>
18
19 <ul class="mt-4">
20 @foreach ($tasks as $task)
21 <div class="mt-2">
22 <hr>
23 </div>
24
25 <li>
26 <h1 class="text-2xl">
27 <strong>{{ $task->title }}</strong>
28 - Due: {{ $task->due_date }}
29 </h1>
30
31 <p class="text-gray-600">
32 {{ $task->description }}
33 </p>
34
35 <div class="flex gap-2 mt-4">
36 <div class="p-2 text-white bg-gray-700">
37 <a href="{{ route('tasks.edit', $task->id) }}">
38 Edit
39 </a>
40 </div>
41
42 <div class="p-2 text-white bg-red-700 rounded">
43 <form action="{{ route('tasks.destroy', $task->id) }}"
44 method="POST"
45 style="display:inline;">
46 @csrf
47 @method('DELETE')
48 <button type="submit">Delete</button>
49 </form>
50 </div>
51 </div>
52 </li>
53 @endforeach
54 </ul>
55 </div>
56 </div>
57 </div>
58 </div>
59</x-app-layout>

Essa visualização inclui um link para o formulário de criação e percorre todas as tarefas para exibir aquelas pertencentes ao usuário autenticado.

11

Adicione um link para a funcionalidade de tarefa a partir da navegação do seu aplicação . Vá para resources/views/layouts/navigation.blade.php e adicione o seguinte código após o link de navegação do dashboard:

1// ...existing code ...
2<div class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex">
3 <x-nav-link :href="route('tasks.index')" :active="request()->routeIs('tasks.index')">
4 {{ __('Tasks') }}
5 </x-nav-link>
6</div>

Neste ponto, você pode testar as operações CRUD do seu sistema de gerenciamento de tarefas. Certifique-se de que tudo funcione corretamente antes de passar para a próxima seção.

12

Para implementar o sistema de aviso para tarefas vencidas, crie um comando Personalizado do Atlas para enviar alertas por e-mail e registrar o comando para agendamento automático.

Para criar um comando Atlas personalizado, execute o seguinte código no seu terminal:

php artisan make:command SendTaskReminders

Após criar o comando, atualize o conteúdo do arquivo app/Console/Commands/SendTaskReminders.php com o seguinte código:

<?php
namespace App\Console\Commands;
use App\Models\Task;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;
class SendTaskReminders extends Command {
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:send-task-reminders';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Execute the console command.
*/
public function handle() {
$now = Carbon::now();
$upcomingTasks = Task::where('last_notification_date', null)->get();
$upcomingTasks = Task::where('last_notification_date', null)
->where('reminder_time', '>=', $now->clone()->subMinutes(10))
->get();
foreach ($upcomingTasks as $task) {
$emailBody = <<<EOF
Hello,
This is a reminder for your task:
Title: {$task->title}
Description: {$task->description}
Due Date: {$task->due_date}
Please make sure to complete it on time!
Regards,
Your Task Reminder App
EOF;
Mail::raw($emailBody, function ($message) use ($task) {
$message->to($task->email)
->subject("Task Reminder: {$task->title}");
});
$task->last_notification_date = $now;
$task->save();
$this->info("Reminder email sent for task: {$task->title}");
}
return self::SUCCESS;
}
}

A lógica principal do comando Personalizado do Mestre está escrita no método handle(). O código obtém o carimbo de data/hora atual usando Carbon::now().

Em seguida, ele consulta o banco de dados para obter todas as tarefas em que reminder_time é menor ou igual ao tempo atual e onde reminder_time é maior ou igual a 10 minutos antes do tempo atual. No MongoDB, todas as datas são armazenadas em UTC. Mesmo que seu servidor use um zona horário diferente , você não precisará alterar o zona horário .

A query busca todas as tarefas vencidas nos próximos 10 minutos. O código percorre os resultados e envia alertas para os e-mails do usuário de tarefas que serão vencidas nos próximos 10 minutos.

Observação

Para que o agendador de tarefas funcione corretamente, você deve configurar seu aplicação para enviar e-mails. Mailtrap.io é uma ferramenta útil para testar o envio de e-mails. Para saber mais, consulte Enviar e-mail no Laravel.

13

Para concluir a configuração, agende o comando Array criado na etapa anterior para executar a cada minuto. Esta abordagem executa automaticamente php artisan app:send-task-reminders a cada minuto.

Navegue até routes/console.php e adicione o seguinte código:

// ...existing code ...
Schedule::command('app:send-task-reminders')->everyMinute();

Para testar se isso funciona, execute o seguinte comando:

php artisan schedule:run

Em um servidor de produção, você deve configurar um tarefa cron para executar o comando php artisan schedule:run em intervalos regulares.

Em um servidor baseado em Linux ou Unix, você pode abrir seu arquivo de configuração do cron usando o seguinte comando:

crontab -e

Adicione o seguinte código à aba de configuração do cron:

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

Substitua /usr/bin/php pelo caminho para o binário do PHP e /path-to-your-project pelo caminho completo para o projeto Laravel no servidor. Salve e saia do arquivo.

Para verificar se a tarefa cron está configurada corretamente, execute o seguinte comando:

crontab -l

Agora você tem um aplicação agendador de tarefas que usa Laravel e MongoDB. Este tutorial demonstra como realizar as seguintes ações:

  • Configurar um projeto Laravel para trabalhar com MongoDB

  • Implemente recursos CRUD para o agendador de tarefas

  • Crie um comando personalizado do Laravel Atlasan para o sistema de alerta

  • Agende uma tarefa para executar o comando Mestre em intervalos

  • Configurar a tarefa cron em um servidor baseado em Linux

Para saber mais sobre os conceitos abordados neste tutorial, consulte os seguintes recursos:

  • Exemplos de uso para exemplos de código de operações comuns

  • Modelos Eloquent para trabalhar com modelos Eloquent

Voltar

Execute um comando