ihssan
ihssan

Reputation: 369

Two bundles use the same event listener

In my Symfony2 project, I have two bundles:

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

Answers (2)

George
George

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

Wouter J
Wouter J

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

Related Questions