I'm still learning Laravel, as what I'm trying to accomplish at the moment is the following logic:
-An User submits a form-> The form input is saved into DB, and is 'sent' to another User who can then validate it->I save into the DB if the state is validated or not, and inform the User who sent the form.
I know this is not too hard, but I'm doing it as I learn Laravel, so I'm coming up with a few 'problems'.
First of all, I do have quite a lot of forms, and I did get the Post logic working. At the moment I'm not working with the Database yet, so I tested the Forms with SESSION, to make sure the data was being saved.
So my first question is: is it best practice in this case to keep all form logic into one Controller? Like the following(this is working with two different forms) (session is there only for testing purposes)
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function geralSuggest(Request $request)
{
$name = $request->input('obs');
return redirect('sugestoes');
}
public function GD(Request $request)
{
session_start();
$name = $request->input('nome');
$cc = $request->input('cartao');
$array = array ($name, $cc);
$_SESSION["testPostSection"] = $array;
return redirect('declaracaogd');
}
}
Secondly, I have some forms where the user can add inputs. Lets say one input is for the name, and the user has a button that when he clicks he adds another name input, so he can input many names at once. This is done by Javascript on my side. What I'm wondering is how will I save this inputs, since I 'don't know' how many "names" the user will be submitting. I was thinking a for or foreach loop, where I would check with "isset", but I'm not sure if it will work. I will be testing this when I get to it regardless, and I'm sure I'll figure it out, but if you know a good logic for this and could point me in the right path, it would be appreciated.
Lastly, about my general logic, for User validation, from what I read on Laravel documentation, I think Events will be what makes the trigger to 'warn' the second User that he needs to validate a form, is that correct?
I'm sorry if I'm asking "too much at once" or if these are very basic questions. I just wanted to make sure that I'm going in the right direction.
Thanks a ton in advance!
Im not sure if I understand your system 100% correctly. But it seems you are trying to make a human validation program? So 1 users submits data and another users validates this data. In this case I would do this in 2 seperate controllers. Laravels explenation on controllers states: "Controllers can group related request handling logic into a single class." Providing data or validating data are 2 different things. But this isnt a strict rule.
For the second question. Laravel has an all() method. $input = $request->all(); will give you an array will all request data. After that you could loop over the array and insert it into a db or the storage method you want.
Edit: another way to handle this if you could have multiple names could be:
// View
<input type="text" name="names[]">
<input type="text" name="names[]">
// Controller
$request->names; // This is an array of values
Source: https://laracasts.com/discuss/channels/laravel/get-the-values-of-dynamically-generated-inputs
And events are indeed the way to go if you want to send a message. so you could fire an event as soon as the data is submitted. And one of the listeners would send a email or something like that
Related
So, for weeks now I have been playing around with my own PHP MVC Framework, purely for learning purposes. I've got the basics done, and I think I know what goes where, etcetera. But I have so far not been able to figure out the following.
Say I have a music database, and I have a "music controller", a "music model" and obviously a "music view". What I want to end up doing is, being able to ofcourse insert a new artist, and/or a new track, also I would like to be able to edit them, and so on. My URL's look like this:
example.com/controller/mainfunction
In my "music controller" I have a method as follows:
public function addTrack()
{
if (isset($_POST["submit_add_track"]))
{
// call the model to add track to database etc..
}
}
So, if I were to have a form in my "music view" and submit that, I could add a new track to the database. I also have a method to add a new artist, and so on.
But here is what I am struggling with. How should I design this? Should I use the music controller to add tracks and artists? Like so:
example.com/music/add/artist
example.com/music/add/track
Or should I do it differently, maybe I should use the "music controller" just to display the artists and tracks, and insert stuff with another controller? Like so:
example.com/insert/artist
example.com/insert/track
The latter seems the way to go for me, but I am not sure if this would be good design.
I think maybe what I am asking is, would it be good to use an "insert" controller, and then a "track method" to display the "insert track" form in the view? Next to this, there will be a lot more pages, not only music. But I just cannot figure out the logic behind this on how to do this properly so I can easily extend.
As you can see, I'm lost, any pointers (big or small) would help me a lot. Thanks in advance!!
Edit:
So, just to see if I'm on the right track now. I have a music controller with the code pasted below. If in the controller the "addArtist" method get's called, it goes to the model, adds the artist to the database, returns something to the controller, and it's done. Now for the part where I still have troubles. How do I display the form to actually add an artist? I know it should be in the view. But how should I call it? Something like this?
example.com/music/insertArtist
This could work, but then I would have an "insertArtist" method, for just displaying the form, and an "addArtist" method, for actually inserting the new artist to the database each time the form is submit. I know I am missing something, but I cannot quite figure this out still. What I am thinking is, in the "addArtist" method, I include the "addArtist" view file to be displayed, which holds the form, and I put in some "if submit then add the artist". Does that make sense and if so, am I on the wrong track?
public function addArtist()
{
// $artist_model->addArtist();
}
public function editArtist($artistID)
{
// $artist_model->editArtist();
}
public function deleteArtist($artistID)
{
// $artist_model->deleteArtist();
}
public function addTrack()
{
// $artist_model->addTrack();
}
public function editTrack($trackID)
{
// $artist_model->addTrack();
}
public function deleteTrack($trackID)
{
// $artist_model->addTrack();
}
example.com/music/addArtist
example.com/music/addTrack
You must strictly follow the format of /controller/method
When I say method, I mean literally, method. In fact, in your base controller class, the way you should call a method is
/**
* Executes the requested action
*/
public function ExecuteMethod($method)
{
$this->{$method}();
}
where you would pass addArtist or addTrack to the method.
Basically, the /controller/ part just tells apache which actual controller class to construct, and the /method/ tells it which method in that controller to execute.
EDIT:
This is the best MVC tutorial I know of. I based my MVC knowledge largely on this. However, it is okay to variate the standard MVC structure a bit to suite your needs better, as long as you do not change the core values of MVC that make it so powerful.
EDIT 2: (reply to your edit)
So what you're asking it how to view the form.
Viewing the form and submitting the form are two entirely different actions, and should be treated as such. Additionally, EVERY controller action, MUST have it's own view.
An easy way to put it, every time a user needs ANY data (or action) from the server, you MUST have an action and a view for that.
What this means, is that you will have two separate methods in your controller, viewForm() and submitForm(). Now, what you showed in your controller class, where you had addArtist(), editArtist(), etc, is inefficient, as you are just aliasing them to their corresponding model functions, which sort of skips the entire point of MVC.
I can't really tell you exactly how to implement the controller, as I do not know exactly what your goal is. But let's assume that you have a page that lists all the Artists, and you have buttons next to each for all the actions (Btw, as I said in the comments, in an implementation like this, if you are displaying Artists and Tracks on different pages, they should really have separate controllers). In this implementation, you would have a controller -> view setup like this:
/Artists/view -> returns an html list of artists with buttons
/Artists/viewAddForm -> returns a blank form you would use for creating new artists
/Artists/submitAdd -> returns an html confirmation page
/Artists/viewEditForm -> returns a form for editing with prefilled values
/Artists/submitAdd -> returns an html confirmation page
/Artists/delete -> returns an html confirmation page
So a user is presented with a list of artists. They have 3 options.
They click add, fill out the form, submit it, and get taken to a confirmation page.
They click edit, edit the form, submit it, and get taken to a confirmation page.
They click delete, and they get taken directly to a confirmation page since there is no data to fill.
The structure for Tracks would be exactly the same.
The way I handled this in my framework was to try and support a RESTful interface. I have
example.com/artist
example.com/track
I then use the HTTP verbs to represent the intent (POST/PUT/DELETE/GET)
It doesn't always fit neatly, but it's one way of doing it.
In your case I would worry about putting too much code in a single file. If you put all the responsibility in an insert controller, that quickly becomes an unwieldy code file. In your case I would probably go with two controllers and then create the right methods on each.
This is a long running question that gets me every time I am developing.
I suppose it is not specific to CodeIgniter, but as I am using it, I will consider it in my example.
Firstly, which is better:
function add_entry($data_array)
{
//code to add entry
}
function edit_entry($data_array)
{
//code to update entry
}
OR
function save_changes($what,$data_array)
{
//if what == update update
//otherwise insert
}
Both produce the same action, but does it really matter which one you use?
Getting onto more complicated things.
I have a page where I need to get ONE entry from the database.
I also have a page where I need to get all the entries from the same database ordered by a user specified column.
My resultant method is a function similar to
function($data_array,$order_by='',$limit='')
{
//get where $data_array
//if order_by!='' add order by
//if limit !='' add limit
}
As I develop my application and realise new places where I need 'similar' database functionality I am what feels like hacking previous methods so they work with all my case scenarios. The methods end up containing lots of conditional statements, and getting quite complex with in some cases 4 or 5 input parameters.
Have I missed the point? I don't want duplicate code, and when for the most part the functions are very similar I feel like this 'hacking' methodology works best.
Could someone advise?
Finally my admin functionality is part of the same application in an admin controller. I have an admin model which contains specific methods for admin db interaction. I however use some model functionality from 'user' models.
FOr example if on an admin page I need to get details of a db entry I may load the user model to access this function. There is nothing wrong/insecure about this..? right?
In addition to that within my admin model itself I need to get data about a user database entry so I call my user model directly from my admin model. This is strictly OK, but why? If i need data and there is already a method in my user model which gets it.. it seems a little pointless to rewrite the code in the admin model BUT each time that function is called does it load the whole user model again?
Thanks a lot all.
In order, add edit in the model vs save. Personally I have a save built in MY_Model that chooses whether it is a save or an edit depending on the existence of a primary key in the data being passed, so obviously I prefer that method it means a lot less duplication of code since I can use the save for any table without having functions in the model at all.
As to the second question I think it depends on situation. I also have a number of functions that have a ton of conditionals on them depending on where they're used and for what. In some cases I'm finding this makes the legibility of the code a little rough. If you're running them all through if statements it also could be impacting performance. DRY is a concept, not a rule and like other design concepts there are times when they just don't make sense, it's like database normalization, it's my personal opinion it's VERY easy to over normalize a database and destroy performance and usability.
Finally, using user functions in the admin code. I don't see an issue here at all, the reverse probably isn't true, but rewriting a function just because it's an "admin" function, when it's identical to a user function is utterly pointless. So you're correct there, it's a waste of time and space.
I'm working on my first CodeIgniter application and have encountered some confusion around handling post data.
More specifically, I understand the role of $this->form_validation->set_rules(), and how set_value() works to repopulate input values when the validation failed, but what I can't figure out is if $this->input->post is the same value as the set_value equivalent.
I understand that the majority of validation rules would have a boolean result, however what about ones like trim|htmlspecialchars - these also have the benefit of preparing the data for db queries.
So in my model, can I access the inputs after being processed by the Form Validation library, or should I do the additional preparation inside the model directly onto $this->input->post('variable')?
My gut tells me that I should add final processing like htmlspecialchars right before the SQL in the model, as it is really a db specific operation (I would not want & instead of & in my form inputs, but I would want & in the database).
Incidentally in my reading I did come across $this->validation->variable which would appear to have been the answer to my question in previous CI versions.
They are similar, but not exactly the same.
You would use $this->input->post('variable'); within the controller only. This variable will be validated and cleaned (if you decide to clean it with xss_clean or apply any other prepping functions).
set_value() should only be used within the Views. While this is not essential, the real value of doing this opposed to using $this->input->post is you can set a "default" value as the 2nd parameter which is automatically used if the post value is empty.
As mentioned set_value() is strictly for repopulating form inputs - nothing else. For example, set_checkbox() is going to return something like checked="checked" which is obviously not what you want to send to your model.
There's room for argument about where the input validation and prepping should be handled, but most will agree that it should be done in the controller.
You can do additional processing in the model if you wish, but generally you don't want to be accessing $_POST from the model - it makes the model less useful. Not all data is going to be coming straight from the user, so it's better to prep the data beforehand and send it as a new array/object to the model. The model should not care where the data is coming from.
Let the form validation library and controller layer process the user input (what it's intended for), and the model can process the data you send to it.
Developer
I work both frame work cakephp and codeignator. I feel best thing cakephp data validation. spouse you have 8 fields form you create validation in controller with designator. After validation all fields is empty if you fill 8 fields and by mistake 1 fields miss then after validation codeignator data validation refresh page and empty all fields.
but in cake php just opposite data validation create in model you create one time validation and use some thins when you call model then call validation exp: add,edit.
I'm trying to improve some PHP scripts using a OO design (it's procedural now with some OO parts). Just to be clear, I'm not trying to build a full MVC application, but I am trying to seperate parts as much as possible. I've never used MVC before in PHP (only a little bit in Java).
When using Google, I find 100 different MVC approaches for PHP and I can't find a good book on this subject. If anyone could suggest me a good book on OO design in PHP, it would be much appreciated.
Currently, a part to add a user to the database (assuming a user only contains a firstname for now), looks like this (users.php):
$validator = new UserValidator();
if ($validator->validate($_POST['user_firstname']))
$result = $db->execute("INSERT INTO `users` (`user_firstname`) VALUES (?)", $_POST['user_firstname']);
Knowing that adding users may be done at multiple places and I don't want code repeat, I will create a usermodel. This class will contain a method addUser(). The thing I'm a bit stuck with is the validation. The UserValidator will check if all fields are filled in correctly.
I could do this:
$validator = new UserValidator();
if ($validator->validate($_POST['user_firstname']))
$result = $user->addUser($_POST['user_firstname']);
But I could also do this:
$result = $user->adduser($_POST['user_firstname'];
Now the User-class will contain the validator and the addUser()-method will perform this validation. Assuming the above code is the controller, what option is the best? Delegating the validation functionality to the model or doing it in the controller?
The same problem applies when getting information of a certain user. Not everyone may get this info, so my code could look like this:
if ($user->hasAccess($_SESSION['id'], $_GET['id'])
$user->getUserById($_GET'id']);
(The hasAccess()-method will check if the user who is logged in can view details of a certain user id)
But I could also just call getUserById() and check if you have access in that method. Which option is the best?
Thank you!
In your first example, putting the validation logic in the call $result = $user->adduser($_POST['user_firstname']; is the cleaner way to go. Keep your controllers thin and let your models handle as much of the logic as possible. Ideally, your controller is coordinating data that will be passed to your "view", whatever that may be.
Your second example is less clear. You might have logic in hasAccess() that doesn't belong in getUserById() or you might be creating more work for getUserById() than makes sense for the method. It's always best to keep similar functionality as close as possible, but there are some assumptions that can't be made just by looking at the two lines you posted.
I user CakePHP pretty frequently, an MCV framework for PHP, and in such a case, the UserValidator would be broken out into a separate entity called a "component." The controller would call the component to do the validation before the save and then, if all passes, the data would be sent to the model for a save.
I think creating a separate validator class that can check your data in the controller may be the way to go.
On one hand form validation could be seen as part of the application logic and therefore belonging in the model.
On the other hand, it deals directly with the input coming from view and handles displaying errors, etc. From that angle it makes more sense to put it into controllers.
Which one is the right approach from the MVC point of view?
P.S my form validation actually consists only of writing a list of fields, their rules, and passing it on to a form validation library, which returns true/false on whether it passed validation or not.
Example:
$this->load->library('form_validation');
$this->form_validation->set_rules('name', 'Name', 'required');
$this->form_validation->set_rules('email', 'Email', 'required|valid_email');
//........
if ($this->form_validation->validate())
// Process data
else
$this->register_form(); //A controller action that will show a view with errors
Should this be put into a controller or model?
Ideally, you want 3 layers of validation:
View: Client side (javascript, html5 validation, etc.). This catches obvious errors and omissions before the data hits the controller, wasting the user's time and invoking an unnecessary page load if there are errors.
Controller: This is your Form validation layer. Controllers usually are meant to handle input directly, and send it over to the model. It is very rare that every field in your form has a directly related column in your DB, you usually need to alter the data in some way before passing it to the model. Just because you have a field you need to validate called "confirm email", doesn't mean that your model will be dealing with a "confirm email" value. Sometimes, this will be the final validation step.
Model: This is your last line of defense for validation, and possibly your only validation in the case of sending data to the model without it coming directly from a form post. There are many times when you need to send data to the DB from a controller call, or with data that is not user input. We don't want to see DB errors, we want to see errors thrown by the app itself. Models typically should not be dealing with $_POST data or user input directly, they should be receiving data from the controller. You don't want to be dealing with useless data here like the email confirmation.
Validation is Model's issue. Only model knows how your data should look like. You describe your data fields in model, so you should describe validation rules for this fields in the same place.
It seems to be obvious for me, but I'd gladly listen to opponents.
I would say the form validation code should be in the controller (not the model) in most cases.
Madmartigan put it best in his comment above "Form validation !== Data validation. Not all forms interact with a model"
Web forms are logically part of the View/Controller part of MVC, since the user interacts with them in the view.
Seems like everyone always says model hands down to this question, which has its merits (compared to the opposite), but I think the answer to the question is more subtle. Validation of the data itself should be performed on the model.
But there are other types of validation, such as whether the form has been submitted with unexpected fields (for security purposes, obviously) or whether a user has permission to make the operation requested. By putting these types of validation in the model, it cements the model (an abstraction of the data) to completely separate things, like how the user system works or how form submissions are evaluated for security purposes.
You can imagine changing one of those classes or systems of classes, then having a mess because you have to change all of your models, too. Whereas controllers are the mediator between the client input and the data: in that role, they are the proper validators of the examples above, and likely many others.
Taking in account other answers (and some research), if you have to validate data with rules like not-empty fields, email validation and stuff, the Controller shouldn't let this data pass through itself, but if you have rules like "only a user with a reputation greater than 150 can vote down an answer", you should do this in the model layer.
If you want to have business rules validation, I advise you to have an object like the Business Object Pattern, with that, in any part of the software when you want to "vote down an answer" you have your business logic preserved and centralized.
It is an interesting theoretical discussion, but if we focus on the point that the question was made in the context of Codeigniter(CI):
In CI you can specify a custom validation rule like this:
$this->form_validation->set_rules('email', 'Email', 'required|callback_my_validation');
In this scenario, you must define a public function called "my_validation" that must return true or false and the framework will add the error (if returned false) to a stack of errors.
So... if you put this code in the controller, you are inadvertedly exposing a public url, meaning it would by possible to call something like "http://yoursite.com/my_validation" (I don't think you intend that).
The only way to protect this url would be to go into the "routes.php" file and prevent there the access to this url. This does not seem practical and seems to point us in the direction that CI developers intended us to handle validation in the model.
The model should validate its own data.
Say you have a Contact model, that only requires a first name and phone number. It should validate that first name and phone number are filled.
However, if this Contact model is part of a Quote, you may need a full name and email address as well.
In that case, you could either extend the Contact model (to be a QuoteContact model) and add more validations, or you could do the extra validations on the Quote model.
You should write your models so as to be reusable in other applications (even if they never will be), so they should be independent of the controller. If the validations are in the controller, then you lose those validations if you switch to say a command line version.
If you validate form in serverside using codeigniter then it validate in controller
You need to include the form_validation library using autoload like this
$autoload['libraries'] = array("form_validation")
OR directly you load in Controller
$this->load->library('form_validation');
Then you set the validation rule to each form field
$this->form_validation->set_rules('username', 'User Name', 'required');
$this->form_validation->set_rules('useremail', 'User Email', 'required|valid_email');
If any error found after validation a form field then it catch in validate function
if ($this->form_validation->validate()) {
//return back to form
} else {
//successful validate all field
}
There is another angle to this not covered in the other answers. It depends on what you are saying you Controller / View is! If it is Javascript that checks for validation as users type, for security reasons you should have a validation in your backend as well (this could again be in the controller of your backend or model because anyone can just push Data through Ajax without the browser.
For performance reasons, you should have a validation in your front end controller / view as well because you don't want to be hitting your database every time a user selects an invalid Birth Date or something.
So apart from the theoretical foundation of validation in M, V, and / or C you must also consider the practicality of frontend vs backend irrespective of MVC.
My personal recommendation is to not limit yourself to only one level of validation. An ill placed validation (like the Confirm Password example mentioned in the other answers) can have serious implications on the architecture.