You don’t always need to start from scratch or Spatie’s list of useful libraries

Сергей Иванюк
Appus Studio
Published in
5 min readFeb 2, 2021

My name is Sergey. I work for Appus Studio. Like others, our team often faces basic tasks. Usually, for many, such code goes from project to project, and some each time rewrite and supplement the code that performs the same task. This may be a good approach, but why reinvent the wheel when a lot has already been invented and tested before you? Yes, ready-made libraries are best suited for such tasks.

I got acquainted with these libraries at the beginning of my career as a PHP developer, when I was doing an internship with a mentor at the first company. Due to my lack of experience, at first they did not impress me. Yes, they solved the necessary tasks, but the documentation seemed very complicated to me, so I thought it would be easier to write a couple of classes myself, as it is convenient for me. But time passed and I realized how wrong I was.

The Spatie community has over 340 different libraries. Their technology stack addresses both backend and frontend tasks. In addition, there are solutions for the integration of various third-party services. But in this article I will introduce you to some of the most popular libraries used by our Appus team.

Laravel Medialibrary

This package will help you link all sorts of files to your Eloquent models. All your files will be stored in one table.

Here are some code examples:

$yourModel = YourModel::find(1);
$yourModel->addMedia($path)->toMediaCollection(‘images’);

The package can also handle your uploads directly:

$yourModel->addMediaFromRequest('image')
->toMediaCollection('images');

Want to store multiple large files on a different file system? No problem:

$yourModel->addMedia($smallFile)
->toMediaCollection('downloads', 'local');
$yourModel->addMedia($bigFile)
->toMediaCollection('downloads', 's3');

In order to customize your model for working with media files, you just need to add the appropriate interface and trait:

namespace App\Models;use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class YourModel extends Model implements HasMedia
{
use InteractsWithMedia;
}

You also need to add the definition of media collections to your model.

public function registerMediaCollections(): void
{
$this->addMediaCollection('my-collection')
//add options...
// you can define as many collections as needed
$this->addMediaCollection('my-other-collection')
//add options...
}

Additional options can be added:

  • defining a fallback URL or path;
  • allowing only specific files in the collection;
  • using a specific disk;
  • storing only one file in a collection;
  • limiting the limit of files in the collection;
  • registration of conversions;
  • creating responsive images.

You can also determine different conversions using a separate method:

public function registerMediaConversions(Media $media = null): void
{
$this->addMediaConversion('thumb')
->width(368)->height(232)->sharpen(10);
}

This method also has a number of options. You can apply filters, frames, perform transformations in specific collections. Since everything will be saved in addition to the original file and converted, you can also add the ability to save through queues.

In order to display media file (or files), it is enough to execute one method depending on your needs:

$yourModel->getFirstMediaUrl('collectionName');
$yourModel->getMediaUrl('collectionName');
$yourModel->getMedia('collectionName').

Laravel Permission

This package allows you to manage user permissions and roles in the database.

Once installed, you can do things like this:

// Adding permissions to a user
$user->givePermissionTo('edit articles');
// Adding permissions via a role
$user->assignRole('writer');
$role->givePermissionTo('edit articles');

If you are using multiple guards, this will not be a problem either. Each guard will have its own set of permissions and roles that can be assigned to guard users.

Since all permissions will be registered with the Laravel gates, you can check if the user has permission using the default Laravel can function:

$user->can('edit articles');
@can('edit articles')
...
@endcan

In order to add the ability to use roles and permissions, just connect the trait:

use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles;
}

A unique set of permissions can be added for any user:

$user->givePermissionTo('edit articles');// You can also give multiple permission at once
$user->givePermissionTo('edit articles', 'delete articles');
// You may also pass an array
$user->givePermissionTo(['edit articles', 'delete articles']);

You can also unbind permission from the user:

$user->revokePermissionTo('edit articles');

Or unbind and add new ones using this method:

$user->syncPermissions(['edit articles', 'delete articles']);

It’s the same with roles, except instead of using the User model object, we’ll use Role.

There are methods for checking permissions:

$user->hasPermissionTo('edit articles');
$user->hasPermissionTo(Permission::find(1)->id);
$user->hasPermissionTo($somePermission->id);
$user->hasAnyPermission(['edit articles', 'publish articles']);
$user->hasAllPermissions(['edit articles', 'publish articles']);
$user->hasAnyPermission(['edit articles', 1, 5]);

The same thing works with roles:

$user->assignRole('writer');// You can also assign multiple roles at once
$user->assignRole('writer', 'admin');
// or as an array
$user->assignRole(['writer', 'admin']);
$user->removeRole('writer');
// All current roles will be removed from the user and replaced by the array given
$user->syncRoles(['writer', 'admin']);

$user->hasRole('writer');
$user->hasAnyRole(['writer', 'reader']);
$user->hasAllRoles(Role::all());

In addition, individual permissions can also be assigned to the user. For example:

$role = Role::findByName('writer');
$role->givePermissionTo('edit articles');
$user->assignRole('writer');
$user->givePermissionTo('delete articles');

To check if a user has directly assigned permissions, use one of the methods:

// Check if the user has Direct permission
$user->hasDirectPermission('edit articles')
// Check if the user has All direct permissions
$user->hasAllDirectPermissions(['edit articles', 'delete articles']);
// Check if the user has Any permission directly
$user->hasAnyDirectPermission(['create articles', 'delete articles']);

Defining a super administrator:

If you want the “super admin” role to respond true to all permissions, without having to assign all of those permissions to the role, you can use Laravel’s Gate :: before() method. For example:

use Illuminate\Support\Facades\Gate;class AuthServiceProvider extends ServiceProvider
{
public function boot()
{
$this->registerPolicies();
Gate::before(function ($user, $ability) {
return $user->hasRole('Super Admin') ? true : null;
});
}
}

In addition to the libraries presented, there are many others. In their list, you can always find something suitable for you.

At Appus Studio, we use these libraries both on customer projects and on our products. This gives us advantages in the speed of development, the reliability of the functionality, and the absence of the need to maintain documentation on the relevant parts of the functionality.

--

--