Thursday, August 25, 2011

How to use Zend ACL


This feature will be useful for the one who actually wants to control the user roles & privileges to access modules/action in the Zend Framework projects.

First create a class and define your roles and resources to be used.

Eg:

Roles: Admin, user, Guest
Resources: default, admin (in this eg resources are modules)

CLASS:
<?php

class MyAcl extends Zend_Acl
{
    	public function __construct()
    	{
        	// Resources
        	/* Default module */
	$this->add(new Zend_Acl_Resource('default'));
	/* Admin module */
	$this->add(new Zend_Acl_Resource('admin'));

	// Roles
	$this->addRole(new Zend_Acl_Role('Admin'))
	->addRole(new Zend_Acl_Role('User'), 'Admin')
	->addRole(new Zend_Acl_Role('Guest'));

	// Authorization
	$this->deny('Guest', 'admin');
	->allow(array('Admin', 'User', 'Guest'), array('default'))
	->allow(array('Admin', 'User'), array('admin'));
	}
}
?>


Next you need a plugin to check the routes and to autorize based on the roles & resources. If the route is not autorized it'll go to $_noauth at the same time if the role is not having access to resource it'll go to $_noacl. By default the role will be “Guest”.

PLUG-IN:

<?php

class Plugin_Auth extends Zend_Controller_Plugin_Abstract{

    
    private $_auth;
    private $_acl;

    private $_noauth = array ('module' => 'login', 'controller' => 'index', 'action' => 'index');   
    private $_noacl = array ('module' => 'default', 'controller' => 'error', 'action' => 'denied');
   
    public function __construct ()
    {
        $this->_auth = Zend_Auth::getInstance();      
        $this->_acl = new MyAcl();
    }

    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
              
            $role = 'Guest';
            if($this->_auth->hasIdentity())
            {
                $role = $this->_auth->getIdentity()->role;               
            }
            $controller = $request->controller;
            $action = $request->action;
            $module = $request->module;
	
	// Assign resource based on your requirements
            $resource = $module;

            if (!$this->_acl->has($resource))
            {
                $resource = null;
            }

            if (!$this->_acl->isAllowed($role, $resource, $action)) //$role, $resource, $action
            {
                if(!$this->_auth->hasIdentity())
                {
                    $module = $this->_noauth['module'];
                    $controller = $this->_noauth['controller'];
                    $action = $this->_noauth['action'];
                }
                else
                {
                    $module = $this->_noacl['module'];
                    $controller = $this->_noacl['controller'];
                    $action = $this->_noacl['action'];
                }
            }

            $request->setModuleName($module);
            $request->setControllerName($controller);
            $request->setActionName($action);
        }

    }
?>  

Monday, April 18, 2011

Bootstrapping in Zend Framework

In Zend Framework basically request is handled as follows:

   1. Application bootstrapping
   2. Routing
   3. Dispatch

"Bootstrapping" was handled by Zend_Application after that the route(module, controller, and action were requested) was identified in "Routing".  .

In general bootstrapping creates a single entry point for our whole application so it makes our application at the start itself "getting it ready to execute". It'll load all our necessary files as soon as the routing & dispatch is done.


For modules, before routing and dispatch we need some things set up:
  • Autoloading support for module resources( view helpers, access to models, access to forms, etc. ) and it'll be enabled by default.
  • Setting up module-specific routes. During bootstrapping and before routing occurs this will be specified.
  • Module-specific navigation elements. This usually goes hand-in-hand with your routes (most Zend_Navigation pages utilize named routes).
  • Setting up module-specific plugins. If there is functionality your module may be needing to enable as part of the routing/dispatch cycle, set this up in plugins and attach them to the front controller.
In the modular structure we can even specify separate bootstrap file for each module. So that we can do things specific to each modules and also we have a master bootstrap file to get full control.


FYI: I have come across one good PDF which explains all about ZF dispatch process - zenddispatch_en.pdf

Here is the exaple for config.ini file.

[production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"

autoloaderNamespaces[] = "Plugin"
autoloaderNamespaces[] = "Helpers"
autoloaderNamespaces[] = "Validator"

resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.frontController.params.displayExceptions = 1
resources.frontController.params.prefixDefaultModule = "1"

resources.frontController.actionhelperpaths.Helper_Action = APPLICATION_PATH  "/../library/Helpers/Action"


resources.modules[] =
resources.view[] =
resources.view.helperPath.Helper_View = APPLICATION_PATH "/../library/Helpers/View"

resources.db.adapter = "pdo_mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "username"
resources.db.params.password = "password"
resources.db.params.dbname = "database_name"
resources.db.params.charset = "utf8"
resources.db.params.driver_options.1002 = "SET NAMES utf8"
resources.db.isDefaultTableAdapter = true


resources.layout.layout = "layout"
resources.layout.layoutPath = APPLICATION_PATH "/layouts"


[staging : production]

[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.params.displayExceptions = 1

Friday, April 15, 2011

How to configure Zend Framework

In Zend Framework you have four ways to use configuration file.
  • Zend_Config_Ini
  • Zend_Config_Json
  • Zend_Config_Xml
  • Zend_Config_Yaml
In most of the case everyone will use Zend_Config_In,

Using Zend_Config_Ini you can store configuration information's in the well known INI format and also you can get them in the application by using nested object property syntax. In this INI format we have some hierarchy of configuration data keys and also its possible to inherit between sections. You can use dot or period character (".") to follow hierarchy. A section may extend or inherit from another section by following the section name with a colon character (":") and the name of the section from which data are to be inherited.

[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
appnamespace = "Application"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.params.displayExceptions = 0
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
resources.view[] =
resources.db.adapter         = pdo_mysql
resources.db.params.host     = localhost 
resources.db.params.username = user_name
resources.db.params.password = user_password
resources.db.params.dbname   = database_name

[staging : production]

[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.params.displayExceptions = 1 
In the above example, The DB was configured using a hierarchy of keys "resources.db.adapter" also the "Staging" was inherited( [staging : production] ) from "Production". Like this we can define configurations for different environment of our project.

Thursday, April 14, 2011

Directory structure in Zend Framework

Using ZF you can create your project as you wish but as its of MVC Architecture we need to follow simple rules like separating model, view & controller. So in order to achieve this you can use any of the two major classification in ZF,


Conventional Directory Structure: You have single MVC to cover your entire project.
index.php
.htaccess
library/
application/
         Bootstrap.php
configs/      application.ini layouts/   scripts/       layout.phtml controllers/          IndexController.php          TestController.php models/ forms/ views/ scripts/      index/         index.phtml      test/         test.phtml helpers/ filters/
If your project is big enough to have more modules the basic structure won't fit you so i recommend you guys to follow,

Modular Directory Structure: Its the reliable and very useful directory structure as far as i know, You can use this way to manage projects of any size. And more importantly in this style your entire project can be split up into several modules and it'll be very easy to manage & update individually.
index.php
.htaccess
library/
application/
         Bootstrap.php
configs/
     application.ini
layouts/ 
     scripts/
          layout.phtml
modules/
     default/
          controllers/
                   IndexController.php
                   TestController.php
          models/
          forms/
          views/
             scripts/
                  index/
                     index.phtml
                  test/
                    test.phtml
             helpers/
             filters/
     blog/
       controllers/
                IndexController.php
       models/
       forms/ 
       views/
          scripts/
               index/
                  index.phtml
          helpers/
          filters/
Please remind that either you need to specify "Default" module in configs file else you can create a module "default". With this you can decide about your directory structure in ZF.

In Htaccess file you need to give the following to rewrite all request to index.php by this single entry pont we achieve bootstrapping in ZF.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]

Sunday, February 20, 2011

Installation of Zend Framework

To install ZF you just need a LAMP platform and if you are done with this platform you can go for the step to install. For a beginner its better to download Quickstart(http://framework.zend.com/manual/en/learning.quickstart.create-project.html) and make use of the default directory structure of ZF.

Basically there are two ways to create modules, controllers like stuff in ZF.
1. Manually by knowing the exact directory structure & naming convention.
2. Using Zend Tool- http://framework.zend.com/manual/en/zend.tool.usage.cli.html

Using the above two ways you can create MVC structured ZF project.

Monday, December 27, 2010

Intro to Zend Framework

As far as i know worked in ZF, it was really good. The good thing about this Framework is, its the based on MVC and also it was the base for few open sources. It has a library like all other frameworks .

http://framework.zend.com/manual/en/learning.quickstart.intro.html

Model-View-Controller

So what exactly is this MVC pattern everyone keeps talking about, and why should you care? MVC is much more than just a three-letter acronym (TLA) that you can whip out anytime you want to sound smart; it has become something of a standard in the design of modern web applications. And for good reason. Most web application code falls under one of the following three categories: presentation, business logic, and data access. The MVC pattern models this separation of concerns well. The end result is that your presentation code can be consolidated in one part of your application with your business logic in another and your data access code in yet another. Many developers have found this well-defined separation indispensable for keeping their code organized, especially when more than one developer is working on the same application.

Note: More Information
Let's break down the pattern and take a look at the individual pieces:

learning.quickstart.intro.mvc.png

  • Model - This is the part of your application that defines its basic functionality behind a set of abstractions. Data access routines and some business logic can be defined in the model.

  • View - Views define exactly what is presented to the user. Usually controllers pass data to each view to render in some format. Views will often collect data from the user, as well. This is where you're likely to find HTML markup in your MVC applications.

  • Controller - Controllers bind the whole pattern together. They manipulate models, decide which view to display based on the user's request and other factors, pass along the data that each view will need, or hand off control to another controller entirely.