I’m planning to build a website using the Zend Framework 1.11 right now. What I have right now is an overview of the controllers I’ll have to implement and a basic set of methods (controller actions), which will be needed.
So now my problem is that i have for example an UserController and a BranchController. A User might register himself up to five Branches, so this is a 1:n relationship. Should I put the addBranch-Action in the UserController or the BranchController? I’m asking, because I have several actions, which also refer to the User, but if I put all those in the UserController I’ll get a huge set of methods (actions) there.
Other example: I have a ChatController, and a User might send a chat request to another user. Do I put the sendRequest action in the ChatController or does this belong into the UserController?
Any advice on how to manage this?
A controller does not (have to…) have a 1:1 relationsip with a model, however it should have a 1:1 relationship with its view. Technically, in MVC proper the view has a controller (rather than the controller having a view).
Controller actions are essentially events on the view. Someone clicks something on the view, it calls the relevant controller action. What it does with the model after this is irrelevant. Because of this, each controller handles events for a single view.
You shouldn’t have UserController. Instead you should have RegistrationController, SendMessageController, ViewMessageController. Etc.
Ah, ok. I feel I’m getting the point. But now, how would you plan your controllers? Because now I’ve a list like which actions belong to a user (like register, edit profile, change password etc.), a branch (list users for branch, add branch, view branch tree, etc.) and so on. Whats the usual way to determine the controllers, you’ll need, based on a list like mine?
I’m interested, because this is the first time, that I’m planning before coding. Usually I wrote the code and then it got really messy everytime, so I thought it would be a good idea to think about codedesign before
Don’t plan the controllers, plan the views.
Get a list of views your system will need (which you seem to have: registration form, view message, list messages, send message, list users, etc). Each view will have a controller. The controller is the simplest part of MVC and in a simple “List Users” controller it will do little to nothing (until you start adding events to the view, such as data filters and ordering).
You will, of course, need to plan how the views link back to the (domain) models but this should be easier to work out than using a controller as a starting point.
Ah ok. I’ll try this and if I get stuck, I’ll ask again
Well, I’m stuck again. Lets get back to my example of sending another user a chat request. I won’t have a view for this. To send a request, there will only be a link on a users profile (which will be a UserProfileView). If I click it, the request will be send, but there will be no specific view for this. What do I do in this case?
Sorry for these questions, but I feel like out there are many people who have doubts about this, me in first place
Then it’s a profile operation. The event is triggered (in this case) on the profile view.
The related profile controller action would call startChatRequest() (or similar) on the model… and do nothing else.
Why does it go in the model? Because other views/controllers may need to also initiate chat requests. E.g. you might have the same thing in a “Who’s online?” section.
Ok, getting near But if I have multiple places of the “Start chat” button in several views? For example, it will be visible, as I said, on the profile, but then again there will be a list of users, which belong to a certain branch, a list of online users etc. And you may start a chat on every of these (view) pages. Maybe in the ChatController, belonging to the (running)chatView?
Well, like most things, there’s no right (or wrong) answer here:
One, potentially overkill, method is to make the “Start Chat” operation its own MVC triad. That way it is 100% reusable and you have zero repeated code.
edit: I don’t know how well (if at all) Zend handles Hierarchical MVC so this may not be as easy as I stated
Another option is to make each controller call the “Start chat” function on the model (as I suggested above). This has the advantage of a simpler program at the expense of a little repeated code: the $model->startChat(); call would appear in multiple controllers, and is why it’s in the model, not the controller as this way only 1 line is repeated.