Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
A standardised way for handling AJAX responses across your Zend Framework application.
PHP JavaScript
Branch: master

README.md

Zend-AjaxResponse | jQuery's $.get() and $.post() on steroids!

So I heard you do $.get(), $.post() requests for your awesome Zend application. On the "happy path" everything is working, you get what you expected. Fair enough, so far so good...

Scenario

Your AJAX calls most probably populates partial HTML into some div tags, or does some other awesome stuff?

Now you implemented authentication, possibly combined it with ACL. What would happen if user's session would expire or your user is not allowed to access specific action/actions? Could the user expect to get the same output? Or maybe!?... most probably your div tag is now populated with contents from your login screen ;)...

That's where it comes into help!

Exactly! To keep your users happy, to make testing team happy and to sleep tight every night you SHOULD use this library - a set of seamless Zend classes and jQuery plugin.

Sounds good, so where to start?

So you will have AjaxResponse container object injected into Zend_Registry with each request. The FrontController plugin will check for AJAX requests and will wrap rendered view, response status, error code, error message and even redirectUrl into JSON object and will send it off to response body after last dispatch.

What you need to do is just use $.AjaxResponse.get() instead of $.get() and $.AjaxResponse.post() instead of $.post().

Installation

Add this line to your application.ini

autoloaderNamespaces.AjaxResponse = "AjaxResponse_"

In your application/Bootstrap.php make sure you add this method

/**
 * Initialises AjaxResponse Controller Action Helper and FrontController plugin
 *
 * @return void
 * @param void
 */

protected function _initAjaxResponse()
{
    // so let's start by creating the container for AJAX response
    $container = new AjaxResponse_Container;

    // "what's your address, Sir? :)"
    $basePath = realpath(APPLICATION_PATH . '/../library/AjaxResponse');

    // register path to our controller action
    Zend_Controller_Action_HelperBroker::addPath(
        $basePath . '/Controller/Action/Helper',
        'AjaxResponse_Controller_Action_Helper_'
    );

    // register controller plugin
    Zend_Controller_Front::getInstance()->registerPlugin(
        new AjaxResponse_Controller_Plugin_AjaxResponse()
    );

    Zend_Registry::set('AjaxResponse', $container);
}

By doing this we will attach our FrontController plugin and will register Action Helper for your controllers to do some amazing stuff on your demand.

Exploit the power of AjaxResponse

Let's say in your Auth plugin you could do this:

/**
 * Returns AjaxRequest container object
 *
 * @param void
 * @return AjaxResponse_Container
 */

private function _getAjaxRequestContainer()
{
    return Zend_Registry::get('AjaxResponse');
}

/**
 * Initialises Acl
 * Before each and every action dispatch this will be triggered
 *
 * @param Zend_Controller_Request_Abstract $request
 * @return void
 */

public function preDispatch(Zend_Controller_Request_Abstract $request)
{
    // ...

    if(false === $acl->has($resource)) {
        // resource does not even exist

        // get our AjaxResponse container object
        $container = $this->_getAjaxRequestContainer();

        if(false === $container->isAjaxRequest()) {
            // on normal request just redirect user to the index page
            $redirector->gotoSimple('index', 'index', 'default');
        } else {
            // fun begins with AJAX request

            $container
                ->setFailureStatus('your_error_code', 'your_error_message', '/default/error/error')
                // lock the container that NOTHING could be changed by your actions
                // so when the time will come for AjaxResponse plugin to put your action's rendered view contents
                // into container's body it will be just ignored and skipped!
                ->lock();
        }
    }

   // ...
}

So even in that situation your AJAX response will become bullet proof.

Normally you don't need to add ANYTHING to support AJAX requests out of the box for EVERY of your actions. Zero lines of additional code in each action's method. But you can do even this:

class IndexController extends Zend_Controller_Action
{
    public function ajaxTestAction()
    {
        // you can use helper to override anything in AjaxResponse container, even if it was locked before! ;)
        $this->getHelper('AjaxResponse')
            // first we need to unlock the container for further changes
            ->unlock()
            // then modify things
            ->setSuccessStatus()
            // override previous body and lock the container again if you want ;)
            ->setBody('whoohoo, no one will change this')
            ->lock();
    }
}

Now the Javascript part

$(document).ready(function() {

    $('#magic').click(function() {

        // you can call GET AJAX requests, the way you normally call $.get(...);
        // ... without "onFailure" callback user will be redirected to redirectUrl value received from server
        $.AjaxResponse.get('/default/index/ajax-test', function(response) {
            console.log('success', response);
        });

        // plus, instead of just declaring one callback function
        // you can now have "onSuccess" and "onFailure" functions
        $.AjaxResponse.get(
            '/default/index/ajax-test',
            {
                // so this would be called if AjaxResponse received "success" status
                onSuccess: function(response) {
                    // response variable actually is body property value
                    console.log(response);
                },

                // you can do your AWESOME failure handling here
                onFailure: function(errorCode, errorMessage, redirectUrl) {
                    // on failure you will accept errorCode and errorMessage
                    console.log(errorCode, errorMessage);

                    // you could do additional stuff and THEN do a redirect...
                    if(redirectUrl) {
                        window.top.location = redirectUrl;
                    }
                }
            }
        );

        // ... or do POST requests, like you do with $.post(...);
        // you can utilise "onSuccess" and "onFailure" in EXACTLY the same manner like in $.AjaxRequest.get()
        $.AjaxResponse.post('/default/index/ajax-test', { something: 'xyz', variable: 3 }, function(response) {
            console.log(response);
        });
    });
});

Contribute

Please, DO CONTRIBUTE. If you find some inconsistencies, any possible features, fork it, add some COOL stuff and do a pull request. I will be more than happy to approve a good contribution :)!

Author

Author of this software is Laurynas Karvelis laurynas.karvelis@gmail.com working @ Explosive Brains Ltd. Released under "DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE" http://sam.zoy.org/wtfpl/COPYING

Something went wrong with that request. Please try again.