Access control is part of business logic. If you look at use cases, or even user stories, you will see that there are actors involved in any business process. The access control lists are a method to ensure that all and only the actors CAN be involved with the business process.
Access control needs to be supported in the model, the view and the controller.
Access control is part of the model: By limiting the ability to change or view columns or records per the business logic, you necessarily prevent many failures. If only system administrators can change a secondary key field, then it won't be accidentally changed because someone implemented a form incorrectly. Now, I also suggest that you don't specify the restriction as based on "system_administrator" privilege but rather "change_secondary_key" privilege, which system_adminstrators have by design. This separates role from function.
Access control is part of the view. By not enabling form fields to edit data for which the person doesn't have the privileges, you prevent both confusion and errors.
Access control is part of the controller. The controller adjusts the page flow to present only the information appropriate to the user at a time and place that is appropriate.
Certainly, you want to have central management of access controls, on the principle of DNRY (Don't Needlessly Repeat Yourself). Access control is a cross-cutting concern.
I will try to answer some of these questions. Having a single View Class helps makes the code easier to maintain if they share a lot of components. For most of the pages, it's common to always have the same header and footer. This is only different in pages that require authentication. For example, a login page will have its own header and footer.
In this design, the View class will have the render method to allow you to set the footer and header. Your mandatory parameters will be the main file and the data.
static function render(
$main_file,
$data,
$header='default_header.html',
$footer='default_footer.html');
So with that, you only need one line on every controller that needs a view.
// inside LoginController
function Show($id){
//...your regular code here
// renders view
ViewClass::render('login.html', $data, 'login_header.html', 'login_footer.html');
}
// inside PostController
function Show($id){
//...your code here
// no need to specify header and footer
ViewClass::render('post.html', $data);
}
To take care of dynamic contents inside the header and footer, I use hooking strategy. This means my PostController and other authentication zone extends another BaseController class that loads header and footer data.
It may seem like a lot of boilerplate code, but the other advantage is that you can change the view to render JSON without affecting your controller logic.
// inside PostController
function Show($id){
//...your code here
// now loading json templates
ViewClass::render('post.json', $data, 'header.json', 'footer.json');
}
One more point is that true MVC design is meant to make it easier for your designer to work on the views. If you create classes for every view, it has implications on the designer's involvement. Designers should not be writing your classes.
Best Answer
For your example I would create two controllers:
In general a RESTful approach where you think about everything as a resource that can be displayed, created, edited and destroyed gives you a good idea how to structure things. As you can see from my examples I don't stick too close to every single verb in REST.
You would most likely need more controllers for further functionality. For example a Users Controller where users can create new accounts. And in addition to this you would need an admin interface where you can edit the resources with higher privileges. In such a case it is quite common to have nearly every controller duplicated.
A very very rough estimate to get an initial idea could be one controller for every table in your database that users can access. But this is really only a very crude measurement.