Craftable

Media

This packages adds an ability to assign a media to your eloquent models. It uses Spatie's spatie/laravel-medialibrary, but it goes a bit further:

  • Collections definition - inspired by the conversions definition, we have created Media Collections definition via similar fluent API
  • Auto-Process - saving the eloquent model automatically processes and attaches media collections from the request
  • Authorization - controls, who has the permission to attach specific medium to specific model
  • Private access - controls, who has the permission to view specific medium

Requirements

This package requires PHP 7.0+ and Laravel (5.5, 5.6 or 5.7).

This package uses JSON columns, so MySQL 5.7+ or PostgreSQL 9.5+ is required.

To create derived images GD needs to be installed on your server. If you want to create PDF or SVG thumbnails Imagick is also required. For the creation of thumbnails of video files ffmpeg should be installed on your system.

Check out https://docs.spatie.be/laravel-medialibrary/v6/requirements for more details.

Installation

{danger.fa-exclamation-triangle} This section is only when you want to use this package as a standalone package. If you are using with Craftable, then this package is already installed.

Let's add a new requirement:

composer require brackets/media

That's it. Provider will be discovered automatically.

Basic Usage

There are two core concepts to understand - MediaCollections and MediaConversions.

If you have different types of files that you want to associate with your model (e.g. image gallery, list of PDFs), you can put them in their own MediaCollection.

When adding files to your media library, MediaConversions can automatically create derived versions such as thumbnails, optimized versions, etc.. You can register as many MediaConversions as you want.

Media Collection definition

First, we need to define the media collections for the specific model.

Let's imagine a Post model for following examples. You need to register media collection like this:

use Illuminate\Database\Eloquent\Model;
use Brackets\Media\HasMedia\HasMediaCollections;
use Brackets\Media\HasMedia\HasMediaCollectionsTrait;

class Post extends Model implements HasMediaCollections {

    use HasMediaCollectionsTrait;

    public function registerMediaCollections() {
        $this->addMediaCollection('gallery');
    }

Here we have added new gallery media collection.

Attaching media to model

By default, media are attached automatically from the request (on saving event hook). You just need to attach a gallery data structure to your request data and you are all set:

class PostsController extends Controller {
    ...
    public function store(StoreRequest $request)
    {
        // this will automatically attach $request->file('gallery') to the Post
        $post = Post::create($request->validated());
        ...
    }

The $request->gallery should be an array in following format:

[
    [
        'id' => null,
        'collection_name' => 'gallery',
        'path' => 'my_lovely_picture_1.jpg',
        'action' => 'add',
        'meta_data' => [ // or any other data
            'name' => 'test',
            'width' => 200,
            'height' => 200,
        ],
    ],
    [
        'id' => null,
        'collection_name' => 'gallery',
        'path' => 'my_lovely_picture_2.jpg',
        'action' => 'add',
        'meta_data' => [ // or any other data
            'name' => 'test',
            'width' => 200,
            'height' => 200,
        ],
    ],
    ...
];

This feature can be turned-off with $autoProcessMedia property:

class Post extends Model implements HasMediaCollections {

    use HasMediaCollectionsTrait;

    public $autoProcessMedia = false;

Once turned-off you can still call processMedia() method on your model. Or you can still use Spatie's standard way of attaching media (see https://docs.spatie.be/laravel-medialibrary/v6/basic-usage/associating-files).

Uploader

This package covers only backend functionality. However, you can use our uploader from brackets/admin-ui package, that works very well with this packages.

Retrieve

To retrieve files you can use the getMedia method:

$mediaItems = $post->getMedia('nameOfTheCollection');
$publicUrl = $mediaItems[0]->getUrl();

// to retrieve media from any Media Conversion
$publicUrl = $mediaItems[0]->getUrl('nameOfTheConversion');

For more info check the Spatie's docs: https://docs.spatie.be/laravel-medialibrary/v6/basic-usage/retrieving-media

Media Conversions

If you want to adjust media during handling (e.g. resize, crop, optimize, fine tune colors), your models should implement the HasMediaConversions interface. This interface expects an implementation of the registerMediaConversions method.

use Illuminate\Database\Eloquent\Model;
use Brackets\Media\HasMedia\HasMediaCollections;
use Brackets\Media\HasMedia\HasMediaCollectionsTrait;
use Spatie\MediaLibrary\HasMedia\Interfaces\HasMediaConversions;
use Spatie\MediaLibrary\Media;

class Post extends Model implements HasMediaCollections, HasMediaConversions {

    use HasMediaCollectionsTrait;

    public function registerMediaCollections()
    {
        $this->addMediaCollection('gallery');
    }

    public function registerMediaConversions(Media $media = null)
    {
        $this->addMediaConversion('detail_hd')
            ->width(1920)
            ->height(1080)
            ->performOnCollections('gallery');
    }

As you can see, we didn't touch the Spatie's conversions functionality at all. For more info check their docs as well https://docs.spatie.be/laravel-medialibrary/v6/converting-images/defining-conversions.

Advanced usage

There are following methods on Media Collections:

public function registerMediaCollections()
    {
        $this->addMediaCollection('gallery')
            ->disk('media') // Specify a disk where to store this collection
            ->private() // Alias to setting default private disk 
            ->maxNumberOfFiles(10) // Set the file count limit
            ->maxFilesize(2*1024*1024) // Set the file size limit
            ->accepts('image/*') // Set the accepted file types (in MIME type format)
            ->canView('media.view') // Set the ability (Gate) which is required to view the medium (in most cases you would want to call private())
            ->canUpload('media.upload') // Set the ability (Gate) which is required to upload & attach new files to the model
    }