Reputation: 369
In my Symfony2 project, I have two bundles:
UploadBundle
, which registers the uploaded file into a Database
; and * UploadSfdcBundle
, which registers the upoaded file in SalesForce
I am using oneup/uploader-bundle
to upload the files.
I configured the event listener for each Bundle like this:
For uploadBundle
:
services.yml:
services:
envivio_upload.upload_listener:
class: Envivio\UploadBundle\Listeners\UploadListener
arguments: [@doctrine.orm.entity_manager]
tags:
- { name: kernel.event_listener, event: oneup_uploader.pre_upload, method: onPreUpload }
- { name: kernel.event_listener, event: oneup_uploader.post_upload, method: onPostUpload }
UploadListener
class upload the file into the Database
and for UploadSfdcbundle:
services.yml:
services:
envivio_upload_sfdc.upload_listener:
class: Envivio\UploadSfdcBundle\Listeners\UploadSfdcListener
arguments: ["@codemitte_forcetk.client", "@codemitte_forcetk.query_builder"]
tags:
- { name: kernel.event_listener, event: oneup_uploader.pre_upload, method: onPreUpload }
- { name: kernel.event_listener, event: oneup_uploader.post_upload, method: onPostUpload }
UploadSfdcListener
upload the file in SalesForce
.
The problem is that if I want to upload the file in database
, the listener of SalesForce
will also be executed and vice versa.
How can I tell Symfony2 to use UploadListener
when I'm uploading to database
, and to use UploadSfdcListener
when I'm uploading to Salesforce
?
Upvotes: 1
Views: 559
Reputation: 1499
Since you are using OneupUploader, you should add some custom data with the upload so you know which process/upload type runs. Each controller/service that is responsible for rendering the twig page should pass a custom variable that is available in twig which I am calling 'filetype'. In your salesforce bundle, set
$filetype = 'salesforce';
I am using the blueimp frontend and here is how to add the custom data on your twig page:
<script type="text/javascript">
$(document).ready(function()
{
var url = "{{ oneup_uploader_endpoint('salesforce') }}";
$('#fileupload').fileupload({
url: url,
dataType: 'json',
formData: {
id: "{{user.getId}}"
,filetype: "salesforce"
},
done: function (e, data) {
$.each(data.result.files, function (index, file) {
$( "#begin" ).remove();
$('<p/>').text(file).appendTo('#files');
console.log(file);
console.log(data.result.files[index].name);
});
$('#progress .progress-bar').css('width', '100%');
},
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .progress-bar').css(
'width',
progress + '%'
);
}
});
$("#fileupload").change(function() {
$( '<p id="begin">Upload started...</p>' ).appendTo( "#files" );
});
});
In my event listener I have:
public function onUpload(PostPersistEvent $event) {
...
$uploadtype = $request->get('filetype');
switch ($uploadtype) {
//custom logic for each different type of upload
}
//code always processed for all files
}
When testing, I use chrome and look at console tab to see the data that is uploaded and then check the dev logs to see what was called and processed. It took a bit of work to get it correct, but I have many different parts where people can upload files with different purposes for those files. Some are saved in a private area, some are placed in a public storage service and I found it easiest to have 1 event listener sort out what should be processed instead of multiple listeners.
One issue with this is what bundle should this go into? If you want to make your code reusable, you may want separate listeners for each bundle and only process the filetype appropriate for that bundle. I have a 'master bundle' that manages the other bundles and this is where I have my event listeners. It works well for this project, but is not necessarily clean.
I'm open to anyone's thoughts if they do it differently since this is a very common situation.
Upvotes: 1
Reputation: 41934
Each event listener recieves a PostUploadEvent
/PreUploadEvent
event object. This has a getType()
method (which is the key of the onup_uploader.mappings
setting). Using this value, you can determine which controller was used. If it's the incorrect one, use return
to stop the execution of the method.
Upvotes: 2