Cartalyst LLC.
Media by Cartalyst
2
67
0
6
2

This package requires a valid subscription. Subscribe for access.

Preface

Introduction

A Platform 4 extension to manage media.

Have a read through the Installation Guide.

Features

  • Create, update, delete files.
  • Email files.
  • Set media visibility to private/public.
  • Share file urls.
  • Download files.
  • Blade call @media('id', 'download|thumbnail')
  • Blade call @thumbnail('id', [ 'options' ], 'default')
  • Add tags.
  • Create config styles.

Examples

The $media variable used below is a reference to the MediaRepository.

$media = app('platform.media');
Retrieve all media.
$media = $media->find(1);
Dynamically create a new employee.
// $file must be an instance of `Symfony\Component\HttpFoundation\File\UploadedFile`

$media->upload($file, [
    'name'  => 'Foobar',
]);

Setup

Installation

The best and easiest way to install the Media extension is with Composer.

Preparation

Open your composer.json file and add the following to the require array:

"platform/media": "3.3.*"

Add the following lines after the require array on your composer.json file:

"repositories": [
    {
        "type": "composer",
        "url": "https://packages.cartalyst.com"
    }
]

Note: Make sure that after the required changes your composer.json file is valid by running composer validate.

Install the dependencies

Run Composer to install or update the new requirement.

php composer install

or

php composer update

Now you are able to install the extension through Platform's admin.

Usage

In this section we'll show how you can manage your media.

Repository

IoC Binding

The media repository is bound to platform.media and can be resolved out of the IoC Container using that offset.

$media = app('platform.media');

Methods

The repository contains several methods that are used throughout the extension, most common methods are listed below.

For an exhaustive list of available methods, checkout the MediaRepositoryInterface

  • find($id);

Returns an media object based on the given id.

  • findByPath($path);

Returns a collection of all media.

  • upload($file, array $input)

Uploads the given file and populates the data passed as input.

  • create(array $data);

Creates and stores a new media object.

  • update($id, array $data);

Updates an existing media object.

  • delete($id);

Deletes a media object.

Manager

The media manager makes integrating media with your extension a breeze. It allows you to attach media to your entities. The following example is going to explain how to use the manager for an Employee.

Model setup

The model must use Platform\Media\Support\MediaTrait and implement Cartalyst\Support\Contracts\NamespacedEntityInterface

Example
<?php
namespace Platform\Employees\Models;

use Platform\Media\Support\MediaTrait;
use Illuminate\Database\Eloquent\Model;
use Cartalyst\Support\Traits\NamespacedEntityTrait;
use Cartalyst\Support\Contracts\NamespacedEntityInterface;

class Employee extends Model implements NamespacedEntityInterface
{
    use NamespacedEntityTrait, MediaTrait;

    protected static $entityNamespace = 'platform/employees';

    ...
}

Note The $entityNamespace of your model is used by the media when uploading images.

View setup

On the view, a simple blade call is needed that requires an instance of the model in question to be passed in as first argument, an optional second argument indicates whether the widget should allow attaching a single or multiple media objects, multiple is the default.

Third argument is optional and can be a view that would override the default widget view that ships with the extension.

Example
Allow only a single image to be attached to the model
@mediaUploader($employee, false)
Allow multiple images to be attached to the model
@mediaUploader($employee)
Use a custom view for the media widget
@mediaUploader($employee, true, 'yourvendor/yourextension::widgets.upload')
Use the media manager in a Platform Extension / Model Form
@extends('layouts/default')

{{-- Page content --}}
@section('page')

<section class="panel panel-default panel-tabs">

    {{-- Form --}}
    <form id="employees-form" action="{{ request()->fullUrl() }}" role="form" method="post">

    {{-- Form fields --}}
        ...

        <div class="row">

            @mediaUploader($employee)

        </div>

    </form>

</section>
@stop

Upload media

  1. Click on Upload
  2. Drop your files on the uploadable area
  3. Start Upload

upload-media

Note

The files are going to be attached to your entity.

Select media

You can attach media to your entity by using the Media Manager Selector.

  1. Click Select
  2. Select your files
  3. Select to attach the selected media to your entityNamespace

select-media

Note

You can select/unselect files by clicking on the Selected Collapse or by clicking again on the selected media. Furthermore you can search your media library or narrow your library down by applying mime-type filters.

Sort media

The media manager is built with sorting in mind. Just drag the media by clicking and dragging the arrows icon.

drag-media

Detach media

Detach a media by clicking on the trash Icon. The File is not going to be entirely deleted, only the relation to the entity. If you want to delete a media permanently you can use the Media Extension.

detach-media

Cropping Media

Often you would like to have uniform images attached to your entities. This example is going to show you how you could crop your images for a specific entity. As an example, we will continue to use an Employee model.

Set up the Media Style

I have created a new Organization\Employee Extension with Platform's Workshop, which simplifies the process of creating all the files and views significantly. This is an excellent starting point to work with.

Example: ImageMacro

We're going to create our own ImageMacro that is extending Platform's Platform\Media\Styles\Macros\AbstractMacro.

This file is going to be saved under workbench/organization/employees/src/Styles/Macros/ImageMacro.php. Feel free to apply your own coding style and save the ImageMacro where ever it feels right to you.

<?php
namespace Organization\Employees\Styles\Macros;

use Illuminate\Support\Str;
use Cartalyst\Filesystem\File;
use Platform\Media\Models\Media;
use Illuminate\Container\Container;
use Platform\Media\Styles\Macros\AbstractMacro;
use Platform\Media\Styles\Macros\MacroInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;

class ImageMacro extends AbstractMacro implements MacroInterface
{
    /**
     * The Illuminate Container instance.
     *
     * @var \Illuminate\Container\Container
     */
    protected $app;

    /**
     * The Filesystem instance.
     *
     * @var \Cartalyst\Filesystem\Filesystem
     */
    protected $filesystem;

    /**
     * The Intervention Image Manager instance.
     *
     * @var \Intervention\Image\ImageManager
     */
    protected $intervention;

    /**
     * Constructor.
     *
     * @param  \Illuminate\Container\Container $app
     *
     * @return void
     */
    public function __construct(Container $app)
    {
        $this->app = $app;

        $this->intervention = $app['image'];

        $this->filesystem = $app['cartalyst.filesystem'];
    }

    /**
     * @param Media $media
     * @param File  $file
     *
     * @return File
     * @internal param $cachedPath
     *
     */
    public function cropOriginalFile(Media $media, File $file)
    {
        $cachedPath = $this->style->path . '/' . str_random(10) . '.' . $file->getExtension();

        // Crop the Media
        app('image')->make($file->getContents())
                    ->fit($this->style->croppedImageWidth, $this->style->croppedImageHeight, function ($constraint) {
                        $constraint->aspectRatio();
                    })->save($cachedPath);

        // Upload the file
        app('cartalyst.filesystem')->update($media->path, file_get_contents($cachedPath));

        // Delete temporary File
        \Illuminate\Support\Facades\File::delete($cachedPath);
    }

    /**
     * {@inheritDoc}
     */
    public function down(Media $media, File $file)
    {
        $path = $this->getPath($file, $media);

        \Illuminate\Support\Facades\File::delete($path);
    }

    /**
     * {@inheritDoc}
     */
    public function up(Media $media, File $file, UploadedFile $uploadedFile)
    {
        // Check if the file is an image and has the namespace of an Employee
        if ($file->isImage() && $media->namespace == 'organization/employees.employee') {
            $path = $this->getPath($file, $media);

            // Update the media entry
            $media->thumbnail = str_replace(public_path(), null, $path);
            $media->save();

            // Create the Thumbnail
            $this->intervention->make($file->getContents())
                 ->fit($this->style->width, $this->style->height, function ($constraint) {
                     $constraint->aspectRatio();
                 })->save($path);

            // Crop original File
            $this->cropOriginalFile($media, $file);
        }
    }

    /**
     * Returns the prepared file path.
     *
     * @param  \Cartalyst\Filesystem\File   $file
     * @param  \Platform\Media\Models\Media $media
     *
     * @return string
     */
    protected function getPath(File $file, Media $media)
    {
        $width  = $this->style->width;
        $height = $this->style->height;

        $name = Str::slug(implode([$file->getFilename(), $width, $height ?: $width], ' '));

        return "{$this->style->path}/{$media->id}_{$name}.{$file->getExtension()}";
    }
}

Note

Dependend upon what Filesystem Disk you are using, we are making sure that we are creating a cached file first and then replace the original file. Feel free to adjust the function to your needs.

Example: Set Image Style

We've created the ImageMacro sucessfully and need to set the style so that the media manager is going to apply it when ever a file is uploaded. Here, we are putting the logic to set the style in the Organization\Employees\Providers\EmployeeServiceProvider. We are registering the Style which is applying the ImageMacro that we created before.

<?php
namespace Organization\Employees\Providers;

use Cartalyst\Support\ServiceProvider;

class EmployeeServiceProvider extends ServiceProvider
{
    /**
     * {@inheritDoc}
     */
    public function boot()
    {
        // Register the attributes namespace
        $this->app['platform.attributes.manager']->registerNamespace(
            $this->app['Organization\Employees\Models\Employee']
        );

        // Subscribe the registered event handler
        $this->app['events']->subscribe('organization.employees.employee.handler.event');

        // Get the Media Manager
        $manager = app('platform.media.manager');

        // Set the Employee Image Style
        $manager->setStyle('EmployeeImage', function (Style $style) {
            // Set the style image height and width.
            $style->height = 1200;
            $style->width  = 1200;

            // Set the style image height and width for the cropped image
            $style->croppedImageHeight = 600;
            $style->croppedImageWidth  = 600;

            // Set the style macros
            $style->macros = ['EmployeeImageMacro'];

            // Set the storage path
            $style->path = public_path('cache/media');
        });

        // Set the Employee Image Macro
        $manager->setMacro('EmployeeImageMacro', 'Organization\Employees\Styles\Macros\ImageMacro');
    }

    /**
     * {@inheritDoc}
     */
    public function register()
    {
        // Register the repository
        $this->bindIf('organization.employees.employee', 'Organization\Employees\Repositories\Employee\EmployeeRepository');

        // Register the data handler
        $this->bindIf('organization.employees.employee.handler.data', 'Organization\Employees\Handlers\Employee\EmployeeDataHandler');

        // Register the event handler
        $this->bindIf('organization.employees.employee.handler.event', 'Organization\Employees\Handlers\Employee\EmployeeEventHandler');

        // Register the validator
        $this->bindIf('organization.employees.employee.validator', 'Organization\Employees\Validator\Employee\EmployeeValidator');
    }
}

Note

In this example the image is going to be cropped to fit 1200x1200px. The thumbnail is resized to 600x600px.

When a file is uploaded, the Media Manager is going through all Styles and its Macros. In the up() function we are checking if the uploaded file is an image and has the namespace organization/employees.employee. The Macro is handling the cropping and creating the thumbnail. This way you are able to set up as many Styles and Macros as you need and every Macro can have different rules in the up() function. Every Entity could have its own ImageMacro and Style. Let's say you're not only working with an Employee model, but you have a Organization too, you could easily follow the steps above and create an ImageMacro for the Organization.

You wont find fancy lifestyle graphics and marketing bravado here. Just cold... hard... code...

Code Well, Rock On!
Processing Payment...