I've just started reading up on CakePHP and everything is going pretty good so far, though I have a query on the best way to do the following:
I have a "User" model and a "UsersController" controller.
I currently have a "home" page which is controlled by the home_controller.php (obviously). The home page contains a registration for for a user.
The Question
When the form is posted from the home page, I need to access the User model (from the home controller).
What is the best practice for this task?
If I understand the situation correctly, I would post the form to some function in users controller. Then this function would save the data, or log in, or whatever. Finally make redirect back to home for example.
you can easily share one model across many controllers
var $uses = array('ModelName');
I do that with User Model and
Account Controller (Login, Register, ...)
Members Controller (Search, Listing, Profile, ...)
Overview Controller (Start Page, Home, ...)
for example. they all share the User Model.
I currently have a "home" page which is controlled by the home_controller.php (obviously) What other methods do you have in home_controller, other than index? And in Cake convention, the controller is plural, so: users, categories... Most likely, you are not aware of pages_controller and routing in Cake.
Anyway, yes, you can make a post to any controller (or even to another domain) from any page, just like any regular HTML page. echo $this->Form->create('User', array('controller'=>'users','action' => 'register')); You can read more here: http://book.cakephp.org/view/1384/Creating-Forms
Related
As I understand it the "MVC" came before the web and is often used in Desktop software for example.
If I understand correctly, the Controller runs at the time that the user will click a button and this will trigger an action.
But if we talk about web pages, the scenario is a little different, assuming the user clicks a link then it triggers an action.
But then, came me the doubt, is the home page part of a Controller?
What I mean is, the homepage is not usually performed by a user action within the website is just the home, but noticed that many PHP frameworks use a Controller for the home, is that correct?
Another doubt is in my "home" I have several items, for example:
banners
featured posts
recent posts
Each of these items would have a different Model, can I call more than one Model and a View into the Controller?
Would these be the correct steps? Or most of php frameworks are not strict?
You are completely right and I understand the confusion.
In a pure MVC approach, the Controller only listens to user actions and updates the Model accordingly. The Model then notifies the View (through the Observer design pattern) and the View updates itself, accessing the data it needs from the Model.
This is how it was done before the web, in desktop application, where the Model and the View are running concurrently, and where the Model can notify the View. The Controller doesn't set up the View.
In this pure MVC model, the example you mentioned about the homepage doesn't need a Controller indeed. The View would just render itself, accessing the data it needs through the Model. Controllers are very thin and only listen to user actions and update the Model. That's all they do.
In the web, this model is not possible, and thus there are alternative approaches. The Model can't notify the View as in the pure model, and thus what popular frameworks require you to do, is to set up the View in your Controller. That's why for your example of the homepage you need a Controller, as you will set up your view there with all the data it requires.
However, there is another approach I have been personally writing about, where Controllers don't set up the View which allow you to keep tiny Controllers. You can read about it here: A better OOP approach to building MVC applications
Thus I believe that the homepage shouldn't need a controller action at all. The View should just render itself and access the data it needs to render. The Controller's role is to handle user actions and update the model accordingly, as you said. If it does more than that, it probably violates SRP. The Controller shouldn't set up the View, instead, the View should get its own data from the Model.
Dear Friends: It seems like more of a Conceptual problem than a programming problem. Am new to MVC and have problems in understanding what can call what. THE FLOW OF PROGRAM CONTROL.
The Problem: Controller A --Calls-->Model A--calls-->View A. Now once the View A is loaded it also contains a form for inserting comment with a sumbitt button.
Once the comments are inserted (and submitted) it calls Controller B--calls-->Mocel B. which insert data into comments table -- further it has NO View to call.
QUESTION 1: how to call the Controller A from Model B (since model B does not have a view). it is possible to load ViewA from ModelB but that will require to re-write the code that exists in Controller a already. FURTHER more i want the comment form to be inserted into many pages so will i have to reload all those pages (Views) manually.
Question2: it is possible to make comments form (Controller B and Model B) part of Controller A and Model A BUT then comment form will cease to be a re-usable module and will need to be inserted into every page that i like it to be used in.
Question3: Is there some conceptual error i an making. it is the way MCV works?
Summary:: There is a form managed by Controller B and Modal B (it has no view and it displayed as part of a page managed by Controller A, Model A and View A) Model Bafter doing its job it needs to call Controller A (so that it can refresh the page) HOW?
THANKS TO YOU BRAVE SOULS IN ADVANCE
I think your strategy is a little off starting with
Controller A --Calls-->Model A--calls-->View A
Your models really shouldn't be calling your view. The controller is usually in charge of this. Requests are made to the controller and the controller gets all the data from the model then formats/templates it using a view and outputs it to a user. Controllers should be at the center of every request.
QUESTION 1 how to call the Controller A from Model B?
Model B really shouldn't be calling a controller. MVC really isn't desinger for this. If you need data from model B get it from the controller. If you need functionality that exists in controller A refactor it into a utilty function that can be used anywhere in your app.
Question2: it is possible to make comments form (Controller B and
Model B) part of Controller A?
Yes once again this comes from a good app design. I'd imagine that one of your models is able to retrieve comments. Perhaps per user perhaps per time frame. From controller A you can call that model function. By loading the model $this->load->model('Post')
and retireving your posts $this->Post->most_recent_posts().
Question3: Is there some conceptual error i an making. it is the way
MCV works?
Yes the functions of your site are too tightly bound to their controllers and models. They hve to be more loose/general so functionality can be used in any controller.
I'd like to answer you last/main point but it would really really help to see some code.
I'm fairly new to the MVC architecture but I'm picking it up nicely, having my own framework almost done.
Nonetheless, I'm having a 'design issue', how to call the controller?
The controller, as in the function that checks if the user hit the submit button.
Example of controller:
$class->login($_POST['username'], $_POST['password']).
I know a lot of MVC frameworks and apps call it by the URL with $_GET params, but I think it's stupid to have one method or one class for each page that needs a function like logging in.
How do you guys do it? What's your method for this?
Any help is appreciated!
You might want to look up the Front Controller concept (and inversion of control), which you are probably already using in some form, but may not know it. The Front Controller analyzes the URL and current state of things, and determines what controller to load.
In my framework I have "routes" that have attributes, one being "require login". The Front Controller determines what "route"/controller needs to be run and checks for pre-requisites for that route, like login requirement. If the user isn't logged in, then the login "route"/controller is loaded instead of the requested "route"/controller. If login is successful, then control is passed to the appropriate "route" controller.
It shouldn't be the job of each controller to manage logins, only one controller should do that, usually the front controller. Any controller should be able to be loaded under any URL since it's the front controller that determines what controller to load. The sub-controllers don't know "why" they are loading, only that they are loading to do their 1 job.
You could have a base controller which contains a function, requireAccess($access_level). Other controllers would extend this controller. requireAccess() would redirect to the login page if the correct access level is not present.
As for redirection using GET variables for clean urls in MVC, I would not recommend this. It could cause problems down the line with wanting variables that contain slashes in them. Instead we would typically want to get the original request uri, and parse it ourselves.
Typically MVC urls follow the pattern /Controller/Action/Id/etc
I'm new to the MVC pattern but have been trying to grasp it, for example by reading the documentation for the CakePHP framework that I want to try out. However, now I have stumbled upon a scenario that I'm not really sure how to handle.
The web site I'm working on consists of nine fixed pages, that is, there will never exist any other page than those. Each page contains something specific, like the Guest book page holds guest book notes. However, in addition, every page holds a small news box and a short fact box that an admin should be able to edit. From my point of view, those should be considered as models, e.g. NewsPost and ShortFact with belonging controls NewsPostController and ShortFactController. Notice that they are completely unrelated to each other.
Now, my question is, how do I create a single view (web page) containing the guest book notes as well as the news post box and the short fact? Do I:
Set up a unique controller GuestBookController (with an index() action) for the guest book, so that visiting www.domain.com/guest_book lets the index action fetch the latest news post and a random short fact?
Put static pages in /pages/ and in let the PagesController do the fetching?
< Please fill in the proper way here. >
Thanks in advance!
It sounds like you need to look into elements, or else you may be able to embed this into the layout - but its neater to use an element if you ask me, keep the things separate.
http://book.cakephp.org/2.0/en/views.html#elements
These allow you to have create small views that you are able to embed into other views.
You may also need to put some logic into the AppController (remember all other controllers extend the app controller) to load the data required for these views. The beforeRender function should be useful for this - its one of the hook functions cakephp provides, so if you define it on a controller, its always called after the action is finished before the view is rendered.
Something like this in your AppController should help:
function beforeRender() {
$this->dostuff();
}
function doStuff() {
// do what you need to do here - eg: load some data.
$shortfacts = $this->ShortFact->findAll();
$news = $this->NewsPost->findAll();
// news and shortfacts will be available within the $shortfacts and $news variables in the view.
$this->set('shortfacts', $shortfacts);
$this->set('news', $news);
}
If there are models you need in the app controller for use within this doStuff method, then you need to define them within uses at the top of the AppController
class AppController {
var $uses = array('NewsPost', 'ShortFact');
}
What is the best way to embed Login Form into several pages in Zend Framework?
Currently I have two controllers, LoginController for separate login form
and IndexController for actions on index page.
I need to include Login Form into index page to let users log in both from the front page and from Login page.
My current solution is to make IndexController extend LoginController, but I have to make some adjustments to the code of both controllers (e.g. call parent::IndexAction from inside child indexAction to render login form and various redirects should be updated too).
Is it OK implement "multi-page" login with such a controller inharitance?
What is the best practice?
Action helpers may help you http://devzone.zend.com/article/3350-Action-Helpers-in-Zend-Framework
Might be easier to just create your own form on your index page (careful to name the inputs as you had on your login page) and just set the action to your login script.
i also recommend you moving most of your code into the user model instead of the controller.
I think "thin controllers, Fat models" pattern is more expendable and maintainable then extending controllers.
I also use the extending a generic login controller for my aplications, but the generic controller just has a functions that gets the inputs and sends them to the model and redirects or sends an error to the view.