MVC Validation Advice - php

I'm currently validating input and returning errors in a "fat controller" as follows:
class SomeController
{
public function register()
{
// validate input
$username = isset($_POST['username']) && strlen($_POST['username']) <= 20 ? $_POST['username'] : null;
// proceed if validation passed
if (isset($username)) {
$user = $this->model->build('user');
if ($user->insert($username)) {
$_SESSION['success'] = 'User created!';
} else {
$_SESSION['error'] = 'Could not register user.';
}
} else {
$_SESSION['failed']['username'] = 'Your username cannot be greater than 20 characters.';
}
// load appropriate view here
}
}
class SomeModel
{
public function insert($username)
{
// sql for insertion
// ...
return $result;
}
}
While this works and is easy enough for me to implement, I understand that this is incorrect because the validation belongs in the model, which I'm attempting to correct using a "fat model" as follows:
class SomeController
{
public function register()
{
$user = $this->model->build('user');
$user->insert($_POST['username']);
// load appropriate view here
// ...
}
}
class SomeModel
{
public function insert($username)
{
// validate input
$error = false;
$username = trim($username) != '' && strlen($username) <= 20 ? $username : null;
// proceed if validation passed
if (isset($username)) {
// sql for insertion
// ...
$_SESSION['success'] = 'User created!';
} else {
// store error in session
$error = true;
$_SESSION['error']['username'] = 'Your username cannot be greater than 20 characters ';
}
return $error ? false : true;
}
}
The problem I see here is that the model is supposed to be portable, in that it should never need to change. But if the requirement for the length of $username changes, then obviously I'll have to alter my model.
I feel like this may be a really common question but I've yet to find a straight-forward answer. Without implementing any extra "layers", "mappers" or whatever other confusing terms are out there, how could the example pseudo-code provided be modified to correctly handle this transaction? (eg, validate input, return error if validation fails)?

Without implementing any extra "layers", "mappers" or whatever
You should consider the "model" to be a application layer rather than a single class. The term "layer" could be thought of as a simple way to reference the M slice of MVC sandwich. So to accomplish the flexibility you desire you will need to create it.
A number of clear seperations can be made. I would consider having three abstractions: services, data mappers and entities.
A service would be exposed to the controller and perform the service being requested.
// some controller
function register() {
$service = $this->getUserService();
$user = $service->register($_POST['first_name'], $_POST['last_name']);
if ($user instanceof \My\Entity\User) {
// set user in view
} else {
// redirect to error
}
}
So task one complete, the controller is now dumb to whatever happens within register, all it wants to know is how to resolve the appropriate result. If there is a user object, success, otherwise false something went wrong.
The service class itself would encapsulate the services being offered:
// class UserService.php
function register($firstname, $lastname) {
// validate arguments
if ($this->isValidUsername(....
$userMapper = $this->getUserMapper();
$user = new My\Entity\User();
$user->setFirstName($firstname);
$user->setLastName($lastname);
return $userMapper->save($user);
}
return false;
}
We handle the validation of the arguments and also create the new user, passing it to the data mapper which will perform the "actual save" abstracting the database operations.
// UserMapper
function save($user) {
// save $user to db
$sql = 'INSERT INTO ....
return true;
}

I'm not sure what you would consider to be an undesirable "layer" or "mapper". This is an interesting question, and my first though was that you could just include a configuration file that defined a constant for your username length. My second though was that you could have someModel extend a class or implement an interface, wherein you values would be set as properties or constants. I suspect that you have thought of these, and are avoiding them; that this is what you mean by avoiding "layers" and "mappers" It seems that you are being guided by these principals in this code:
Avoid "magic numbers"
KISS
Composition over inheritance
skinny controller/fat model
So, are you running php5.4+ ? Maybe define a trait which could be used in this and other models that defines the username length and other changeable values in the application. Or maybe that too is to much of a "layer"?

Related

OO PHP | Properly Passing POST Paramaters

I am relatively new to OO PHP and I am trying to create a login class.
The issue I am having is that I want to pass the POST values username and password to my class but I cannot establish a decent way of doing so.
below is a snippet of my class
class PortalLogin{
private $username;
private $password;
function __construct(){
//I connect to DB here
}
function login($username, $password){
//error check the paramaters here
//then I can run the query
}
function __destruct(){
//I disconnect from DB here
}
}
Above is a breakdown of the class I am creating below is how i plan to execute it (my main issue at the moment).
$login = new PortalLogin();
if(isset($_POST['username'])){
if(isset($_POST['password'])){
$login->login($_POST[username],$_POST[password]);
} else {
//throw error
}
} else {
//throw error
}
I really do not like the construction of the code above it seems to messy to be doing so much outside of my class. how can I pass the POST information to the class and execute the checks there? I am worrying that if I pass the POST information to the class and one of the POSTS contains nothing it will error.
I think you got a problem with the syntax of post..
if(isset($_POST['username']) && isset($_POST['password'])){
$login->login($_POST['username'],$_POST['password']);
}
use AND.. so if both username and password exist then call the login function()
I’m not sure where OOP comes in to this, but if you were going the object-oriented route you would have a class that represents a request from which you could grab POST data from:
$username = $request->post('username');
$password = $request->post('password');
Your post() method could return a default value (null) if the variable didn’t exist in the POST data.
You could then have a class that checks your user based on these variables:
$auth = new AuthService($dbConnection);
if ($auth->checkCredentials($username, $password)) {
// Valid user
} else {
$error = $auth->getLastError();
}
I know I might be in the minority with suggesting this, but I favour static methods for things like this. PortalLogin represents an action rather than data
class PortalLogin
{
/**
* Attempt login
* #param string $username
* #param string $password
*/
public static function login ($username, $password)
{
// do your login stuff
}
}
Then to use you would do this:
if (isset($_POST['username']
&& !empty($_POST['username']
&& isset($_POST['password']
&& !empty($_POST['password']
) {
PortalLogin::login($_POST['username'], $_POST['password']);
}
Even better OO would be to have the username/password checking baked into the User class. (Maybe User::checkLoginCredentials($u, $p); // boolean yup/nope)
You can use error suppression, like this:
$login->login(#$_POST['username'], #$_POST['password']);
If one or both values are not present in the $_POST variable, there won't be an error when calling the method, so you can do the error handling inside your class method.
For more info, check:
http://php.net/manual/en/language.operators.errorcontrol.php
Edit:
Another option is to do this:
$login->login((isset($_POST['username']) ? $_POST['username'] : null), (isset($_POST['password']) ? $_POST['password'] : null));

Where object should be validated?

My problem is that I don't know, witch solution for the validation of input is better and if there is another, better solution. Well, where object should be validated? On the one hand, the object should always be correct. On the other hand, if the user specifies several incorrect data, it's a more elegant solution to notify him of all errors, not just one (first occured).
// Solution 1:
try {
$user = new User();
$user->setFirstname($_POST['firstname']);
$user->setSecondname($_POST['secondname']);
$user->setLastname($_POST['lastname']);
$user->hasLeftHand($_POST['has-left-hand']);
$user->hasRightHand($_POST['has-right-hand']);
$user->setHandedness($_POST['handedness']);
$user->save($pdo);
} catch (Exception $e) {
echo $e->getMessage();
}
// Solution 2:
$user = new User();
$user->setFirstname($_POST['firstname']);
$user->setSecondname($_POST['secondname']);
$user->setLastname($_POST['lastname']);
$user->hasLeftHand($_POST['has-left-hand']);
$user->hasRightHand($_POST['has-right-hand']);
$user->setHandedness($_POST['handedness']);
$errors = $user->validate();
if (empty($errors)) {
$user->save($pdo);
} else {
echo 'Some errors occured: ' . implode(', ', $errors);
}
// Solution 3:
try {
$user = new User();
$user->setFirstname($_POST['firstname']);
$user->setSecondname($_POST['secondname']);
$user->setLastname($_POST['lastname']);
$user->hasLeftHand($_POST['has-left-hand']);
$user->hasRightHand($_POST['has-right-hand']);
$user->setHandedness($_POST['handedness']);
$user->save($pdo);
} catch (Exception $e) {
$errors = $user->validate();
echo 'Some errors occured: ' . implode(', ', $errors);
}
In solution 1 each set method validates the input. Therefore, the object is always correct. The save method only saves the object in the database. On the other hand, if all the data is incorrect, it will be displayed only the first error.
In solution 2 we allow that object can not be correct between set calls, but to the database can be saved only valid object. set methods do not validate the input. validate method validates the object as a whole, and returns a list of all errors found. save method looks like this:
public function save(PDO $pdo)
{
if(! empty($this->validate())) {
throw new Exception('Invalid state');
}
// Store in database
}
In this solution is easier to validate the object. Becouse, how should work code below in solution 1?
$user->hasLeftHand(true);
$user->hasRightHand(false);
$user->setHandedness('right');
Or this code:
$user->setHandedness('right');
$user->hasLeftHand(true);
$user->hasRightHand(false);
Solution 3 is a copy of solution 2. Code of User class is the same. Changes only its use - try-catch block. In my opinion, this code looks more clearly.
Validation of input should be separated from validating the correctness of a domain object itself. Many frameworks use Form classes for this. Maybe have a look at how it's done in:
Symfony
Zend Framework (Form InputFilters)
In short, the form will validate the input, and will populate a bound object in case the data is valid.
disclaimer: this question is opinion based, and there is no 1 correct answer... but I'll true to recap what we discussed in comments and how I think most people solve it.
separate input validation from the model
<?php
// class for input validation
class UserValidator
{
public function validate(array $data)
{
$errors = array();
if (isset($data['email'])) {
if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
$errors['email'] = 'email not valid';
}
} else {
$errors['email'] = 'email is required';
}
}
}
// model class itself, does not implement extensive validation
class User
{
protected $email;
public function setEmail($email)
{
// only make sure we have a valid string, dont validate email again
if (!is_string($email) || !strlen($email)) throw new \InvalidArgumentException('invalid email given');
$this->email = $email;
return $this;
}
}
So this example separates the input validation so it is easy to provide user feedback when processing form data. The model itself only performs basic checks, and assumes the developer is smart enough to set sane data...
<?php
// where you process a form POST...
$validator = new UserValidator();
$errors = $validator->validate($_POST);
if (count($errors)) {
// provide feedback to your user, he gave us bogus data...
return $errors;
}
// if we are here, we passed validation and can assume our data is good
$user = new User();
$user->setEmail($_POST['email']);
This is a very simplified example, again you should check out how the major frameworks solve this problem, they've had many people thinking hard about this already...
And as the differences between Zend and Symfony underline: there is no golden hammer for this.

Same function for jquery and php validation

So I have this problem. I'm doing a server side validation and a jquery validation.
In server side validation what I do is to use codeigniter's form_validation library, more specifically:
$this->form_validation->set_rules('documentn', 'Passport number', 'required|min_length[7]|max_length[20]|is_natural|callback_checkDocAndUser');
which needs a return true or return false.
I have this user edit form, to change user data. But there are some restrictions... user when stored in database has a unique passport number. I need to be able to change this passport number if it's wrong... but passport numbers should not be repeated on the database.
This is the php function that is called from callback_checkDocAndUser :
public function checkDocAndUser(){
if ((isset($_POST['documentn'])) && (isset($_POST['id']))) {
$dn = UserManager::getInstance()->checkUserDocument($_POST['documentn'],$_POST['id']);
if ($dn) {
//passport belongs to the user
echo "true";
// return true;
}else{
//does the passport entered belong to another user?
$exists = UserManager::getInstance()->getByDocument($_POST['documentn']);
if (!$exists) {
//passport belongs to another user
echo "true";
// return true;
}else{
//passport number is free to use
echo "false";
// return false;
}
}
}
}
As you can see I put some "echo" in the functions. This is because I want to use the same function for a jQuery validation (which needs echo, doesn't work with "return").
documentn: {
required: true,
minlength: 7,
maxlength: 20,
remote: {
url: '/admin/checkDocAndUser',
type: 'POST',
data: {
id: function(){
return $('#id').val();
}
}
}
},
So how can I use the same function for both kind of validations...? is there a way to make jquery function receive a return..or codeigniter's function to receive an echo?
I do the same thing in my CodeIgniter projects and the solution is quite simple. The following answer is generically named where you only need to add your validation logic.
This answer follows the DRY principle where your validation code is not repeated, as well as CodeIgniter structure.
This MODEL does the actual validation for both CodeIgniter (server-side) validation and jQuery Validate (client-side) remote...
// file name 'models/demo_model.php'
class Demo_model extends CI_Model {
public function check_demo($params)
{
// insert your validation logic here...
// the entirety of your validation logic, check the DB, etc.
// if it passes validation
return TRUE;
// if it fails validation
return FALSE;
}
}
This CONTROLLER is only called by client-side remote for jQuery Validation...
// file name 'controllers/demo.php'
class Demo extends CI_Controller {
public function remote_demo($params = FALSE)
{
// call the Model to do the actual validation
$valid = $this->demo_model->check_demo($params);
if ($valid)
{
echo 'true'; // passes validation
}
else
{
echo 'false'; // fails validation
}
}
}
This LIBRARY is only used for server-side validation by CodeIgniter...
// file name 'libraries/MY_Form_validation.php'
class MY_Form_validation extends CI_Form_validation {
public function __construct()
{
parent::__construct();
$this->ci =& get_instance();
}
public function demo_check($params)
{
$this->ci->form_validation->set_message('demo_check', 'The %s is incorrect.');
// call the Model to do the actual validation
return $this->ci->demo_model->check_demo($params);
}
}
The way it's organized, you'll have ONE centrally located validation function residing with your CodeIgniter Models. I chose Models as the central location because the code is primarily interacting with the database.
The following uses the same Model function for both kinds of validation.
Server-side CodeIgniter validation: Calls the Model from MY_Form_validation and the Model will return TRUE or FALSE back to your other CodeIgniter Controllers as per your CodeIgniter validation rules.
Client-side jQuery Validate remote: Calls the Model from the Controller and the Model will return TRUE or FALSE back to the Controller. Then the Controller function will echo true or false based on this boolean response from the Model.
Validation functions always need to return a boolean value.
In your controller, try to retrieve the return value of the validation methods and echo "true" or "false" there.
Put an exit at the end of your function.
EDIT:
If you want to use the same set of validations for both client and server side validation, divide your call to two functions, one which handles client and the another which handles server. check the following code:
In you jquery function call url - admin/validate_form_client
function validate_form_client(){
$op = $this->checkDocAndUser($_POST['documentn'],$_POST['id']);
echo $op;
exit;
}
function validate_form_server(){
if ((isset($_POST['documentn'])) && (isset($_POST['id']))) {
return $this->checkDocAndUser($_POST['documentn'],$_POST['id']);
}
}
public function checkDocAndUser($documentn,$id){
$dn = UserManager::getInstance()->checkUserDocument($documentn,$id);
if ($dn) {
//id belongs to the user
return true;
}else{
//does the id entered belong to another user?
$exists = UserManager::getInstance()->getByDocument($documentn);
if (!$exists) {
// id number belongs to another user
return "true";
}else{
//id number is free to use
return "false";
}
}
}
}
Note: the given function names are just for example. please follow standard practice in the variable and function naming conventions.

Singleton, passing objects, using static, returning errors or globals?

I know, globals not (;
I am new to OOP, and I'm refactoring some functions I created into classes, but I come to a problem. Some of my classes are called from the pages themselves that the users enter (example: $Link->create('page/to/go');). Since this is outside any class, there's no problem, the links get created.
But then, I have a class that attempts to login the user when created, and if the email entered is not in the database it redirects the user to the register page. Obviously, only doing header ('Location '.$Link->create('page/to/go')) does not work.
What I would do is to set the create method as static and then call it from everywhere. But I think this would be similar to using globals and I am trying to correct bad habits. So how should I do this?
Here's some of the code for the class Link, implementing a 404-detect that I explained here:
class Link
{
private function valid($check)
{
$exceptions=array("help/report", "translate"); // More pages and rules to be added
return in_array($check,$exceptions);
}
public function create($arg)
{
if (!file_exists("/path/to/".$arg) && !$this->valid($arg))
{
// Call a function to store the error in a database.
error ("404 for ".$arg);
// One way of handling it. Replace '/' for ' ' and google that string in this page.
$arg=str_replace("/","%20",$arg);
return "https://www.google.com/#q=site%3A".Configuration::get('BaseUrl')."%20".$arg;
}
else
{
// If the page exists or is an exception, create the normal link.
if(empty($arg)) return Configuration::get('BaseUrl');
else return Configuration::get('BaseUrl').$arg;
}
}
}
As you can see in the code, when I implement error() into a class I will have a similar problem.
One option I just thought is that I might want to return an error and parse it from outside the __construct() of the User class. But it only works with this, as it's a yes/not, and I don't think making a error code up is proper for other cases.
So, what is your suggestion for passing properties and methods from one classes to others? Is it okay to use static for this context?
EDIT. The difficulty of my question it's that, almost all book, tutorial, page etc I've seen talks about how to create a SINGLE class. I haven't seen any explaining deeply how classes should talk to each other.
EDIT 2. As requested in the comments, here goes some more code. The user accesses his courses entering only the email (getting a level 1), while the user can only edit his settings if he gets a level 2 in the settings page. Not finished as I'll put some more methods.
class User
{
private $Email;
private $Name;
public function __construct()
{
if (!empty($_POST['logout'])) session_destroy();
else if ( !empty($_POST['email']) )
{
$this->loginEmail($_POST['email']);
}
else if ( $_SESSION['level'] == 1 )
{
if (!empty($_POST['password']))
{
$this->loginFull($_SESSION['email'],$_POST['password']);
}
else
{
$this->loginEmail($_SESSION['email']);
}
}
else if ( $_SESSION['level'] == 2 )
{
$this->loginFull($_SESSION['email'],$_SESSION['pass']);
}
else session_destroy();
}
private function loginEmail($Email)
{
$sql=mysql_query("SELECT * FROM users WHERE email='".mysql_real_escape_string($Email)."'"); //Retrieve the entries from the database
$row=mysql_fetch_assoc($sql);
if(mysql_num_rows($sql)==1)
{
$this->getData($row);
$_SESSION['level']=1;
}
else header ('Location: http://example.org/new/student/');
}
private function loginFull($Email,$Pass)
{
$sql=mysql_query("SELECT * FROM users WHERE email='".mysql_real_escape_string($Email)."' AND pass='".md5($Pass)."'"); //Retrieve the entries from the database
$row=mysql_fetch_assoc($sql);
if(mysql_num_rows($sql)==1)
{
$this->getData($row);
$_SESSION['pass']=$Pass;
$_SESSION['level']=2;
}
else $this->loginEmail($Email);
}
private function getData($row)
{
$_SESSION['email']=$row['email'];
$this->Email=$row['email'];
$this->Name=$row['name'];
}
public function get($Var)
{
return $this->$Var;
}
}
And now the class Error. As you can see, I already performed some DI without even knowing about it here.
class Error
{
private $Page;
private $Language;
private $User;
public function __construct($Page,$Language,$User="None")
{
$this->Page=$Page;
$this->Language=$Language;
$this->User=$User;
if (!empty($_REQUEST['banner']))
$this->Banner=$_REQUEST['banner'];
}
public function add($Kind)
{
if (!mysql_query("INSERT INTO error (kind, page, lang, user, version, date) VALUES ('".mysql_real_escape_string($Kind)."', '".mysql_real_escape_string($this->Page)."', '".mysql_real_escape_string($this->Language)."', '".mysql_real_escape_string($this->User)."', '".Configuration::get('Version')."',NOW() )"))
mail(Configuration::get('ErrorEmail'), "Error '".$Kind."' that couldn't be stored.",
"Full url: ".$FullUrl."\n Language: ".$this->Language->Lang."\n User: ".$Identif."\n Version: ".$Version); // Inform of the error by email
}
}
Create instance of Link class and pass it to where it is needed (using setter or constructor).
Definitelly read something abou DI (Dependency Injection) and then DI Containers.
Nice introduction in Nette Framework - Dependency Injection
Singletons and Static aren't a good choice. In the end everything falls onto the globals problem.
You should inject your link helper into the classes by constructor or setter (DI as #jasir said).
If you'll redirect the user, you can also inject an redirector helper:
$redirector->redirect('controller','action', array('my','params'));
Hint: this is bad too Configuration::get(). Inject the config instead.
And always remember: Don't look for things!

Structure of a form validation class

I want to make a class in OOP PHP to validate forms. However, I've having trouble structuring this.
Initially I thought of creating individual functions for each type of validation (check length of submitted data, check whether it's a number or not, etc), then another function to check whether data passed the validation tests and pass errors into an array.
I'm getting stuck though as my code is becoming very long and difficult to manage- I'm pretty new, so how would you approach this problem?
As i was reading through your post, a question came into my mind about what you write:
Why, instead of validating a form, dont you validte your model's objects?
I mean, in an OOP way of looking things your model´s object (or domain objects) are the ones who knows what data is valid or not for each of their attributes.
Not doint that, and pushing that logic into the UI makes your design fragile, UI dependant and harder to maintain. If you add a new attribute to one of your model's object, you'll have to modify the form validator as well.
If you go with Objects Validation, the idea is that an object cannot be created in an invalid state. If you try to modify it with invalid data, an exception will be thrown.
This makes easy to work with forms. The only think you have to do is populate your objects and watch for exceptions thrown in that process.
This is only an idea to get you started and see another way of solving this problem.
Regarding your question about Forms Validation, as the other guys said, it is always better not to reinvent the wheel and go for an existing, proven, validation framework.
However, if you are curious about it, here is one of the many ways you can do it:
Let's go through the things you need: you are talking about a form that needs to be validated with one or more validation functions. Then you talk about a function that tells you whether the form passed the validation or not, and as a result you got the list of errors found during the validation phase.
As you talk about OOP, the way to go is to give each concept or idea of your problem domain (the domain of form validation) entity via a class that represents it that model the behavior they have.
So, it is natural to think about a FormValidator class with a list of ValidationRule instances, where each one colaborates in the validation process. This validation process is done by calling the validate function of the FormValidator. Also, each ValidationRule will give, as result of calling it´s own validate method an instance of the ValidationRuleResult class, that tells whether the validation was successful or not, along with an error message and additional data (if needed) about the validation. Once all the validation rules were evaluated, the validate method of the FormValidator class will return an instance of ValidationResult class, that summarizes all the validation results of the rules evaluated providing the list of errors found.
To get this down to earth, here is the sample model we're talking about:
A sample implementation
Disclaimer: please bear in mind that, as any design, it may contains flaws. The following is intended to help you to solve your problem, not to be a complete solution.
class FormValidator {
private $_validationRules;
function __construct() {
$this->_validationRules = array();
}
// Registers a new validation rule
function addRule($aValidationRule) { $this->validationRules[] = $aValidationRule; }
// Validates $aForm, evaluating each of the $_validationRules defined
function validate($aForm) {
$aValidationResult = new ValidationResult();
foreach($this->_validationRules as $aValidationRule) {
$aValidationRuleResult = $aValidationRule->validate($aForm);
$aValidationResult->addResult($aValidationRuleResult);
}
return $aValidationResult;
}
}
abstract class ValidationRule {
private $_fieldName;
// The form's field name to be validated
function __construct($aFieldName) {
$this->_fieldName = $aFieldName;
}
function fieldName() { return $this->_fieldName; }
// Returns an instance of ValidationResult describing the result of evaluating the ValidationRule in $aForm.
abstract public function validate($aForm);
}
class ValidationResult {
private $_validationRuleResults;
function __construct() {
$this->_validationRuleResults = array();
}
// Registers a validation rule result
function addResult($aValidationRuleResult) {
$this->_validationRuleResults[] = $aValidationRuleResult;
}
// Returns the list of the error messages of the validation rule results that did't passed
function errorsFound() {
$errors = array();
foreach($this->validationRuleResults as $aValidationResult) {
if ($aValidationResult->passed()) continue;
$errors[] = $aValidationResult->errorMessage();
}
return $errors;
}
// Tells whether all the validation rule results passed or not
function validationPassed() {
foreach($this->validationRuleResults as $validationResult) {
if ($validationResult->passed() == false) return false;
}
return true;
}
}
class ValidationRuleResult {
private $_passed, $_error_message;
function __construct($passed) {
$this->_passed = $passed;
$this->_error_message = '';
}
// Tells whether the form passed this validation rule or not
public function passed() { return $this->_passed; }
public function
// The error message should be empty if passed to avoid confusion
public function errorMessage { return $this->passed() ? '' : $this->_error_message; }
public function setErrorMessage($anErrorMessage) { $this->_error_message = $anErrorMessage; }
}
You can create a validation rule this way:
class NotEmptyValidationRule extends ValidationRule {
public function validate($aForm) {
$fieldName = $this->fieldName();
$fieldValue = $aForm[$fieldName];
$passed = !empty($fieldValue);
$result = new ValidationRuleResult($passed);
if (!$passed) {
$result->setErrorMessage("$fieldName cannot be empty");
}
return $result;
}
}
Some things to note:
Im assuming that $aForm is an associative array of field name / value
You can note that if a validation rule passes, the result is not used (as the ValidationResult class works only on those results that didn't pass). Remember that this is a sample only for the purpose of helping you, is not a complete solution.
Usage
$rule = new NotEmptyValidationRule('name');
$validator = new FormValidator();
$validator->addRule($rule);
$aForm = $__POST['myForm'];
$validationResult = $validator->validate($aForm);
if ($validationResult->validationPassed()) {
$errorsFound = $validationResult->errorsFound();
// do something with the $errorMessage
$errorMessage = array_join('<br/>', $errorsFound);
}

Categories