Tutorial: Build a Task Reminder With Laravel and MongoDB

For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

Tutorial: Build a Task Reminder With Laravel and MongoDB

Overview

In this tutorial, you can learn how to use MongoDB in a Laravel application by building a simple task reminder system. The application allows you to create, read, update, and delete tasks. Additionally, it sends email reminders for upcoming tasks based on a scheduled time.

Prerequisites

Before you begin this tutorial, ensure you have the following components installed in your development environment:

  • PHP and the [MongoDB PHP extension](https://www.mongodb.com/docs/php-library/current/get-started/#install-the-mongodb-php-extension

  • Laravel

  • Composer

  • NPM

You must also set up a MongoDB Atlas cluster. To learn how to set up a cluster, see the Getting Started guide.

Steps

  1. Create a new Laravel project.

Use Composer to create a new Laravel project and navigate to the project directory:

bash composer create-project laravel/laravel LaravelMongodbProject cd LaravelMongodbProject

  1. Install the MongoDB Laravel package.

To use MongoDB in your application, you must install the Laravel MongoDB package and configure it in the config/database.php file.

Install the package by using the following command:

bash composer require mongodb/laravel-mongodb

Tip:

If you encounter an error when you run the preceding command, ensure that the MongoDB PHP extension is installed. To learn how to install, see the [Install the MongoDB PHP extension](https://www.mongodb.com/docs/php-library/current/get-started.md#std-label-php-download-and-install step in the Get Started guide.

  1. Configure the database connection.

After the Laravel MongoDB package installation completes, add your MongoDB database connection to the config/database.php file to complete the configuration. Add the following MongoDB configuration to the connections array that contains configurations for other database types:

```php return [

   'connections' => [

     'mongodb' => [
        'driver' => 'mongodb',
        'dsn' => env('MONGODB_URI'),
        'database' => 'task_reminder',
     ],

     // Other connections here
   ],

]; ```

Your application obtains the dsn value from the .env file. Navigate to your .env file. Then, create a value for MONGODB_URI and set it to the value of your MongoDB connection string.

Tip:

To obtain your MongoDB connection string, navigate to your cluster in MongoDB Atlas. Click the Connect button and click the Drivers under Connect your application. Select “PHP” from the Driver selection menu. Copy the connection string from the dialog box. For detailed steps on how to obtain your connection string, see [Create a Connection String.](https://www.mongodb.com/docs/drivers/php/laravel-mongodb/current/get-started.md#std-label-laravel-quick-start-connection-string

In your .env file, set the DB_CONNECTION value to mongodb to make it the default connection for your application. Edit the SESSION_DRIVER value and set it to mongodb as shown in the following code:

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

  1. Set up authentication with Laravel Breeze.

After installing and configuring your application to work with MongoDB, set up authentication. Laravel simplifies authentication implementation by providing packages such as Laravel Breeze, Laravel Fortify and Laravel Jetstream. This tutorial uses Laravel Breeze for authentication.

Install Laravel Breeze by using Composer:

bash composer require laravel/breeze --dev

After the installation completes, run the following commands:

```bash php artisan key:generate

php artisan breeze:install php artisan migrate

php artisan db:seed npm install npm run dev ```

This prompts you to choose your preferred stack and testing package. For this tutorial, select the first option, Blade with Alpine:

text ┌ 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 │ └──────────────────────────────────────────────────────────────┘

This command adds authentication views, routes, controllers, and other related resources to your application.

  1. Configure the User model and authentication for MongoDB.

Laravel Breeze creates a default User model for SQL databases. You must update it to work with MongoDB and resolve rate limiting compatibility issues.

Open app/Models/User.php and replace its contents with the following:

```php <?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',
       ];
   }

} ```

  1. Serve the project and test the MongoDB connection.

Serve the project by using Laravel's built-in server and confirm that everything works properly. In the Laravel project directory, run the following command:

bash php artisan serve

The project serves at 127.0.0.1:8000. If port 8000 is already in use, Laravel switches to a new available port, which it prints to the terminal.

To test the authentication system, select the Register button in your application and create a new user account. This stores the user in your MongoDB database and allows you to log in with those credentials. For this tutorial, you can set the username to test@example.com and the password to password.

To verify that the Laravel MongoDB package was configured properly, create a route to ping your MongoDB cluster. Add the following to routes/web.php:

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]; });

Visit this route in your browser. With the correct configuration, you see the message “MongoDB is accessible!” in your browser.

  1. Create the task model and controller.

Create the model and controller for the task scheduling feature by using the following command:

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

This command creates the Task model in the app/Models directory and the TaskController in the app/Http/Controllers directory with resource methods.

Create a route for the TaskController by navigating to routes/web.php and adding the following code:

```php use App\Http\Controllers\TaskController;

// Other route definitions...

Route::resource('tasks', TaskController::class)->middleware('auth'); ```

  1. Configure the Task model.

Navigate to app/Models/Task.php and replace the contents of the file with the following code:

```php 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.'); } } ``` The `TaskController` class contains code that handles the CRUD operations of the task model: - The `index()` method retrieves all tasks belonging to the logged-in user and sends them to the `index.blade.php` file for display. - The `create()` method returns the form view for creating a new task. - The `store()` method validates input, assigns the logged-in user's email to the task, and saves it to the database. - The `edit()` method retrieves the specific task to be edited and displays it in an edit form. - The `update()` method saves the edited task to the MongoDB task collection. - The `destroy()` method deletes a specific task. Each operation redirects back to the task list with a success message for user feedback. 10. Create view files for the task scheduler. In the `resources/views` directory, create a folder named `tasks` and create the following files in it: - `create.blade.php` - `edit.blade.php` - `index.blade.php` Navigate to `resources/views/tasks/create.blade.php` and add the following content: ```php

{{ __('Tasks') }}

Create New Task

@csrf
@error('title')

{{ $message }}

@enderror
@error('due_date')

{{ $message }}

@enderror
``` The form contains text inputs for `title` and `description` and date and time inputs for `due date` and `reminder time`. Navigate to `resources/views/tasks/edit.blade.php` and add the following content: ```php

{{ __('Edit Task') }}

@foreach($tasks as $task)
@csrf @method('PUT')
@error('title')

{{ $message }}

@enderror
@error('due_date')

{{ $message }}

@enderror
@endforeach
``` The edit form contains the same input fields as the create form and is loaded with the data of the task currently being edited. Navigate to `resources/views/tasks/index.blade.php` and add the following content: ```php

{{ __('Tasks') }}

    @foreach ($tasks as $task)

  • {{ $task->title }} - Due: {{ $task->due_date }}

    {{ $task->description }}

    @csrf @method('DELETE')
  • @endforeach
``` This view includes a link to the create form and loops through all the tasks to display those belonging to the authenticated user. 11. Add navigation link for tasks. Add a link to the task feature from your application navigation. Go to `resources/views/layouts/navigation.blade.php` and add the following code after the dashboard navigation link: ```php // ...existing code ... ``` At this point, you can test the CRUD operations of your task management system. Ensure that everything works correctly before you move on to the next section. 12. Create a custom Artisan command for sending reminders. To implement the reminder system for due tasks, create a custom Artisan command to send reminders through email and register the command for automatic scheduling. To create a custom Artisan command, run the following code in your terminal: ```bash php artisan make:command SendTaskReminders ``` After you create the command, update the contents of the `app/Console/Commands/SendTaskReminders.php` file with the following code: ```php get(); $upcomingTasks = Task::where('last_notification_date', null) ->where('reminder_time', '>=', $now->clone()->subMinutes(10)) ->get(); foreach ($upcomingTasks as $task) { $emailBody = <<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; } } ``` The main logic of the custom Artisan command is written in the `handle()` method. The code gets the current timestamp by using `Carbon::now()`. Next, it queries the database to get all the tasks where `reminder_time` is less than or equal to the current time and where `reminder_time` is greater than or equal to 10 minutes before the current time. In MongoDB, all dates are stored in UTC. Even if your server uses a different time zone, you don't need to change the time zone. The query fetches all tasks that are due in the next 10 minutes. The code loops through the results and sends reminders to the user emails of tasks that will be due in the next 10 minutes. **Note:** For the task scheduler to work properly, you must configure your application to send emails. Mailtrap.io is a useful tool to test email sending. To learn more, see [Send Email in Laravel.](https://mailtrap.io/blog/send-email-in-laravel/) 13. Schedule notifications for task reminders. To complete the setup, schedule the Artisan command created in the previous step to run every minute. This approach automatically runs `php artisan app:send-task-reminders` every minute. Navigate to `routes/console.php` and add the following code: ```php // ...existing code ... Schedule::command('app:send-task-reminders')->everyMinute(); ``` To test that this works, run the following command: ```bash php artisan schedule:run ``` On a production server, you must configure a cron job to run the `php artisan schedule:run` command at regular intervals. On a Linux- or Unix-based server, you can open your cron configuration file by using the following command: ```bash crontab -e ``` Add the following code to the cron configuration tab: ```bash * * * * * /usr/bin/php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1 ``` Replace `/usr/bin/php` with the path to your PHP binary and `/path-to-your-project` with the full path to your Laravel project on your server. Save and exit the file. To verify that the cron job is set up correctly, run the following command: ```bash crontab -l ``` ## Summary You now have a task scheduler application that uses Laravel and MongoDB. This tutorial demonstrated how to complete the following actions: - Configure a Laravel project to work with MongoDB - Implement CRUD features for the task scheduler - Create a custom Laravel Artisan command for the reminder system - Schedule a task to run the Artisan command at intervals - Configure the cron job on a Linux-based server ## Next Steps To learn more about the concepts covered in this tutorial, see the following resources: - [Interact with Data](https://www.mongodb.com/docs/drivers/php/laravel-mongodb/current/interact-data/insert.md#std-label-laravel-fundamentals-insert-documents for code examples of common operations - [Model Your Data](https://www.mongodb.com/docs/drivers/php/laravel-mongodb/current/model-data/model-class.md#std-label-laravel-eloquent-model-class for working with Eloquent models ?>