-
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.
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();
STEP 1
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 two 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'; } `
-
STEP 2
You need to create a controller, in which you should have action, that will send file service to a view to generate upload form. There are three forms: AudioUpload, VideoUpload, ImageUpload. Here it is an example how it all works:
Controller
class CarController extends AbstractActionController { public function uploadImageAction() { $imageService = $this->getServiceLocator()->get('Media\Service\File'); $id = 1; //or get it from the url, whatever return new ViewModel([ 'imageService' => $imageService, 'type' => File::IMAGE_FILETYPE, //Obviously, you can choose between image, audio, video 'id' => $id ]); }
View `
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`
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, which will be the owner of the file. You need to bring it from the view
to send appropriate ajax request to a controller, which we will create later!.
STEP 3
As I promised, we need to create .js file, which we use with upload form in order to send ajax requests on a controller, which we also will create soon. 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 here I will use an example from Jquery File Uploader, here it is (I marked two strings you need to edit):
`
define([
'jquery',
'tmpl',
'iframe-transport',
'fileupload-ui'
], function (
// Initialize the jQuery File Upload widget:
$('#fileupload').fileupload({
// Uncomment the following to send cross-domain cookies:
//xhrFields: {withCredentials: true},
var id = 1 //I repeat, you must get this id in another way, that's just an example
url: 'module/car/start-image-upload' + id
});
// Enable iframe cross-domain access via redirect option:
$('#fileupload').fileupload(
'option',
'redirect',
window.location.href.replace(
/\/[^\/]*$/,
'/cors/result.html?%s'
)
);
if (window.location.hostname === 'blueimp.github.io') {
// Demo settings:
$('#fileupload').fileupload('option', {
url: '//jquery-file-upload.appspot.com/',
// Enable image resizing, except for Android and Opera,
// which actually support image resizing, but fail to
// send Blob objects via XHR requests:
disableImageResize: /Android(?!.*Chrome)|Opera/
.test(window.navigator.userAgent),
maxFileSize: 5000000,
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i
});
// Upload server status check for browsers with CORS support:
if ($.support.cors) {
$.ajax({
url: '//jquery-file-upload.appspot.com/',
type: 'HEAD'
}).fail(function () {
$('<div class="alert alert-danger"/>')
.text('Upload server currently unavailable - ' +
new Date())
.appendTo('#fileupload');
});
}
} else {
// Load existing files:
$('#fileupload').addClass('fileupload-processing');
$.ajax({
// Uncomment the following to send cross-domain cookies:
//xhrFields: {withCredentials: true},
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 Now we must to create a Controller, on which ajax requests will be sent. It is very simple, because we are using Jquery File Uploader, so we have 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 obviouse: ` 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( $user->getImages(), '/test/image/delete-image/' ); } return new JsonModel($dataForJson);}
As you can see, creating a file for an object is quite simple, you just need to call one method$image = $imageService->createFile($form, $tesla);`. As you can see, we pass to it a whole form, from which it will get the file, and the object, that will be the owner of the image