General MVC Questions on PHP & Magento Validations - php

I have been using Magento & PHP CodeIgniter MVC for about 4 months. I am having a peculiar problem understanding where to set the validation logic for both CodeIgniter & Magento, only if I consider to follow the MVC architecture to its true nature & in a very proper semantic way.
First of all, I will start off with Magento:-
Say I have a "Assignment" module in Magento, which is about Players & Tournaments both. I have 3 action methods, in this "Assignment" module's controller, where I need to check & validate the following:-
Player ID
Tournament ID
This validation is also required in the "Assignment" module's Block class, along with in the 3 action methods.
So my query is should I write the validations for the above 2 points in this module's Controller class or in the Model class, because I will need to use the validations both in the Block class & also in the Controller class?
Also what does actual MVC architecture suggest in this case?
If possible, please provide a code snippet, highlighting the logic of your implementation.
Regarding CodeIgniter or any other PHP MVC Framework:-
Since Validation of anything using sessions is quite page-specific & since there is no concept of Blocks in CodeIgniter, so normally session validations & setting of session variables are done in the Controller class only.
So my query in this regard is that is this a correct approach & under what circumstances should I put setters of sessions & session validations in the Model class?
And again, what does actual MVC architecture suggest in this case?
And again, if possible, please provide a code snippet, highlighting the logic of your implementation.
I am really in confusion state regarding this & I'm sort of stuck in here. Please help me in here. Any solution / help is greatly appreciated. Many thanks in advance.
EDIT:-
If possible, please provide some Magento code on how to create & write proper Validations, along with throwing Exceptions, with the actual Exception messages defined in the Model methods?

The Model layer should be able to maintain its own consistency, so regardless of other decisions, you should include your validations in the Model layer. To help the user (and provide more helpful validation messages), you may also wish to do some validation in the controller level.
The advantage of this approach is that, assuming you maintain your model layer, there is no chance of a rogue controller setting bad data. This plays into your second question, for which the Magento answer would be to use an object to manage data in parts of the session, and to validate that data on the way into the session.
As an aside, to deal with validations in your Blocks/Views, consider using validation like this. It has its own flaws, but generally minimizes the amount of validation code you have to write:
// make sure that the below returns the relevant assignment model class
$assignment = $this->getAssignment(); // or get it via a session, or helper, or what have you.
$player = getChosenPlayer();
try {
$assignment->setPlayer($player); //throws exception when invalid
... do more ...
$assignmnent->save();
} catch(SomeException $e) {
addValidationError($e->getMessage());
renderPageAgain();
}

Related

MVC - functionality in the controller/model

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.

PHP MVC (no framework), should I be calling a lot of methods in my controller or model?

I've been working on creating my own MVC app in PHP and I've seen a lot of differing opinions online about how exactly this should be set up. Sure, I understand there seems to be a general "It's MVC, it is what you make of it" approach, but I'm running into 2 seemingly conflicting viewpoints.
A little background on my app: I'm using smarty as my presenter and an object-oriented approach. Seems simple enough, but I'm trying to figure out the ubiquitous "what is a model" question.
If I take a look at some tutorials and frameworks, they seem to view the model as strictly a class that inherits DAL methods from an abstract class, with a little bit extra defined in the class itself as your data needs differ from object to object. For example, I might see something like $productModel->get(5) that returns an array of 5 products from the database. So what if I need to query multiple models? Do I store all of the data in the controller or an array and pass that to the view? Then if I'm dynamically calling my controller, how can I persist the data unique to the controller necessary to render the view? This seems bad, especially because I then have to pass in things like "controllerName", "controllerData", and my View::render() method gets hugely bloated with parameters, unless I pass in the controller itself. Maybe I'm missing something here.
Let's say I want to make a login that queries a users table. Login is a model or a controller, depending on certain implementations I've seen online. Some implementations (I'll call this method 1) make a LoginController with method login() that might do a comparison of $_POST and what's returned from the user model instance $user->get(1) to see if a user is validated. Or maybe login() might be a method in a default controller. On the flipside, an implementation (implementation method 2) that resembles more of a Joomla approach would make a Login model and declare all of the actions inside of that. Then any data that needs to get assigned to the view would get returned from those methods. So login->login() would actually check post, see if there's a match, etc. Also the User model would probably be instantiated inside that model method.
My feelings about 1: The controller is fat. Additionally the controller is storing data pulled from models or passing in ten thousand variables. It doesn't seem to jibe with the idea that the model should be passing data to the view that the controller should be blind to. Also, let's say I want to wrap everything that is in a specific model handled by a specific controller in an outer template. I'd have to copy this template-setting code all across my controller functions that interface with this model. It seems grossly inefficient.
My feelings about 2: It doesn't make for having actions that aren't model methods. If I want to go to my site root, I have to make an index model or something that seems like overkill in order to have a model that passes data to the view. Also, this doesn't seem to be a very popular approach. However, I do like it more because I can just do View::render(mymodel->func()) and ensure that the data is going to be passed back just the way I like it without having to crap up my controller with code merging a thousand query results together.
I've waded through far too many religious arguments about this and want to know what you guys think.
I've built my own framework in the past too so I know what you're going through. I've heard the saying "build fat models" and I agree with that -- as long as the main goal is to return data. I considered the controller to be "The Overlord" as it manipulated data and directed where it should go.
For a login controller i might create something it like...
Post URI: http://example.com/login/authenticate
LoginController extends ParentController {
public function authenticate() {
$credential_model = $this->getModel('credentials');
// Obviously you should sanitize the $_POST values.
$is_valid = $credential_model->isValid($_POST['user'], $_POST['email']);
$view = $is_valid ? 'login_fail.php' : 'login_success.php';
$data = array();
$data['a'] = $a;
// .. more vars
$this->view->render($view, $data);
}
}
In my opinion data should always flow from the model -> controller -> view as it makes the most sense (data, manipulation, output). The View should only have access to what it has been given by the controller.
As for this...
Then if I'm dynamically calling my controller, how can I persist the data unique to the controller necessary to render the view?
Well I would imagine you're building a 'base' or 'parent' controller that gets extended off of by your dynamically called controllers. Those child controllers can have properties that are needed for for the view to render -- honestly I'd need an example to go further.
Hopefully this helps a bit. If you ask more specific questions I might be able to give a better thought out opinion.
If you're writing your own app, I think the best solution is to do it yourself and find out.
Ultimately, whatever makes the most sense to you, and whatever makes it easier for you to conceptualize your app and quickly add to or change it, is going to be your best option.
If one way is "wrong", then you'll find out through experience, rather than someone else telling you. And you'll know the entire situation that much better, and know EXACTLY why one way is better.
What helped me when I was writing my own framework in PHP was, strangely enough, CherryPy. It made the concept of an object-oriented web app so simple and obvious, and I enjoyed using it so much, that I modeled the basic structure of my PHP framework to imitate CherryPy.
I don't mean to imply you should learn CherryPy. I mean that simplicity, clarity, and enjoying developing with your own web app go a LONG way.
If I were to give one piece of specific advice, I'd say try to avoid retyping code; write your code to be reusable in as many situations as possible. This will not only be good for your app, but for future apps you may write or work on.
You might check out Eric S. Raymond's Rules for Unix Programming. I think they're definitely applicable here.

Where is the best place to verify form data?

Question is simple . Where should I put form verification process in the mvc design pattern (Zend , Symphony, Cakephp, Codeigniter) . I ask this question because i have my own framework. But i can not decide where should i handle form verification . For example , i can write if statements in controller but this makes controller "fat" , or i can add verification statements in model function ( in User::register( , , ) ) . Of course this is not very complex thing ,but my aim is to understand how do they do in enterprise level applications .
If you consider the Models in MVC as what we in the .NET world call ViewModels (and I believe are called Presentation Models elsewhere) instead of Domain Models, the Model would be an excellent place to add validation/verification.
This would allow you to reuse the verification logic anywhere you are reusing the Model, and it makes sense since the Model would be encapsulating the verification logic together with the data. That sounds like high cohesion to me.
As a sanity check, the ASP.NET MVC framework seems to be heading in that direction as well. Since the question is tagged 'php' I'm not sure this last piece of information strengthens or weakens the argument.
Validation is Control of input. MVC stands for Model View Controller, so validation should be in a controller.
General validations like isInt(), isStr(), isEmailAddress, isFloat() etc etc could/should be placed in a base controller. Then you can have subcontrollers for specified Models (mapping to your database). Those subcontrollers then extend from the base controller.
There are multiple places where validation can happen.
First, client-side versus server-side: it's frequently a good practice to do pre-validation on the client side (ex. "only numbers allowed!") before sending the bits up the wire. Server side validation is always mandatory as a security / data integrity requirement.
Front end versus model requirements: a particular form might not know of model's requirement for related data objects (for example, if there's a business logic rule that value of 3 in a particular field should not be present if the number of related records is less than 5) - the only place that would know that is the model.

Should you validate in the Model? (Symfony based question, but related to general MVC)

This is a quick question relating to Symfony, but could be a general MVC question.
I have a class in my model, for example, WebUser. This class has a property of email_address. This value must be unique to each WebUser.
Now, I've made it so all my Symfony forms validate that the email_address is unique for the given WebUser, however I'm wondering if I should add this validation to the model as well?
But this also got me thinking, should you actually validate every set() method in the model? It seems a wise enough decision to make sure no erroneous data ends up in the database, however most (if not all) data has to go through the controllers, which validate as well. So to me it seems I'm running the same validation twice and it just seems pointless?
What are your thoughts on this? I'm still leaning towards validation in the model as that makes the most sense as it dictates the business logic.
If you should validate in the model, how do you throw an appropriate set() error in Symfony that is handled correctly by the form framework?
Thanks.
I disagree with "Validation should be part of domain logic, not front-end logic".
Validation is a complex functional part of your application and must be context aware. ie. you have to know is the user is logged in, what kind of credentials she has, the status of the request/form and so on. Models instead must be context agnostic (to work in any environment not only http request but also cli etc.) so they don't know about the user, the state and the http request. This is a strong requirement for the testability of your model classes.
For the summentioned reason functional validation must belong to the form which knows the application state (ie. session). symfony helps a lot with the sfValidator* classes which belongs to the form component indeed. That's the reason why forms are tested with functional testing.
Data validation should be in the model instead (ie. check if the value is an integer or a string, check if it's null and so on). This is easily accomplished with the Doctrine in-schema validation rules.
I can't speak specifically to Symfony, but I know that I purposely shun Zend Framework's form validation, and instead validate on my models (Zend Framework does not provide its own Model component, so it has no actual opinion on the matter).
There's nothing wrong with validating on the form, but I think you should also be validating on the model. Validating on the form might be useful for quick and easy input checking, especially if the processing logic is complex - you won't waste time working with data that's obviously bad.
Reasons I think model validation is best:
There's a chance a model will alter the data after it passes through the form and before it goes into the DB
Validation should be part of domain logic, not front-end logic (I realize Symfony seems to disagree).
Validation state travels with the model object, instead of the form object.
If you're not totally sold validating only in the model, a combination of the two sounds like a good solution.
EDIT: At the end of the day, it might make the most sense to just go with your framework on this. If Symfony seems most opinionated toward validation in the controller, and doesn't provide an easy path for validation in the model, just go with what they want you to do (or the direction in which the Symfony community leans). Fighting your framework is never fun.
I can't help out with the symfony part but most MVC-Frameworks do validation in the model, since this is the only place inside a MVC environment where validation should be.
This goes for the validation of the model's attributes of course.
I Think You Should User MVC Validator Tool Ket Insted of using others rely on modelstate its easyer and also testable and its based on formcollected not to the model that give you free run way
Regards MArwan HAfez

Use of XML for Model class and structuring

I am currently working on a little application:
The structure follows in some way the MVC pattern.
For short it has the basic things, Models, Controllers etc.
Now I am sitting here and do not know whether :
1.
The SQL database is only managed by a model through methods the programmer gives him like: "Hey we have name record so we need a getName() method".
OR
2.
The model dynamically creates the whole database and methods, using a XML file, with which even a non-programmer can design a database.
And should the model class check every/a single request whether it is a valid request e.g. getName() won't work on the houses_tbl, and if it is not valid it does not perform the query, and sends back an error message instead?
I have absolutely no idea how to handle my model class, which structure it should follow and how much the programmer should have to put into a new model so it works as he wants it to work.
Major points:
perfomance (which way saves the most perfomance)
KISS (which way is simple enough, so a second team mate can understand my logic)
extendability (can I extend the structure)
Check these Data Source Architectural Patterns: Table Data Gateway, Row Data Gateway, Active Record, Data Mapper. For code examples to these patterns in PHP, you could check Zend_DB_*.
Which pattern you should pick depends on your application. If you are doing a simple CRUD application, you might want to use Row Data Gateway. If you are building an application with a lot of business logic from a certain domain, you will likely pick a different one.
Just remember that the M in MVC is not just the Persistence layer. The model is the heart of your application. Controller and View are just an end to your application. Further reading by Rob Allen and Matthew Weier O'Phinney.
As for your major points, I suggest to just stick to general established practises. UnitTest your code, write meaningful code and document it, favor aggregation over composition, capsule and separate concerns, code against an interface, refactor, etc.
Why not statically create the objects etc. during development from the database. i.e. use some Object-Relational-Mapping ?
That way you create your Person object from (say) the database schema. It creates a getName() accessor, and the rest of your code compiles against that. If you remove/rename the name field, then the generated code changes and consequently stuff doesn't compile. Catching these errors early will save a lot of grief.
This question details some PHP/ORM options. I confess I've not checked these to see if they're entirely what you want, but hopefully they should point you in the right direction.

Categories