-
Notifications
You must be signed in to change notification settings - Fork 4
Media
This module is created to upload files and bind them to a specific object entity.
If you want to look at the code of the working examples, just go to module/Test/Controller/ and you will see Audio, Video, Image controllers.
Let's look, how to do that if you have, for example, entity Car, and want to upload images to its objects, and then simply get them like this:
$tesla->getImages();
Use File trait in your entity class (it is universal for all types of files: images, audio, video), for example:
class Car
{
use \Fury\Media\File;
...
Attention! This trait has three abstract methods you need to realize
- getEntityName method in your entity class, that return the alias of your entity
- getId method (I think there's no need to describe what it does)
- setEntityManager method, which must be called on PostLoad that is done in this example
/**
* @ORM\HasLifecycleCallbacks
*/
class Car
{
use \Fury\Media\File;
...
private $entityManager;
/**
* @ORM\PostLoad
*/
public function setEntityManager(LifecycleEventArgs $args)
{
$this->entityManager = $args->getEntityManager();
}
public function getEntityName()
{
return 'Car';
}
###WOW!
Now you can call from the Car object such methods: getImages(), getAudios(), getVideos(). They are realized in a trait, that's everything you need to know, quite simple, ha?
##STEP 2
You need to create a controller with an action that will send file service to a view in order to generate an upload form. There are three forms: AudioUpload, VideoUpload, ImageUpload. Here it is an example how it all works:
Controller Part
class CarController extends AbstractActionController
{
public function uploadImageAction()
{
$fileService = $this->getServiceLocator()->get('Media\Service\File');
$id = 1; //or get it from the url, whatever
return new ViewModel([
'fileService' => $fileService,
'type' => File::IMAGE_FILETYPE, //Obviously, you can choose between image, audio, video
'id' => $id
]);
}
View Part
<?php
$fileService->generateFileUploadForm($type); //You also have to pass type of file to generate form for it
?>
<script>require(['image']);</script> //I will tell you about this js module later, just wait
###WOW!! Just look how simple it is. You don't need to create upload form by yourself, just generate it! It is especially useful when you have a lot of forms in a view, or a lot of views that use upload feature, so you don't need to copy paste each time you want to upload smth.
Tips:
- fileService - is a \Media\Service\File object
- type - is a type of file you need to upload. Use predefined constants, such as:
\Media\Entity\File::AUDIO_FILETYPE,
\Media\Entity\File::VIDEO_FILETYPE,
\Media\Entity\File::IMAGE_FILETYPE - id of the entity that owns the file. You need to bring it from the view to send appropriate ajax request to a controller (Calm down, I will show you how to create it later!).
##STEP 3
As I promised, we need to create .js file, which is used with upload form in order to send ajax requests to the controller (Yes, I will show you how to create it too, don't worry). Here I am using requirejs, so this .js file will be declared as module in config (look at STEP 2, we required this module in a View Part). We are going to upload images, so let's name this file image.js. You can make it like you want, but I will use an example from Jquery File Uploader (in fact, you just need to change url here):
define(['jquery', 'tmpl', 'iframe-transport', 'fileupload-ui'], function ($) {
$(function () {
'use strict';
$('#fileupload').fileupload({
var id = 1; //You must get this id in another way, that's just an example
url: 'module/car/start-image-upload/' + id
});
$('#fileupload').addClass('fileupload-processing');
$.ajax({
url:
$('#fileupload').fileupload('option', 'url'),
dataType: 'json',
context: $('#fileupload')[0]
}).always(function () {
$(this).removeClass('fileupload-processing');
}).done(function (result) {
$(this).fileupload('option', 'done').call(this, $.Event('done'), {result: result});
});
})});
##STEP 4
At this step we are going to create an another controller (ajax requests are sent to it). It is very simple, because we are using Jquery File Uploader, so we have to pay attention on such things:
- POST\GET requests. If it is a get request, we must return the list of images, if it is a post request, we must upload it.
- In both situations we must return appropriate json to make Jquery File Uploader display them as good as it can. To make that we must use Blueimp Service. Just look at this example, I think it is quite obvious:
public function startImageUploadAction()
{
$imageService = $this->getServiceLocator()->get('Media\Service\File');
$blueimpService = $this->getServiceLocator()->get('Media\Service\Blueimp');
if ($this->getRequest()->isPost()) {
$form = new \Media\Form\ImageUpload();
$inputFilter = new \Media\Form\Filter\ImageUploadInputFilter();
$form->setInputFilter($inputFilter->getInputFilter());
$request = $this->getRequest();
$post = array_merge_recursive(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
$this->getServiceLocator()->get('Doctrine\ORM\EntityManager')->getConnection()->beginTransaction();
$form->setData($post);
if ($form->isValid()) {
$tesla = $this->getServiceLocator()
->get('Doctrine\ORM\EntityManager')
->getRepository('Car\Entity\Car')->findById(1); \\That's just an example, this id will be sent from ajax
$image = $imageService->createFile($form, $tesla);
$this->getServiceLocator()->get('Doctrine\ORM\EntityManager')->getConnection()->commit();
$dataForJson = $blueimpService->displayUploadedFile($image, '/test/image/delete-image/');
} else {
$messages = $form->getMessages();
$messages = array_shift($messages);
$this->getServiceLocator()
->get('Doctrine\ORM\EntityManager')->getConnection()->rollBack();
$this->getServiceLocator()->get('Doctrine\ORM\EntityManager')->close();
$dataForJson = ['files' => [[
'name' => $form->get('image')->getValue()['name'],
'error' => array_shift($messages)
]]];
}
} else {
$dataForJson = $blueimpService->displayUploadedFiles(
$tesla->getImages(), //That's how simple we get all images
'/test/image/delete-image/' //It's an url mask, that must contain module, controller, action
);
}
return new JsonModel($dataForJson);
}
###WOW!!! Oh my God, as you can see, uploading a file for an object is the simplest thing you have ever seen, you just need to call one method $image = $imageService->createFile($form, $tesla);. As you can see, we pass to it a whole form (it will get the file from it) and the object, that will be the owner of the image.
##Few words about video and audio Everything is similar, but by default you can upload only mp3 files for audio, and mp4 for video. That's not a mandatory, because you can solve this problem by extending, or converting. Look at these services to see, how the conversion is done