Categories
Tutorial

AJAX Notifications in CakePHP

Notifications can help get the users attention about important events. If you’re here I probably don’t have to explain what notifications are to you, but I like to have a little preamble introducing the topic. In this blog I’ll show you how to create custom notifications in CakePHP using AJAX.

Creating Our Script

For this tutorial I want to notify an employee to turn in their reports 3 days before the end of the month. Let’s create a script that calls our report class 3 days before the end of the month, and asks if there are any reports coming up.

const notify = async () => {
  var reports_due = await ajaxRead('/reports/due.json');

  if (reports_due) 
		$('#reports-notification').show();
    $('#reports-notification').find('#notification-text').text("You have " + goals_due + " reports due soon");

};

$( document ).ready(function() {
  notify();
});

As you can see we’re simply calling the due function in our reports controller, retrieving the count of reports due, and notifying the user.

Let’s add the notification HTML to our users’ profile page!

<!-- START Notifications -->
  <div id="reports-notification" class="alert alert-warning" role="alert" style="display: none;">
    <span id="notification-text"></span>
    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
      <span aria-hidden="true">×</span>
    </button>
  </div>
<!-- END Notifications -->

We’ll be using Bootstraps alert component, but if you don’t have, or don’t want, Bootstrap in your application you can have a plane div. All the script needs is the ids to hook into.

Adding the Due Function

Now that our front end is ready to notify the user we need to set up our due function to accept the AJAX calls from our script.

Go to the reports controller, and add the following function.

use Cake\\Http\\Exception\\BadRequestException;

public function due() {
    if (!$this->request->isAll(['get', 'json'])) {
      throw new BadRequestException();
    }
		$employeeId = $this->request->getSession()->read('Auth.User.employee_id');
    try {
      $reports = $this->Reports
                   ->find()
                   ->where([
                     'Reports.employee_id' => $employeeId,
                     'Reports.due_date BETWEEN :start_date and :end_date'
                   ])
                   ->bind(':start_date', date('Y-m-d', mktime(0, 0, 0, date('m')  , date('t')-3, date('Y'))), 'date')
                   ->bind(':end_date', date('Y-m-d', mktime(0, 0, 0, date('m')  , date('t'), date('Y'))), 'date')
                   ->count();

      $this->set('reports', $reports);
      $this->set('_serialize', 'reports');
    } catch (\\Cake\\Datasource\\Exception\\RecordNotFoundException $e) {
      $errors = [
        'messages' => ['record not found'],
        'data' => [
          'id' => $employeeId,
          'dateRange' => $dateRange
        ]
      ];
    } catch (\\Cake\\ORM\\Exception\\PersistenceFailedException $e) {
      $errors = [
        'messages' => $reports->getErrors(),
        'data' => [
          'id' => $employeeId,
          'dateRange' => $dateRange
        ]
      ];
    }

    if (!empty ($errors)) {
      $this->set('errors', $errors);
      $this->set('_serialize', ['errors']);
    }
  }

This function assumes that you’re using sessions to store your user’s ids. You can also pass in the employee id if your application doesn’t use sessions.

Conclusion

Done! This is a basic example, and you can probably already see some ways to really spice up your notifications. Maybe you could add some animations, or even just add the ability to click on the notification and be taken to the goal page.

I hope you enjoyed this quick tutorial, if you did please leave a comment below!

Don’t forget to subscribe to get new CakePHP updates regularly!