User Login with Zend Framework

10May08

So my last post I showed a simple little form I had created for letting people create records. Let’s talk about something a little more useful this time. It is very common to want to include a login form, or if they have logged in, some user control bar on every page in your site/application. Let me emphasize, I am by no stretch of the imagination the holy grail of how to do stuff, and would be safe to say that since I am suggesting this approach it is, not the best way. :) However, it has served me well in the few applications I have made with Zend Framework, thus I will share.

** Update **

File Structure
Below is how I structured my files:
+ Project

+ app
  + forms
  + layouts
    + helpers (If you put your view helpers here, register this dir as a view helper dir)
    + scripts
  + lib
  + models
  + modules
    + default
      + controllers
      + views
        + scripts
        + helpers (default location Zend FW looks for View Helpers when default         module invoked)
+ config
+ misc
+ www

Invoking Code
Since, we will be putting this on every page it makes sense to put the invoking code in Zend_Layout. If, you aren’t using Zend_Layout.. I highly suggest you start migrating it into your code. Zend Layout basically allows you to have a “layout” for different pages, which renderes “templates” that correspond to the actions. (That’s a nutshell version) So in my layout I simply put:

echo $this->userControlBar();

This will invoke Zend_View to look for the view helper: UserControlBar. Now it’s good to know a couple of things here, each page request will only have one Zend_View object. So, Zend_Layout, doesn’t have it’s own view object, rather the Zend_View is injected into the Zend_Layout. This means, that the view helper User Control Bar, has to be registered with the view for that action. I may be over-complicating the issue, just be sure that you could call $this->userControlBar() in the template scripts corresponding to all the actions. :)

The View Helper
Now, we need the View Helper. In the helper, we will call default View Helpers that come with Zend_View but in order to do that we have to register the View object with the View Helper. To do that we simply add the following method to our View Helper:

    public function setView($view) {
        $this->_view = $view;
    }

Then the next method we make is the actual View Helper:

    public function userControlBar() { echo 'hi'; }

This should return ‘hi’ in the Layout. Now we simply, need to make it work. We want to first determine if the user has been authenticated which can be done with:

    Zend_Auth::getInstance()->hasIdentity()

This, as expected, will return true or false. So let’s put it in a little if statement:

    if(Zend_Auth::getInstance()->hasIdentity()) {
      //user is logged in
    } else {
      //user is not logged in
    }

Now let’s just say we want 3 controls, and we want the html to be:

We can do this very easily with two default View Helpers: (htmlList, and url). First thing we need to do is build an array of the links we want to show. You -could- abstract this out another level it warranted it, but we have a simple app, so we can just hard code this array (note how we are utilizing the registered view):

   $links = array();
   $links[] = '<a href="' . $this->_view->url(array('controller'=>'action1'),
 '', true) . ">Control One';
   $links[] = '<a href="' . $this->_view->url(array('controller'=>'action2'), 
'', true) . ">Control Two';
   $links[] = '<a href="' . $this->_view->url(array('controller'=>'action3', 
'param'=>'value'), '', true) . ">Control Three';

Then we can register the $links array with the View Helper htmlList:

   //Should change name most likely :)
   $linkList = $this->_view->htmlList($links, false, array('id'=>'userControl') , false);

The above code will generate the HTML we need. So our ViewHelper now looks like:

   if(Zend_Auth::getInstance()->hasIdentity()) {
      //user is logged in
      $links = array();
      $links[] = '<a href="' . $this->_view->url(array('controller'=>'action1'), '', true)
 . ">Control One';
      $links[] = '<a href="' . $this->_view->url(array('controller'=>'action2'), '', true)
 . ">Control Two';
      $links[] = '<a href="' . $this->_view->url(array('controller'=>'action3', 
'param'=>'value'), '', true) . ">Control Three';
      //Should change name most likely :)
      $linkList = $this->_view->htmlList($links, false, array('id'=>'userControl') , false);
      return $linkList;
   } else {
      //user is not logged in
   }

Now that’s all good and dandy, but what if they aren’t logged in? Well, we have two options here, we can just write the Form ourself or use Zend_Form. I personally love Zend_Form. However for sake or this tutorial we will just generate the html ourself. You can simply put the html of the form in a variable and return it for now, that way if you want to do it the right way later, and use Zend_Form, it’s really easy :)

      ...
   } else {
       $form = '... html for login form here ...';
      return $form;
   }

That’s it. Now in all of our pages we will either have a login form or a control bar. We’ve used the View Helpers, Zend_Layout, *hopefully Zend_Form*, wrote our own Helper, and the gorgeous part is we haven’t touched the “Application” code inside the Modules/Defaults/Controllers. We simply listen to Zend_Auth and return whatever.

Hope this helps, and I’d love to see how I could improve my technique.

About these ads


3 Responses to “User Login with Zend Framework”

  1. Hi,

    I’m just curious to know how you made your helper avialable for the layout view.
    I tried this in the bootsrap (doesn’t seem to work) :

    $layout = new Zend_Layout($config->layout->toArray(), true); // Starts the MVC
    $view = $layout->getView();
    $view->addHelperPath(‘application/views/helpers’, ‘Default_View_Helper’);

    I defined Default_View_Helper_Join like this :

    class Default_View_Helper_Join extends Zend_View_Helper_Abstract {
    public function Join() {
    $output = ‘TEST’;
    }

    In the layout.pthml :

    join() ?>

    And apparently, Zend_Loader can’t load my helper …

    Uncaught exception ‘Zend_Loader_PluginLoader_Exception’ with message ‘Plugin by name Join was not found in the registry.

  2. 2 HerrSerker

    I have it in a plugin:

    view)) {
    $viewRenderer->init();
    }
    $this->_view = $viewRenderer->view;

    // add View/Helper directory to path
    $prefix = ‘My_View_Helper’;
    $dir = dirname(__FILE__) . ‘/../layouts/helpers’;
    $this->_view->addHelperPath($dir, $prefix);

    }
    }

  3. Hi, I’ve done something pretty similair to what you’ve done here – but my problem now is to figure out what action to assign to the form – since it is not associated directly with any specific controller/action/view. I would be sooooo grateful if you could help me out here – the ZForums are a dead end, and Stack is also pretty quiet on that front.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

%d bloggers like this: