All my previous projects have had this workflow on Contact pages
User submits form
Controller gets $_POST details
Controller validates details (and sets error messages if necessary)
Controller sends email
Controller redirects to thanks page
Is this the standard workflow?
I used to validate everything in controllers, and then did some more reading and they recommended against it. Therefore, should I send the $_POST details to a helper type object and let it do all the work (validation/sending)?
In controller we should only check validation. The main validation should be on model before operations with DB.
The controller file need to check & validate the user input data.
After getting & accumulating all the data, it needs to transfer the data to the Model file for checking with the database (if needed) & then need to do some other works from here (like setting sessions / cookies, or sending mails, or firing hooks, ...). However, the control must come back to the same controller method, as all the previous model functionalities must be fired by a method call, from the same controller method.
The proper view method must be called now, and then the output must be rendered to the console.
Hope it helps.
Validation is typically performed in the Model, not in the Controller.
This is because data structures are usually defined in the Model and it is best to compare the acquired data immediately before manipulation (i.e. inserting into a database, etc.).
Related
help me! I am a php rookie and i am confused with the php request.
Working on MVC structure for view, I created a HTML form, and on form submit i want to do call two different methods sendMail() and validateData() available in two different controllers (php file) - say one in process.php and another in register.php .
On form submit first I want to validate the data and save data to database using validatedata(). Then I want to send a verification mail to the user using sendMail().
To handle the request (click event) I am using jquery ajax. Ajax takes a single URL for posting data to the specified URL. So how can I make two different URL requests in a single Ajax call, or say how can I call both the methods in a single Ajax call?
Please suggest me what i should do to solve this issue?
thanks in advance.
A controller should handle an entire request.
So if the user makes (for example) a request asking to create a new user account then a single controller should:
Validate the data the user has sent to make sure it is what is required before creating an account
Create the account in the database
Send the email
Return a response saying if it worked or if there was an error
So you'll end up with something like
{
$errors = validateData($_POST);
if ($errors) {
echo generateErrorPage($errors);
exit;
}
$result = createUserInDBAndSendEmail($_POST);
showSuccessPage($result);
}
(That's very rough and ready for the sake of example).
Don't divide the steps you need to do to complete the task up between different controllers. Then you only have one URL to worry about.
You can divide the functions up between different files and then include them.
The complete process for creating a user might require additional feedback from the client, e.g.
Client makes a request to the CreateUser controller
Server creates a user in "unconfirmed" state, sends email to the user and returns an HTML page telling them to check their email
User clicks a link in the email to make a request to the ConfirmEmail conroller
Server changes the user to "confirmed" and returns a logged in homepage with a welcome message
… and in that case it would have multiple controllers since you need the user to make two different requests.
I have a controller which handles the adding of records to a database. Sometimes these records require a couple of passwords to be entered, to "sign the record". Therefore, when the form is submitted, it is passed to a function in the controller called "getSignatures." This will load a view with inputs for the passwords needed. The users will then enter their passwords to "sign the document". This will then be passed to a function in the controller called "checkSignatures," which will call a function in the model to check the passwords.
However, I still need to pass through or save all the data from when the form is submitted.
I have tried using a global variable to save the form data, but when the checkSignatures function is called, it's called through a new controller. I also tried passing through the form data to the view, saving it in a hidden input and then passing it back through post but you can't save an array in a hidden input.
Any ideas would be great, and sorry for the long-winded question.
Try using sessions as described here. In particular you should look at CodeIgniter's flashdata.
Sessions will be stored on the server for the entirety of the user's browsing session. This will let you access the data again. Flashdata is deleted after the next page load so they don't stick around for long.
I think this is one of the more complex tricks to get right and therefore I have decided to elicit the help of the very knowledgeable people on StackOverflow. My scenario is as follows: I have two entities, a user and an account. A user is always linked to an account upon registration (and depending on the type of user, might be linked to more than one account. Upon registration the function saveUser() is called (via ajax from frontend) and the submitted form data is retrieved from the Request Object. This data is then passed to the function saveAccount($data) (which is called in the saveUser() function) in the form of a parameter and the account is created (sometimes called more than once with different data sets to create various accounts), which is linked to the user.
Now I want to create an account from my admin panel without creating a user, so I want to call saveAccount($data) directly via ajax (from frontend) and pass the form data to it as a PARAMETER (instead of retrieving it in the function via the Request Object), so that I can use the same saveAccount($data) function and that I do not have to create a saveAccount() which works the the Request variable. Does this make sense? Is this possible? If so, how would I go about doing this?
I did not post any code, as I did not see the need for it, this is more a conceptional problem, but if you require the code that I have thus far or if anything is unclear I will be happy to elaborate.
There should not be any saveAccount method, you just rely on relationships between entities, i.e. on a setAccount method, or to a addAccount one in case you need to add an entity to a Collection.
Then Doctrine will take care of saving and persisting everything.
For saving data, I would always rely on a RESTful interface [which you can create easily via FOSRestBundle], and send everything via ajax no matter what; you'll end up with a smoother interface and more maintainable code.
For instances where a controller function can be called either via AJAX with form data or internally by a another controller function the following solution works:
public function saveAccount($data = null)
{
if (empty($data)) $data = $this->getRequest()->request->all();
...
}
Then you can pass an array to the controller function in the same format as your form data array and it will use that data if passed to the function, otherwise it will retrieve the REQUEST (form) data.
It's the first time I'm using an PHP framework and I have a question regarding this design pattern.
Let's say I'm trying to build an php app that has a contact us page (which will ask for the name, email address comment etc and once submitted it will simply use the mail function to send an email to the admin). I know what my view is gonna be, I will also use a controller to render the view, but what should be my model? I'm not going to load anything from the database or save anything to the database. So in this case should I skip the model?
I’d say that, even with a contact form, a model has its use.
A contact form handles enquiries, a contact form has fields, and a contact form usually requires some form of validation. This can be wrapped up in an Enquiry model.
In fact, this is exactly what I do with CakePHP applications. I have an Enquiry model that defines the fields and data validation, and saves any enquiries to the database (for archiving purposes) and has an afterSave callback method that sends me the enquiry details via email. I’m sure you could do something analogous in CodeIgniter.
the gritty details go in the model. even a simple contact form has lots of gritty specific details: names of fields, specific validation rules, etc.
the controller is the boss - validate this form! it does not say how to validate it, and it doesn't need the details of each field in the form. if the form validates - the controller calls the next view. if it does not validate - then the controller shows the form again and maybe passes specific error messages.
the validation details for the contact form - put that in a model.
the emailing of the form: the content of the email, taking the form values and putting it into the email, who the email goes to, the details of actually sending the email - that is all work for a model.
what does this gain us? when your client calls in a year and says - change the text in the email - you won't be hunting through a bunch of controller code. you will look at your model names and know exactly where to go. separation of concerns is not just for building - its for the inevitable changes that happen over time.
EDIT
yes the business logic should be in the model. so like for a contact form the business rules might be - we ask for name and address - and we require the email address and phone number. the validation rules then fulfill the business rules.
then six months later your client calls and says - well people don't like us requiring the phone number - just make the email required. you have put those validation rules in your model - therefore it is only that specific model which needs to change. the controller does not change at all! and since you separated the form validation rules from the sending of the email into separate models - if you make a mistake when changing the validation rule - its much less code to look through and debug.
the other way to look at is - how specific and 'granular' is the method? the more specific it is, the further from the controller it should be. the controller methods should rarely change because of changes to business rules.
so when i said the controller orders "validate this form" - i just meant that the controller is calling the validation method that is in the model, and then its getting back true or false, no matter what changes happen to the form over time.
Models are optional in Codeigniter. If you don't need one then don't use one.
Models are optionally available for those who want to use a more traditional MVC approach.
Documentation
In your particular case you have no need of a model so don't worry about making one.
OP here, just want to do a quick update on this.
I have looked at CodeIgniter's documentation, and surprisingly found out that the form validation code is inside the controller:
http://ellislab.com/codeigniter/user-guide/libraries/form_validation.html#validationrules
which IMO is not a good idea.
Fortunately, there is a way to clean up the controller, which requires you to create a form validation config file inside the config folder:
http://ellislab.com/codeigniter/user-guide/libraries/form_validation.html#savingtoconfig
since I don't want to reinvent the wheel, I guess I will just create the config file without creating the model
I validate all my forms data in the model layer but I also check where my form was submitted from (HTTP Referrer) and I also send a token with the form to help prevent Cross Site Request Forgeries and my question is where should these checks be done? In the controller or in the model layer?
I was thinking up a few different ways to accomplish this and one was to have some sort of protected method in my AbstractController for validating the forms source and posted token but then that might break the SRP.
(..) where should these checks be done? In the controller or in the model layer?
Neither.
In my humble opinion, CSRF protection should be handled at the same level as other forms of access control: outside the MVC triad.
If application fails to verify the token, it means that data in Request instance (or your alternative of it) cannot be trusted, thus it need to be scrapped. I would perform such check before initialization of Controller and/of View instance.
Basicly it is wise check your data multiple times with different intentions. I suggest these levels:
1) A pre-front-controller checks the data recieved for integrity. If you miss some token, or got some timeout from the browser etc, you exit immediately. You will not let these requests reach your MVC. Here is where you might want suoshin. The reason is, that the deeper levels might communicate secured data with the browser, even on an error. Imagine someone missed a security token (attack?), and your view returns an error message and sets some cookies. Using these, the attacker might be logged in after any invalid form request.
2) The front controller verifies if the entered may be entered in that form from that user etc. (e.g. if a US-User might enter a Canada Phonenumber) It is ment to give direct feedback in form of "please enter a correct phone number" and so on.
3) The model validates if the data is in a state to be safely saved and returned, e.g. if it has been escaped, has the right length etc.