Namespacing ACL resources and Galahad_Acl

Chris Morrell writes; In most of my applications I like to handle authorization (querying the ACL) in one (or more) of three ways:

  • Authorize access to a model’s method
  • Authorize access to a controller action
  • Authorize access to an arbitrary “permission”

In general I find it’s best to keep authorization within the domain (querying the ACL within my models when they’re accessed) as this provides the most consistent behavior. For example, if I eventually add a REST API to my application I don’t have to duplicate all my authorization logic in the new REST controllers. When the application calls something like Default_Model_Post::save() it either saves or throws an ACL exception, no matter where it was called from. This is great in that it saves me from having to duplicate code and keeps my system more secure.

On the other hand, there are times when it’s just a lot easier to handle authorization in the controller. For example, if guests should never access my “Admin” module, it doesn’t make sense to ever let them access /admin/ URLs. Also, if you’re using Zend_Navigation, having ACL resources that match controller actions lets you utilize its ACL integration.

If you’re ever going to mix these two techniques, you’ll eventually bump into the case where a model and a controller share the same name. What if you need to set permissions on a “user” controller and different permissions on a “user” model? This is where namespacing comes into play. As suggested by the Zend Framework manual, I always name my controller action resources in the format mvc:module.controller.action. I name my model resources similarly, in the format model:module.modelName.methodName. In both theses cases, “mvc” and “model” are the namespace, and everything following the colon is the actual resource name. Now I can refer to my “admin” module as mvc:admin and the models within my admin module as model:admin.

This is where things get interesting.

Read on; “Namespacing ACL resources & Galahad_Acl”.

Chris continues; Right now I treat my models as resources with a special exception for the user model which is both a resource and a role. Then I actually make the models responsible for managing their own ACL permissions, both setting them up and querying them. To facilitate that, I have a base model class that does a few things. First it has a way to inject an ACL instance into the model as well as a way to pass an ACL instance as the default ACL for all models (which I do in my bootstrap). Second it automatically adds itself to that ACL (with the resource id model:moduleName.modelName). Finally, I have an _initAcl() method which is called when my model is instantiated which adds the appropriate rules to the ACL if they don’t already exist. Whenever my model is doing something that is access-controlled I check the ACL right then.

Here’s a simple code example:


class Default_Model_Post extends Galahad_Model_Entity
{
protected function _initAcl($acl)
{
// Deny permissions to anything on this model unless explicitly allowed
$acl->deny(null, $this);

// Allow guests to fetch the content of posts
$acl->allow('guest', $this, 'fetch');

// Allow admins to save changes to posts
$acl->allow('admin', $this, 'save');
}

public function save()
{
if (!$this->getAcl()->isAllowed($this->getRole(), $this, 'save')) {
throw new Galahad_Acl_Exception('Current user is not allowed to save posts.');
}

$dataMapper = $this->getDataMapper();
return $dataMapper->save($this);
}
}

There’s a little bit more happening in there (for example, I also have helper methods like getRole(), which either gets the role ID stored in the model or grabs it from Zend_Auth if available), but you should get the picture.

That way my access control is happening when the access itself is happening. No matter how my model is used, the ACL is always queried right when it matters. I also like setting up the ACL this way because all rules are loaded into the the ACL only when they could potentially apply (you never need the rules for a Post model if the current request never even loads the Post class).

This is something I’ve been thinking about a lot lately, and I’m just settling into this method. I just blogged about it a little over a week ago: “Namespacing ACL resources & Galahad_Acl” — if anyone has any comments I’d love to hear them

Doctrine – Doctrine 2: Give me my constructor back

John Wage writes; At ConFoo 2010 during my presentation, someone asked about the constructor of entities in Doctrine 2 and whether or not it could be used. I think this is something worth writing about since in Doctrine 1 this was not possible. The constructor was hi-jacked from you and used internally by Doctrine.

In Doctrine 2 it is possible to define the constructor in your entity classes and is not required to be a zero argument constructor! That's right, Doctrine 2 never instantiates the constructor of your entities so you have complete control!

This is possible due to a small trick which is used by two other projects, php-object-freezer and Flow3. The gist of it is we store a prototype class instance that is unserialized from a hand crafted serialized string where the class name is concatenated into the string. The result when we unserialize the string is an instance of the class which is stored as a prototype and cloned everytime we need a new instance during hydration.

Have a look at the method responsible for this:

Read the full article at; Doctrine – Doctrine 2: Give me my constructor back.

Zend Studio code formatter for Zend Framework

Updated: 2013-12-13 – Fixed links!

This is an excellent addition to you tools arsenal if you use Zend Studio and Zend Framework. Kudos to Ivo Jansh for publishing this!

Zend Studio is a great IDE and we use it a lot at Inviqa (in addition to NetBeans, PDT and Vim). One of the nice features is the code formatter that helps develop code according to agreed standards, which is useful to keep projects consistent.

One problem we have with the current versions of Zend Studio is that its default Zend Framework formatter is not consistent with the official Zend Framework coding standard. Luckily, that can be easily fixed. Sandy Pleyte, one of our developers, created a formatting file for Zend Studio that does adhere to the formal standard. There might be a few issues here and there but we’ve found it to work much better than the default one in Zend Studio. Because it might be helpful to others, we’re sharing the formatter file with anyone that’s interested. Download the file and read on for instructions.

 

Instructions

Download the above file to your desktop. Open the Zend Studio formatter preferences, which will give you the following screen:

Click the ‘import’ button and import the file that you’ve downloaded. Voila, your formatter now uses the Zend Framework official coding standards. If you find any issues with this formatter, please let us know in the comments below.

ATK formatter

If you use the ATK business framework, you might also be interested in the following formatter, which is similar to the ZF formatter but adds support for some of ATK’s coding conventions:

Have fun!

via techPortal.

A Simple Resource Injector for ZF Action Controllers

Matthew Weier O’Phinney writes a very useful article about resource injection; Brandon Savage approached me with an interesting issue regarding ZF bootstrap resources, and accessing them in your action controllers. Basically, he’d like to see any resource initialized by the bootstrap immediately available as simply a public member of his action controller.

So, for instance, if you were using the “DB” resource in your application, your controller could access it via $this->db.

I quickly drafted up a proof of concept for him using an action helper:


class My_ResourceInjector extends Zend_Controller_Action_Helper_Abstract
{
protected $_resources;

public function __construct(array $resources = array())
{
$this->_resources = $resources;
}

public function preDispatch()
{
$bootstrap = $this->getBootstrap();
$controller = $this->getActionController();
foreach ($this->_resources as $name) {
if ($bootstrap->hasResource($name)) {
$controller->$name = $bootstrap->getResource($name);
}
}
}

public function getBootstrap()
{
return $this->getFrontController()->getParam('bootstrap');
}
}

In this action helper, you would specify the specific resources you want injected via the $_resources property – which would be values you pass in. Each resource name would then be checked against those available in the bootstrap, and, if found, injected into the action controller as a property of the same name.

You would initialize it in your bootstrap:


class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initResourceInjector()
{
Zend_Controller_Action_HelperBroker::addHelper(
new My_ResourceInjector(array(
'db',
'layout',
'navigation',
));
);
}
}

The above would map three resources: “db”, “layout”, and “navigation”. This means you can refer to them directly as properties in your controllers:


class FooController extends Zend_Controller_Action
{
public function barAction()
{
$this->layout->disableLayout();
$model = $this->getModel();
$model->setDbAdapter($this->db);
$this->view->assign(
'model' => $this->model,
'navigation' => $this->navigation,
);
}

// ...
}

This approach leads to some nice brevity — you no longer need to fetch the bootstrap from the instantiation arguments, and then fetch the resource.

I thought about it some more, and realized that there’s a few problems: How do you know what is being injected from within the controller? How do you control what is being injected.

So, I revised it to pull the expected dependencies from the action controller itself…

Read the complete article here A Simple Resource Injector for ZF Action Controllers.

DataTables – table plug-in for jQuery

The other day I had to write a  NOC application that shows all active phone lines in an out of a customers telecom cluster, thats a lot of constantly changing data that needed to be displayed.

Some design requirements was;

  • *NO* refreshes i.e. blinking screen parts (gives NOC personel an epileptic fit after a day staring at it).
  • No direct database access – read only Json proxy.
  • Near realtime – 1 second updates.
  • Group lines on customer. Toggle on and off.
  • Sortable on all visible columns.
  • Searchable and one click filters.
  • Has to work in an Dojo ContentPane.
  • 100% translatable

To the rescue; DataTables is a plug-in for the jQuery Javascript library.  It is a highly flexible tool, based upon the foundations of progressive enhancement, which will add advanced interaction controls to any HTML table.

I can’t recommend it highly enough, configuration is as easy or as hard as you require it to be, draw up a file with a regular table,thead,tbody,tfoot table put it’s id to be example and place this code snippet into the file;
/*
* Example init
*/
$(document).ready(function(){
$('#example').dataTable();
});

Then popp over to Allans excellent Examples page! and if you dont have a sortable, searchable and great looking grid in about 5 minutes, I owe you a beer!
Key features:

  • Variable length pagination
  • On-the-fly filtering
  • Multi-column sorting with data type detection
  • Smart handling of column widths
  • Display data from almost any data source
  • DOM, Javascript array, Ajax file and server-side processing (PHP, C#, Perl, Ruby, AIR, Gears etc)
  • Fully internationalisable
  • jQuery UI ThemeRoller support
  • Rock solid – backed by a suite of 1300+ unit tests
  • Wide variety of plug-ins inc. TableTools, FixedHeader and KeyTable
  • It’s free!
  • State saving
  • Hidden columns
  • Dynamic creation of tables
  • Ajax auto loading of data
  • Custom DOM positioning
  • Single column filtering
  • Alternative pagination types
  • Non-destructive DOM interaction
  • Sorting column(s) highlighting
  • Extensive plug-in support
  • – Sorting, type detection, API functions, pagination and filtering
  • Fully themeable by CSS
  • Solid documentation
  • Full support for Adobe AIR

Go NOW and take a peek DataTables (table plug-in for jQuery).

Updated Zend_Dojo_View_Helper_Dialog

Charles Kyle Spraggs writes; I’ve been tinkering around with view helpers quite a bit now and I realized that a lot of what I did in the Dialog could be done much easier by extending the DijitContainer view helper. So, I rewrote the dialog view helper to extend DijitContainer and moved Zend_Dojo_View_Helper_Dijit_Extended to Zend_Dojo_View_Helper_Dojo_Extended because the methods are meant to be used statically similar to Zend_Dojo_View_Helper::setUseDeclarative(). For those of you that have no idea what I’m talking about you should read Zend_Dojo_View_Helper_Dialog first.

New code!

Zend_Dojo_View_Helper_Dojo_Extended

This little puppy exists for the sole purpose of adding stylesheets based on the set dojo path (local/CDN) and version (if CDN).

Usage

// Code from Zend_Dojo_View_Helper_Dialog which adds the stylesheet for enhanced dialogs
Zend_Dojo_View_Helper_Dojo_Extended::addStylesheet('/dojox/widget/Dialog/Dialog.css');

more at SpiffyJr’s Blogaroo.

Zend Framework MVC Request Lifecycle

Kevin Schroeder writes an excellent article about the MVC lifecycle thats a must read for anyone even thinking about writing ZF plugins; Matthew wrote up an article on modules in Zend_Application and that got me thinking a little bit. When I have done training for Zend Framework, one of the things that mystifies students to some extent is the whole plugin architecture and where things can go. There has been several articles written about it, but they tend to use code to describe it. I was only able to find a small handfull of articles that used some kind of chart to describe what goes on. Not that that’s a problem, but I had found that when I drew out the request lifecycle that it helped the students understand it better.

The chart on the right is a color-coded chart that shows when something is executed and where it is executed from. This chart is intentionally missing a whole bunch of things for the purpose of simplicity. If you want a more full explanation of the request lifecycle…

Read full story Friday Framework Highlight: Zend Framework MVC Request Lifecycle