'Please enter the %s', 'email' => 'The %s is not a valid email address', 'less_than' => 'The %s number must be less than %d', 'greater_than' => 'The %s number must be greater than %d', 'number_range' => 'The %s number must be in range of %d to %d', 'min' => 'The %s must have at least %s characters', 'max' => 'The %s must have at most %s characters', 'between' => 'The %s must have between %d and %d characters', 'same' => 'The %s must match with %s', 'alphanumeric' => 'The %s should have only letters and numbers', 'secure' => 'The %s must have between 8 and 64 characters and contain at least one number, one upper case letter, one lower case letter and one special character', 'valid_email_domain' => 'The %s email address is not active', 'valid_domain' => 'The %s domain name is not active', ]; private static function make_arrays(array $data, $field): array { $dataset = []; if (isset($data[$field])) { if (common::get_count($data[$field])) { foreach($data[$field] as $the_data) { $dataset[] = $the_data; } } else { $dataset[] = $data[$field]; } } else { $dataset[] = null; // If field is null, force null set } return $dataset; } public static function validate( array $data, array $fields, array $messages = [] ): array { // Split the array by a separator, trim each element // and return the array $split = fn($str, $separator) => array_map('trim', explode($separator, $str)); // get the message rules $rule_messages = array_filter($messages, fn($message) => is_string($message)); // overwrite the default message $validation_errors = array_merge(self::DEFAULT_VALIDATION_ERRORS, $rule_messages); $errors = []; foreach ($fields as $field => $option) { foreach(self::make_arrays($data, $field) as $index=>$v) { $data[$field] = $v; // Force update on arrays $rules = $split($option, '|'); foreach ($rules as $rule) { // get rule name params $params = []; // if the rule has parameters e.g., min: 1 if (strpos($rule, ':')) { [$rule_name, $param_str] = $split($rule, ':'); $params = $split($param_str, ','); } else { $rule_name = trim($rule); } // by convention, the callback should be is_ e.g.,is_required $fn = 'is_' . $rule_name; $callable = self::class . "::{$fn}"; if (is_callable($callable)) { $pass = $callable($data, $field, ...$params); if (!$pass) { // get the error message for a specific field and rule if exists // otherwise get the error message from the $validation_errors $errors[$field] = sprintf( $messages[$field][$rule_name] ?? $validation_errors[$rule_name], $field, ...$params ); } } } } } return $errors; } private static function is_required(array $data, string $field): bool { if (isset($data[$field])) { if (common::get_count($data[$field])) { return false; // Should not be an array here } if (is_string($data[$field])) { return (trim($data[$field]) !== ''); } if (is_int($data[$field])) { return true; } } return false; } private static function is_email(array $data, string $field): bool { if (empty($data[$field])) { return true; } return filter_var($data[$field], FILTER_VALIDATE_EMAIL); } private static function is_min(array $data, string $field, string $min): bool { if (!isset($data[$field])) { return true; } return mb_strlen($data[$field]) >= intval($min); } private static function is_max(array $data, string $field, string $max): bool { if (!isset($data[$field])) { return true; } return mb_strlen($data[$field]) <= intval($max); } private static function is_greater_than(array $data, string $field, string $min): bool { if (!isset($data[$field])) { return true; } return intval($data[$field]) > intval($min); } private static function is_less_than(array $data, string $field, string $max): bool { if (!isset($data[$field])) { return true; } return intval($data[$field]) < intval($max); } private static function is_number_range(array $data, string $field, string $min, string $max): bool { if (!isset($data[$field])) { return true; } $no = intval($data[$field]); return $no >= intval($min) && $no <= intval($max); } private static function is_between(array $data, string $field, string $min, string $max): bool { if (!isset($data[$field])) { return true; } $len = mb_strlen($data[$field]); return $len >= intval($min) && $len <= intval($max); } private static function is_same(array $data, string $field, string $other): bool { if (isset($data[$field]) && isset($data[$other])) { return $data[$field] === $data[$other]; } return false; } private static function is_alphanumeric(array $data, string $field): bool { if (!isset($data[$field])) { return true; } return ctype_alnum($data[$field]); } private static function is_secure(array $data, string $field): bool { if (!isset($data[$field])) { return false; } // Is 8 to 64 CHRs $pattern = "#.*^(?=.{8,64})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*\W).*$#"; return preg_match($pattern, $data[$field]); } private static function is_valid_email_domain(array $data, string $field): bool { if (!isset($data[$field])) { return false; } $domain = ltrim(stristr($data[$field], '@'), '@') . '.'; return checkdnsrr($domain, 'MX'); } private static function is_valid_domain(array $data, string $field): bool { if (!isset($data[$field])) { return false; } return checkdnsrr($data[$field], 'A') || checkdnsrr($data[$field], 'AAAA') || checkdnsrr($data[$field], 'CNAME'); } } /* $data = ['email'=>'jim@aol.com']; $fields = ['email' => 'required | email']; $errors = \CodeHydrater\validator::validate($data, $fields); print_r($errors); */ /* * 'firstname' => 'required | max:255', 'lastname' => 'required | max: 255', 'address' => 'required | min: 10 | max:255', 'zipcode' => 'between: 5,6', 'username' => 'required | alphanumeric | between: 3,255', 'email' => 'required | email | valid_email_domain', */