From 4123e185f428bfd166213878e5aef8ec94843145 Mon Sep 17 00:00:00 2001 From: Vance Lucas Date: Sat, 2 Feb 2013 20:10:02 -0600 Subject: [PATCH] Add error messages with basic translation support * Initial English error messages file and directory * Setup methods to specify language and directory to find lang files in * Change 'alphaDash' validation name to 'slug' for URL slugs * Now passing all parameters to error message via `vsprintf` * Add `message` convenience method to easily specify custom message on last validation rule * Add tests for error messages --- lang/en.php | 27 +++++++++++++ src/Valitron/Validator.php | 75 +++++++++++++++++++++++++++++++------ tests/Valitron/Validate.php | 29 +++++++++++++- 3 files changed, 117 insertions(+), 14 deletions(-) create mode 100644 lang/en.php diff --git a/lang/en.php b/lang/en.php new file mode 100644 index 0000000..ac657cc --- /dev/null +++ b/lang/en.php @@ -0,0 +1,27 @@ + "Required", + 'equals' => "Must be the same as '%s'", + 'different' => "Must be different than '%s'", + 'accepted' => "Must be accepted", + 'numeric' => "Must be numeric", + 'integer' => "Must be an integer (0-9)", + 'length' => "Must be longer than %d", + 'min' => "Must be greater than %s", + 'max' => "Must be less than %s", + 'in' => "Invalid value", + 'notIn' => "Invalid value", + 'ip' => "Invalid IP address", + 'email' => "Inalid email address", + 'url' => "Inalid URL", + 'urlActive' => "Must be active domain", + 'alpha' => "Must contain only leters a-z", + 'alphaNum' => "Must contain only leters a-z and/or numbers 0-9", + 'slug' => "Must contain only leters a-z, numbers 0-9, dashes and underscores", + 'regex' => "Invalid format", + 'date' => "Invalid date", + 'dateFormat' => "Must be date with format '%s'", + 'dateBefore' => "Must be date before '%s'", + 'dateAfter' => "Must be date after '%s'" +); + diff --git a/src/Valitron/Validator.php b/src/Valitron/Validator.php index c98dbb2..4cf95a2 100644 --- a/src/Valitron/Validator.php +++ b/src/Valitron/Validator.php @@ -15,13 +15,17 @@ class Validator protected $_fields = array(); protected $_errors = array(); protected $_validations = array(); + + protected static $_lang; + protected static $_langDir; protected static $_rules = array(); + protected static $_ruleMessages = array(); /** * Setup validation */ - public function __construct($data, $fields = array()) + public function __construct($data, $fields = array(), $lang = 'en', $langDir = null) { // Allows filtering of used input fields against optional second array of field names allowed // This is useful for limiting raw $_POST or $_GET data to only known fields @@ -30,12 +34,50 @@ class Validator $this->_fields[$field] = $value; } } + + // Only load language files if language or directory has changed + if($lang !== static::$_lang || $langDir !== static::$_langDir) { + // Set language directory for loading language files + if($langDir === null) { + $langDir = dirname(dirname(__DIR__)) . '/lang'; + } + static::langDir($langDir); + + // Set language for error messages + static::lang($lang); + } + } + + /** + * Get/set language to use for validation messages + */ + public static function lang($lang = null) + { + if($lang !== null) { + static::$_lang = $lang; + + // Load language file in directory + $langDir = static::langDir(); + static::$_ruleMessages = require rtrim($langDir, '/') . '/' . $lang . '.php'; + } + return static::$_lang; + } + + /** + * Get/set language file path + */ + public static function langDir($dir = null) + { + if($dir !== null) { + static::$_langDir = $dir; + } + return static::$_langDir; } /** * Required field validator */ - public function validateRequired($field, $value) + protected function validateRequired($field, $value) { if(is_null($value)) { return false; @@ -278,7 +320,7 @@ class Validator * @param mixed $value * @return bool */ - protected function validateAlphaDash($field, $value) + protected function validateSlug($field, $value) { return preg_match('/^([-a-z0-9_-])+$/i', $value); } @@ -355,7 +397,7 @@ class Validator /** * Get array of fields and data */ - public function data($field = null) + public function data() { return $this->_fields; } @@ -374,10 +416,18 @@ class Validator /** * Add an error to error messages array */ - public function error($field, $msg) + public function error($field, $msg, array $params = array()) { - // Add to error array - $this->_errors[$field][] = sprintf($msg, $field); + $this->_errors[$field][] = vsprintf($msg, $params); + } + + /** + * Specify validation message to use for error for the last validation rule + */ + public function message($msg) + { + $this->_validations[count($this->_validations)-1]['message'] = $msg; + return $this; } /** @@ -410,13 +460,11 @@ class Validator $result = call_user_func($callback, $field, $value, $v['params']); if(!$result) { - $this->error($field, $v['message']); + $this->error($field, $v['message'], $v['params']); } } } - $result = count($this->errors()) === 0; - $this->reset(); - return $result; + return count($this->errors()) === 0; } /** @@ -443,6 +491,9 @@ class Validator } } + // Ensure rule has an accompanying message + $message = isset(static::$_ruleMessages[$rule]) ? static::$_ruleMessages[$rule] : 'Invalid'; + // Get any other arguments passed to function $params = array_slice(func_get_args(), 2); @@ -450,7 +501,7 @@ class Validator 'rule' => $rule, 'fields' => (array) $fields, 'params' => (array) $params, - 'message' => null + 'message' => $message ); return $this; } diff --git a/tests/Valitron/Validate.php b/tests/Valitron/Validate.php index 6a79c95..b04ae91 100644 --- a/tests/Valitron/Validate.php +++ b/tests/Valitron/Validate.php @@ -22,6 +22,31 @@ class ValidateTest extends \PHPUnit_Framework_TestCase $this->assertSame(1, count($v->errors('name'))); } + public function testAccurateErrorMessage() + { + $v = new Validator(array()); + $v->required('name'); + $v->validate(); + $this->assertSame(array("Required"), $v->errors('name')); + } + + public function testAccurateErrorMessageParams() + { + $v = new Validator(array('num' => 5)); + $v->min('num', 6); + $v->validate(); + $this->assertSame(array("Must be greater than 6"), $v->errors('num')); + } + + public function testCustomErrorMessage() + { + $v = new Validator(array()); + $v->required('name')->message('Name is required'); + $v->validate(); + $errors = $v->errors('name'); + $this->assertSame('Name is required', $errors[0]); + } + public function testArrayOfFieldsToValidate() { $v = new Validator(array('name' => 'Chester Tester', 'email' => 'chester@tester.com')); @@ -291,14 +316,14 @@ class ValidateTest extends \PHPUnit_Framework_TestCase public function testAlphaDashValid() { $v = new Validator(array('test' => 'abc-123_DEF')); - $v->alphaDash('test'); + $v->slug('test'); $this->assertTrue($v->validate()); } public function testAlphaDashInvalid() { $v = new Validator(array('test' => 'abc-123_DEF $%^')); - $v->rule('alphaDash', 'test'); + $v->rule('slug', 'test'); $this->assertFalse($v->validate()); }