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 runningcomposer 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
- Click on Upload
- Drop your files on the uploadable area
- Start Upload
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.
- Click Select
- Select your files
- Select to attach the selected media to your entityNamespace
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.
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.
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 anEmployee
model, but you have aOrganization
too, you could easily follow the steps above and create anImageMacro
for theOrganization
.