Zend Framework RC1 and Zend ACL usage

If you're new here, you may want to subscribe to my RSS feed. Thanks for visiting!

logo.png

Yesterday RC1 of Zend Framework was released. I have been working away using it for several months and I have tried to give back small snippets of code as I went along. I had to do some work on my class that extends the Zend ACL and it reminded me how I like to approach coding as a whole.

I am a strong believer in building in functionality that always goes beyond the base requirements. In this vain I always think how I can make every feature extendable beyond its natural life span.

The Zend Framework being written in PHP 5 has really facilitated the ability to extend everything; every part of the framework seems to be bursting with abilities to extend in different directions. This can be either via helpers, plugins or just simple sub-classing.

In my own project I have extended the Zend ACL to add a range of functionality most of which is beyond my usual time constraints for documenting for a blog post, but I will cover one small method that I have found useful.

The ACL allows rules to be assigned under different resources so that you can separate rules or in fact repeat the same rule under the same different resources.

For example you could have the rule ‘news’ under two resources ‘latest’ & ‘announcements’. Using the ACL this would be written as.

$acl->add(new Zend_Acl_Resource('latest'), 'news');
$acl->add(new Zend_Acl_Resource('announcement'), 'news');

Once you start using the ACL for a few days it becomes obvious that editing the rules in code as above is slow and hard work to maintain. The rules & resources are not something I believe you need a editor for; but they do need to be simplified to rule out mistakes and save time.

The easiest route for me was to stick them into a .INI file which only needs to be parsed when it is updated.

Here is a short section from my ACL.INI

[email]
edit = “Edit”
add = “Add”
view = “View”
delete = “Delete”

[support]
edit = “Edit”
add = “Add”
view = “View”
delete = “Delete”

The words in square brackets represent a resource and the lines within each represent the rule and the rule description.

The code below is a single method that gets run anytime the .INI file changes. It takes care of adding resources that are missing.

public static function rebuildResources() 
{ 
	// Load the ACL ini 
	$config = new Zend_Config_Ini('config.ini', 'access');
	// Build the filename
 	$filename = $config->path.$config->filename;
	// Check if the file already exists
 	if(file_exists($filename)) {
 		$file = file_get_contents ($filename); 
		$access = unserialize($file); 
	} else {
		$access = new access;
	}
 
	// Load the list of resources
	$resources = parse_ini_file('acl.ini',true);
	$save = false;
	// step through all the resources 
	foreach($resources as $name => $rules) { 
		// See if we already have it 
		if(!$access->has($name)) { 
			// Add if we didnt 
			$access->add(new Zend_Acl_Resource($name)); 
			$save = true; 
		} 
	}
 	// Save them back if anything changed 
	if($save) {
		$file = serialize($access); 
		file_put_contents($filename,$file); 
	}
}

The first thing this code does is load up my global config file ‘config.ini’ using the Zend Framework Zend_Config_Ini which is well worth reading up on. In this context all I want from my config is the location of the ACL when I stored it away. Why do you need to store it? the ACL does not come with any functionality for storage ‘reasons explained here‘. You do have a wide range of options but for simplicity in this example I am using file_get_contents & file_put_contents alongside serialize/unserialize.

The next step is to read in ACL.INI file using parse_ini_file. The reason I do not use the Zend version is because parse_ini_file returns in a much easier to deal with format for my requirements for this job.

We then step through each of the resources and check using the member function ‘has’ to see if that resource has already been added. After we have stepped through all of the INI we check if anything was added and then save again.

Just a quick note to say that the method above must be used inside a class that extends the Zend_ACL. As shown below.

class access extends Zend_Acl
{
	...
}

This is just a small section but I hope it gives you some building blocks and ideas on how to use the ACL.

Lastly I would just like to say a big THANKS! to everyone who worked on the framework.

There Are 31 Responses So Far. »

  1. [...] Halstead takes a look at another aspect of the Zend Framework in his latest blog post - the ACL component in the most recent release, Zend Framework RC1. Yesterday RC1 of Zend [...]

  2. Isn’t Zend_Config_Ini overkill for concatenating a file name!? ;)

  3. Zend_Config_Ini contains (nearly) all the preferences for my whole application. When I used ‘Zend_Config_Ini(’config.ini’, ‘access’);’ it is requesting just one small chunk of the INI file, in this case it is loading the preferences for the storage location.

    Here is that entry (I did not include it as the code is just an example.)

    [access]
    path = resources/access/
    filename = access.dat

  4. Yes, but as the Zend framework states “Zend_Config_Ini utilizes the parse_ini_file() PHP function” so it’s sounds like it’s loading in the whole file as per parse_ini_file, then discarding the sections that are not required (Haven’t looked at the source mind)

    Not knocking it, as the code above is probably a very small portion of what you have implemented.

  5. Thanks!

  6. Code looks good, but how scalable/interactive will it be in the long run to store your ACL in a text file, why not a database? Admittedly, I am not familiar with the ZCE approach - so this is just an honest question.

  7. Because you will 99.9% of time be reading from the ACL having it as a text file is much faster than it being in a database. The file system will cache it and like reading any other php file it will be instant so I do not see any problem with it scaling. But the concept is sound whichever route you take for storage.

  8. I guess I am used to a different version of ACL. I implemented the default ACL in CakePHP for a recent project. They use MPTT and have the database structure in place for you. The database was the best solutions because as administrators added groups or users, those groups or users had to be given their proper permissions (injected into the tree). For instance, if we had user ‘John’ who was previously a manager in a department, and he was demoted to a minion - then as we changed his role, he would be assigned (injected) different permissions.

    I think it mostly has to do with the difference between the Cake ACL and Zend ACL, and as I said above - I am admittedly not familiar with the Zend ACL.

  9. I ran into a few snags working with Zend_Acl in 1.0 RC1, when trying to store a serialized ACL into MySQL. I want to have a full ACL object containing all the resources a particular user has access to stored in a field in my users table. However, MySQL was modifying the serialized ACL due to character set issues, I think.

    I’ve blogged about this today, and thought it might be helpful to other developers.
    http://www.oeic.net/oeic/2007/06/07/serialization-issues-in-zend_acl/

  10. Stupid article!
    Code looks like terrible, I think that author doesn’t know Zend Framework at all.
    Before posting articles take a look about coding standarts and thinking about usage of ZF. http://framework.zend.com/manual/en/coding-standard.html

  11. I am sorry you feel that way Paul. But the code is just an example which is why I do not include the whole class. By including just one method I was trying to demonstrate its use for others to then go off and implement their own take on the concept.

  12. [...] that usually get reinvented too often. Zend Framework includes packages for Access Control Lists (Example tutorial), Authentication, Session handling, PDO Database wrappers - basic stuff that developers almost [...]

  13. can you post the source code for a simple example application about this post ?

  14. great idea and I think put it in an ini file is surely and practical way to save ACL rules. on the manual they say they leave the storage things to the users. I just don’t know how. thanks for the code!

    I have yet one problem about “resource” , what on earth are these resource? isn’t it has the same meaning as “controller” or something?do you mean in your code like “news”,”latest”,”announcement” are they just the name of your controller? can resource be defined as something else? thanks!

  15. I can’t believe Paul gave you such a grilling. How rude!

    Thanks for the taking the time to put the article online. Its always interesting to see how other people approach a problem.

  16. [...] show notes also contain a link to a tutorial entry over on his blog detailing (including code) how to use the ACL functionality. [...]

  17. [...] Zone today, many thanks to Cal Evans for bugging me until I did it. The podcast covers the Zend Framework ACL (Access Control List) which I have made heavy use of in our current projects and I wanted to share [...]

  18. Nice article!
    Altough the text file is faster, I would prefer storing in the database so that administrators will be able to add different user groups and so on and so fourth. write an article about it :D until now, i am having a hard time with Zend_Acl :(
    Thanks!

  19. This is a great article, one of the great things about the Zend Framework is leaving quite a lot of the thinking to the developer and giving you more options, so it’s quite open whilst doing a lot of the hard work for you, you still have to think a lot, unlike CakePHP which does a lot of the thinking for you.

    File or DB, you can still port Nick’s approach to this for either storage approach, it’s not hard.

    Thanks.

  20. [...] http://blog.assembleron.com/2007/05/30/zend-framework-rc1-and-zend-acl-usage/ [...]

  21. [...] have previous written at length about the ACL and done a podcast on the subject. It is a little hard to get your head around to start off with [...]

  22. Thanks for this article,

    I have plenty of small project where using a database to store the acl is over kill. A nice way to do it too, is to have one ini file per modules…

    Thumb down to Paul! Booo !!!!

  23. Nude Hypno…

    Nude Hypno…

  24. [...] and usage example - By Jeremy Knope Zend_Acl and storing roles and resources in a DB - By Jani Zend ACL usage - By Nick Halstead Why you need a Zend Framework ACL and Cache GUI - By Nick Halstead Zend_Acl / [...]

  25. [...] and usage example - By Jeremy Knope Zend_Acl and storing roles and resources in a DB - By Jani Zend ACL usage - By Nick Halstead Why you need a Zend Framework ACL and Cache GUI - By Nick Halstead Zend_Acl / [...]

  26. [...] and usage example - By Jeremy Knope Zend_Acl and storing roles and resources in a DB - By Jani Zend ACL usage - By Nick Halstead Why you need a Zend Framework ACL and Cache GUI - By Nick Halstead Zend_Acl / [...]

  27. test

  28. [...] and usage example - By Jeremy Knope Zend_Acl and storing roles and resources in a DB - By Jani Zend ACL usage - By Nick Halstead Why you need a Zend Framework ACL and Cache GUI - By Nick Halstead Zend_Acl / [...]

  29. Great article. That other guy is probably right that it loads the whole file. Caring is probably pedantic and anal retentive :P (although it is something I would optimize early on, I’m a sucker for premature optimization).

    I think I’d load the entire config into one object and shove it in Zend_Registry. Maybe it would eat more memory, I know nothing about it really ;)

    I am daunted by Zend_Acl. I’m used to my resources being represented by strings in a database, with permissions stored as integers for each membergroup for each resource, in such a way that I can lay it out as a table. Nothing more, nothing less.

    And each permission being denied (in an empty, default state) until I allow it, and then allowed until I deny it again either by removing the allow-ance or overriding it with a deny from somewhere.

    Still, if I’m going to use Zend_Acl then Nick, the code you’ve posted is a great place for me to start! Thanks!

    I won’t be shutting the door on the idea of doing this part myself though or bringing in some external tool…

  30. [...] Zend ACL usage - Por Nick HalsteadWhy you need a Zend Framework ACL and Cache GUI - Por Nick HalsteadZend_Acl / Zend_Auth example scenario - Por Cal EvansZend_Auth [...]

  31. [...] and usage example - By Jeremy Knope Zend_Acl and storing roles and resources in a DB - By Jani Zend ACL usage - By Nick Halstead Why you need a Zend Framework ACL and Cache GUI - By Nick Halstead Zend_Acl / [...]

Post a Response