A portrait of Pete Heslop
02 Feb, 2018 3 min read

Phases – Let’s Get Technical!

Phases – Let’s Get Technical!

As we are now a few hundred hours into the design and development of our new project management application Phases, it’s about time we showed you under the hood!

Phases, built in Laravel 5.5, utilises a wide variety of different aspects and elements that the number one PHP framework has to offer.

Here are just a few of the features we’re taking full advantage of:

Events & Listeners

With Laravel events, it is possible to subscribe and listen for events that may occur in the application, by providing a simple observer implementation.

Learn more: https://laravel.com/docs/5.5/events#introduction

To register Events & Listeners, it’s as simple as adding them to the EventServiceProvider included in the Laravel application. For example:

/**

* The event listener mappings for the application.

*

* @var array

*/

protected $listen = [

'AppEventsOrderShipped' => [

'AppListenersSendShipmentNotification',

],

];

After adding events and listeners, just run the command php artisan event:generate to create the files. Existing events will be left untouched.

In Phases we use Events to trigger actions such as, ‘team created’ or ‘project created’, so we can notify users that have been added to a team or project. For example, when creating a team the Team Created event is “triggered” and the listener will be responsible to handle the logic to notify the users.

Notifications

Laravel supports an easy way of sending notifications to users across a variety of delivery channels like email, SMS and Slack. It is also possible to store the notifications in a database is they can be used to display on the web interface.

Creating notifications using the artisan command make:notification.

This will place the generated notification class in app/Notifications. This class contains a via method and a variable number of message building methods (such as ToMail or toDatabase) that converts the notification to a message optimised to that particular channel.

After setting up the class, notifications can be sent using the notify method:

use AppNotificationsInvoicePaid;

$user->notify(new InvoicePaid($invoice));

Learn more: https://laravel.com/docs/5.5/notifications#sending-notifications

We use this in Phases so we can send notifications to users when they’re added to a team or project for example.

Policies and Gates

With Laravel is really easy to authorise user actions against a given resource and there are two ways of doing this; gates and policies.

More info: https://laravel.com/docs/5.5/authorization#introduction

Gates determine if a user is authorised to perform actions and are defined in the AppProvidersAuthServiceProvider class.

Example:

/**

* Register any authentication / authorization services.

*

* @return void

*/

public function boot()

{

$this->registerPolicies();

Gate::define('update-post', function ($user, $post) {

return $user->id == $post->user_id;

});

}

To authorise actions that use Gates it can be done using the allows/denies methods.

if (Gate::allows('update-post', $post)) {

// The current user can update the post...

}

if (Gate::denies('update-post', $post)) {

// The current user can't update the post...

}

Or the forUser can be used in case we want to determine if a particular user is authorised to perform an action, instead of the current logged in user.

if (Gate::forUser($user)->allows('update-post', $post)) {

// The user can update the post...

}

if (Gate::forUser($user)->denies('update-post', $post)) {

// The user can't update the post...

}

Policies are classes that organise the logic around a given model or resource. Policies are generated using php artisan make:policy command.

After creating a policy, it needs to be registered in the AuthServiceProvider class.

class AuthServiceProvider extends ServiceProvider

{

/**

* The policy mappings for the application.

*

* @var array

*/

protected $policies = [

Post::class => PostPolicy::class,

];

After registering a policy, methods may be added for each action it authorises.

For example:

/**

* Determine if the given post can be updated by the user.

*

* @param AppUser $user

* @param AppPost $post

* @return bool

*/

public function update(User $user, Post $post)

{

return $user->id === $post->user_id;

}

To authorise actions using policies via the User model it’s as easy as using two helpful methods: can and can’t. The method receives the action to authorise and the model it relates to. Example:

if ($user->can('update', $post)) {

//

}

In Phases we implement both to authorise actions like creating a project in a team or update a project log and more.

As I’m sure you can tell, we’re getting into the nitty-gritty of user permissions, sign-up flow, and ensuring phases is seamless.

Next week our landing page will be ready and the beta waiting list will be open!

We’ll catch you there.

Laravel