The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Zend Framework and OOP Best practices

I am by no means an expert on MVC or object oriented programming, but as I have been going through the Zend Framework tutorial, something strikes me as being odd and I was hoping one of the experts here could clear it up for me.

In the framework the following URLs would all open up the same controller:

Most likely you would want an URL scheme of the form google.com/news, but even going by the above scheme wouldn't mean you should code like you presented it. Actions related to each other are grouped in controllers thusly:

I'm afraid you're quite lost indeed. Before you get any more confused, you should get acquainted with the kind of MVC and routing you're dealing with: Symfony has a nice writeup and I'm quite sure you'll be able to find something readworthy over at Rails, the inspiration to all of these implementations.

Ezku, we are saying the same thing, and I appologize if my first post didn't make that clear. Based on your post, I would imagine that you would have the same issue with the php architect tutorial as I did?

Ezku, we are saying the same thing, and I appologize if my first post didn't make that clear. Based on your post, I would imagine that you would have the same issue with the php architect tutorial as I did?

Oh, right. Seems like I have to apologize as well. :) Yes, I find the grouping extremely odd. Not the URLs, necessarily - oftentimes it makes a lot more sense to group them "backwards" - but the way how the controllers are organized irks me. There may be advantages to such a setup but the writer sure doesn't seem to elaborate on them. From a code organizing point of view, grouping by sections instead of functionality would make a lot more sense.

Looking at the credits, Chris Shiflett is a familiar character here at Sitepoint. And, looking at the previous post I missed for not reading to the end of the thread before posting, we seem to have his take on the issue already. Yay. I subscribed to your RSS feed, Chris. :)

Obviously, not everyone should be able to invoke the create, update, delete methods. So how is the best way to limit the access to these methods (so that only admins may invoke them for example)? Should I create my own dispatcher + router (+ plugins)...or will the upcoming release of ZF be able to handle this internally?

Or should I create an AdminController and have all the "secure" methods there, and do the access control when I create the AdminController?

Oh ... while we're at the controllers in ZF, I have a (I hope) naive question. The module/command/arguments mapping is fine for simple table-oriented applications, but how would I go around adding a submodule ? Say I have a catalog of commodities, and each commodity has one or more images. The images are aggregates of the commodity - Eg. There's a foreignkey to the commodities pkey. So the most natural URL would be something like /commodities/160/images/ to list all images for commodity #160
This seems like a fairly common need - how is it this solved ? How is it solved in RoR, which seems to be the rolemodel ?

Oh ... while we're at the controllers in ZF, I have a (I hope) naive question. The module/command/arguments mapping is fine for simple table-oriented applications, but how would I go around adding a submodule ? Say I have a catalog of commodities, and each commodity has one or more images. The images are aggregates of the commodity - Eg. There's a foreignkey to the commodities pkey. So the most natural URL would be something like /commodities/160/images/ to list all images for commodity #160
This seems like a fairly common need - how is it this solved ? How is it solved in RoR, which seems to be the rolemodel ?

Uses patterns (: for dynamics, * for wildcards) much like RoR, and with the requirements it compiles to a regexps form for matching with incoming requests.

PS. Ignore how it creates the controller, once its pulled apart a url, I wasn't to happy with the method used there, and currently gone with a DI style container for registering controllers with, and passing that to the Routes object.

Say I have a catalog of commodities, and each commodity has one or more images. The images are aggregates of the commodity - Eg. There's a foreignkey to the commodities pkey. So the most natural URL would be something like /commodities/160/images/ to list all images for commodity #160
This seems like a fairly common need - how is it this solved ? How is it solved in RoR, which seems to be the rolemodel ?

I would imagine, since there is only a single level of pagecontrollers, that this would be dealt with by creating a route such as { '/commodities/:commodity/images/:action', :controller => 'images' } or however you saw fit.

Originally Posted by Ren

PS. Ignore how it creates the controller, once its pulled apart a url, I wasn't to happy with the method used there, and currently gone with a DI style container for registering controllers with, and passing that to the Routes object.

Why does the Routes object have anything to with controllers? Is it like a combined route interpreter + dispatcher? Tell us more about your solution. :)

Uses patterns for dynamics, * for wildcards) much like RoR, and with the requirements it compiles to a regexps form for matching with incoming requests.

That's quite nice. I only skimmed the code, but I'll have a deeper look when I get some time off.
One thing bothers me with this patterns-based approach to routing. They are fairly static - they don't relate to the applications state. I recently tumbled with the same issue, and my solution was to skip the mapper, and instead let a set of nested controllers (intercepting filter if you want) take care of each part of the url as they see fit. Something like :

That's quite nice. I only skimmed the code, but I'll have a deeper look when I get some time off.
One thing bothers me with this patterns-based approach to routing. They are fairly static - they don't relate to the applications state. I recently tumbled with the same issue, and my solution was to skip the mapper, and instead let a set of nested controllers (intercepting filter if you want) take care of each part of the url as they see fit.

How do you go about generating urls?
Eg. You want a url that'll get to the ImageControlller, with this image id.

How do you go about generating urls?
Eg. You want a url that'll get to the ImageControlller, with this image id.

URL-routing and URL-building are obviously tightly integrated. I would build URL's in the same manner as I map the request - iteratively. Each context will have a method url($href) which would return a URL to a resource, relative to that context.
This is an expansion of the previous mock which shows how it works :

The URL-method is quite primitive in this example. I have expanded it further to contain state too. For example a list-controller would have state for sort/order and possibly paging. Theese would be relevant to the controller and any child-controllers, but not for parents, so it could append the state to the url.

Obviously, not everyone should be able to invoke the create, update, delete methods. So how is the best way to limit the access to these methods (so that only admins may invoke them for example)? Should I create my own dispatcher + router (+ plugins)...or will the upcoming release of ZF be able to handle this internally?

Or should I create an AdminController and have all the "secure" methods there, and do the access control when I create the AdminController?

In my personal framework I have "filters" that kick in in each stage.

One before the frontcontroller dispatches to the pagecontroller to check if the user has access to that page, else redirect to somewhere he does. Next part is just before th action is dispatched, another filter checks if the user has permission to that action. If he doesn't, he's redirected to an allowed action/page.

For this case, I wouldn't put the permissions on the controller-level, but push it to the model.
I have generic CRUD-controllers, which are allowed by anyone to execute, but inside the action, the model-component is queried for permissions. Eg. :

I had thought of that as well, but decided against it, and it's down to granuality as you say; For example the decoration of a given action would be solely to validate that the user in question can do something, such as edit a document;

I would have another filter or rule, to validate that the user can actually edit that given content it's self, as such that the user in question is either,

a) The original author, or
b) The user has higher or greater priveleges/permissions of the original author, to do the edit,

For example, the original author of the content could have the privelege level of Author, whereas the user requesting the edit has a higher privelege level, such as Publisher, shown below for example,

Code:

01 Administrator 01 00
02 Publisher 02 01
03 Author 03 02
...

So, if a users given Level (third parameter) is lower than the opposing users Level, they have overall control of the action requested - that way a Publisher can authorise if and when a document is ready for publication, since the author cannot automatically publish as such, for obvious reasons

By generic, in reference to above examples, which route do you take? Would, or do you see any benifit of either sharing the responsibilities between a common abstraction (ie Action) or putting the responsibilities to separate abstractions (ie *Action)?