Jump to content

ZF - run action in background - output before end of action


dgoosens

Recommended Posts

hi freaks,

 

I have spend two days on this and did not find any solution yet... Hope you can help me out here.

 

This is the situation:

For one of my customers I need to create an interface for sending newsletters.

I am working with Zend Framework 1.10 for this...

 

The last step of the whole process is the sending...

Knowing there might be thousands of contacts, I do not want to wait for it to be done...

Thus, I'd need to have the sendAction() to run in the background (quite easy - even if I close the browser the mails are sent)... and redirect the user to the indexAction() immediately.

 

I have been trying to do this with JQuery and an ajax call...

To do so, I figured I'd just have to disable the buffering

protected function _initDisableoutputbuffering() {
        $fc = Zend_Controller_Front::getInstance();
        $fc->setParam('disableOutputBuffering', true);
}

in the bootstrap and use ob_flush(); flush(); in the action to send a simple "ok"

public function asyncsendAction() {

    $this->_helper->getHelper('layout')->disableLayout();
    $this->_helper->viewRenderer->setNoRender();

    $mailId = $this->_request->getParam('mailId');
    $this->_helper->FlashMessenger('The mails are being sent now... You\'ll be notified by mail when it is done.');

    echo "ok";
    ob_flush();
    flush();
    

    $i = 0;
	// simple test send
    while($i < 15) {
        $mail = new Zend_Mail('utf-8');
        $mail->setBodyHtml('test test');
        $mail->setFrom('me@me.com', 'me');
        $mail->addTo('you@you.com');
        $mail->setSubject('test' . $i);

        $mail->send();
        $i++;
    }
}

to the ajax script which would then redirect:

<script type="text/javascript">
    $(function(){
        $('#sendMailing').click(function(){
            $.ajax({
                url: "/site/mails/asyncsend/mailId/<?php echo $this->mailId; ?>",
                success: function(data) {
                    if(data == "ok") {
                        $(location).attr('href', '/site/mails/');
                    } 
                }
            });
            return false;
        });
    });
</script>

 

I think I tried a thousand possible variations on this... but it simply does not work.

The redirect is working, but only when all the mails have been sent.

 

This does not have anything to do with my PHP.ini settings as the output_buffer is set on "off".

 

So, either it is the browser that does not want to redirect before the end of the action OR it is my Action that is not sending the "ok" before the end of it.

 

I know I could handle this with a cron job... But I would really like to avoid this as much as possible.

 

Any of you have any thoughts on this ?

 

Thanks,

dGo

 

ps: do not worry, this app will not be used for spamming

I would not want to develop it otherwise.

Link to comment
Share on other sites

me again...

 

so I tried another way and implemented the following JQuery script:

<script type="text/javascript">
    $(function(){
        $('#sendMailing').click(function(){
            $(location).attr('href', '/wikiwi/mails/');
            $.ajax({
                url: "/wikiwi/mails/asyncsend/mailId/<?php echo $this->mailId; ?>",
            });
            return false;
        });

        
    });
</script>

this seems to work...

although... can I be sure that the mails will be sent this way ?

 

Also, I am facing a new problem...

as long as the mails aren't sent, it seems that I am unable to navigate to any other page...

I am not quite sure I understand where this new issue comes from...

why is it the server does not accept any other calls while the mails are being sent ?

 

any help would be greatly appreciated...

thanks

dGo

Link to comment
Share on other sites

lol

little disappointed here guys...

not one reply...

was it that mysterious or unclear ???

 

well anyway, it seems like I've found a workable solution here

http://w-shadow.com/blog/2007/10/16/how-to-run-a-php-script-in-the-background/

 

the annoying part is that I have to serialize() and urlencode() my params in the URL...

is there a smarter way to pass the params along with the request ?

 

// sendaction
public function sendAction() {

        $this->_helper->getHelper('layout')->disableLayout();
        $this->_helper->viewRenderer->setNoRender();

        $mailId = $this->_request->getParam('mailId');

        $session = Zend_Registry::get(Zend_Registry::get('sessionName'));
        $mailContacts = $session->mailContacts;
        $senderDetails = $session->senderDetails;

        $url = $this->_helper->url('sendmails', 'mails', 'wikiwi', 
                        array(  'mailId' => $mailId,
                                'dGoKey' => md5('W!kiwI2401198dG0'),
                                'senderdetails' => urlencode(serialize($senderDetails)),
                                'contacts' => urlencode(serialize($mailContacts))));

        if(self::backgroundPost($url, $senderDetails, $mailContacts)) {
            $this->_helper->FlashMessenger('L\'envoi du mailing a commencé.');
            $this->_helper->redirector('index');
        }
    }

 

the contacts array could contain thousands of entries... and it seems that this way of doing is kind of limited...

any ideas ?

 

thanks

dGo

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.