How can I make my email code work PHP? - php

Hey this code is suppose to add an error message when an input was not typed on the email form and its suppose to remove the error message when you finally input the code. I have 2 of them working with the following code:
//Generate a unique code
function getUniqueCode($length = "")
{
$code = md5(uniqid(rand(), true));
if ($length != "") return substr($code, 0, $length);
else return $code;
}
//Generate an activation key
function generateActivationToken($gen = null)
{
do
{
$gen = md5(uniqid(mt_rand(), false));
}
while(validateActivationToken($gen));
return $gen;
}
and this code:
//Checks if an email is valid
function isValidEmail($email)
{
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
return true;
}
else {
return false;
}
}
I have made my own code which puts the error messages when there are no inputs on the email form but when I input something right on the email form it does not take the error messages out of the error message box. Here is the code:
//Checks if a name is valid
function isValidName($name)
{
if (filter_var($name, MAIL_NAME_ERROR)) {
return true;
}
else {
return false;
}
}
So to summarize all 5 are working when there is no input like this:
Please enter your full name
Please enter a valid email address
Please enter your telephone number
Please enter your password
Failed security question
But only my security and email are working when I input my email address and security code like this:
Please enter your full name
Please enter your telephone number
Please enter your password
The name, telephone and password are not working right they only work by showing the code but they do not remove the code when I input the right information.
How can I fix my code so that all 3 will go away 1 by 1?

To make your own callback you can't just pass the constant MAIL_NAME_ERROR. If you want to pass your own function you have to do something like:
function mail_name_error(){
//do your thing here
}
function isValidName($name){
if(filter_var($name, FILTER_CALLBACK, array('options' => 'mail_name_error'))){
return true;
}
else {
return false;
}
}
See the options section at http://php.net/manual/en/function.filter-var.php .

Related

Server-side validation not checking the next field in php

I have a login page with two radio button(buyer or seller)
For example, I chose buyer the I will get a login field
Mobile
Password
Or, I chose seller the I will get a login field
Email
Password
I am using the below function for the login code.
function login($pdo){
$account_type=sanitize_data($_POST['account_type']);
$password =sanitize_data($_POST['password']);
if (empty($account_type)) {
$errorMsg= "Please select account type";
$code= "1" ;
}
elseif ($account_type==1) {
$mobileno=sanitize_data($_POST['mobileno']);
if(empty($mobileno)) {
$errorMsg= "Please enter mobile number.";
$code= "2";
}
elseif(is_numeric(trim($mobileno)) == false){
$errorMsg= "Please enter numeric value.";
$code= "2";
}elseif(strlen($mobileno)<10){
$errorMsg= "Number should be ten digits.";
$code= "2";
}
else{
// echo "<pre>";
echo "4";// getting issue here
}
}
elseif ($account_type==2) {
if(empty($email)){
$errorMsg="You did not enter a email.";
$code="2";
} //check for valid email
elseif(filter_var($email, FILTER_VALIDATE_EMAIL) === false){
$errorMsg= "You did not enter a valid email.";
$code="2";
}
else{
}
}
elseif( empty($password)) {
$errorMsg= "Please enter the password";
$code="3";
}
else{
try{
//query here
} catch(PDOExecption $e) {
$dbh->rollback();
print "Error!: " . $e->getMessage() . "</br>";
}
}
}
Now, I am getting issues in nested if condition.
For example, I choose buyer and I added 10 digits mobile number and submitted the form.
According to my code, it should check the server side validation for the field like the password is entered or not. right?
But it stops. I mean if the server-side validation is clear for mobile then it should check the next one but it's not checking.
I mean it's not checking the password. I think my execution is stopped once reach the else part.
elseif ($account_type==1) {
$mobileno=sanitize_data($_POST['mobileno']);
if(empty($mobileno)) {
$errorMsg= "Please enter mobile number.";
$code= "2";
}
elseif(is_numeric(trim($mobileno)) == false){
$errorMsg= "Please enter numeric value.";
$code= "2";
}elseif(strlen($mobileno)<10){
$errorMsg= "Number should be ten digits.";
$code= "2";
}
else{
// echo "<pre>";
echo "4"; // getting issue here
}
}
are the right way to use the code for login and server-side validation?
Actually, it's the outer clause that causes your issues. It reads like this:
if (empty($account_type)) {
// We don't have an account type.
}
elseif ($account_type==1) {
// Account type is '1'. Proceed in here.
}
elseif ($account_type==2) {
// Account type is '2'.
}
elseif(empty($password)) {
// We don't have a password.
}
else {
// We have a password and an account type,
// and it's neither 1 nor 2.
try {
...
} catch(PDOExecption $e) {
...
}
}
I'd suggest splitting your if chains - to be able to do this, though, you might also need to re-structure your sanitation, validation and error handling.
Wrapping your logic in a class might be worth a thought, for example:
// Mock db
class DbConnection {}
class Login {
/**
* #var Array
*/
protected $error;
/**
* #var Array
*/
protected $data;
/**
* #var DbConnection
*/
protected $db;
/**
* Mock sanitizing
*/
protected function sanitize(array $data): array {
return $data;
}
protected function validate(): bool {
// In our sanitize() method, we already made sure
// that everything we need is set, so we don't have
// to do it here.
$account_type = $this->data['account_type'];
$password = $this->data['password'];
// Return early if we don't have an account type or
// a password.
if (!$account_type) {
$this->error = [1, 'Please select account type'];
return false;
}
if(!$password) {
$this->error = [3, 'Please provide a password'];
return false;
}
if ($account_type == 1) {
$mobileno = $this->data['mobileno'];
// We might already have stripped everything that's not a number
// from our mobile number string when sanitizing it, so we already
// made sure it's either empty or numeric.
//
// To validate it, we could either use a regex, or one of the PHP
// ports of Google's libphonenumber library:
// - https://stackoverflow.com/questions/123559/how-to-validate-phone-numbers-using-regex
// - https://stackoverflow.com/questions/22378736/regex-for-mobile-number-validation/
// - https://github.com/giggsey/libphonenumber-for-php
//
// Let's assume we already used one of those methods, so the value of
// $mobileno would be either valid or false.
if (!$mobileno) {
$this->error = [2, 'Please enter a valid mobile number'];
return false;
}
return true;
}
if ($account_type==2) {
// Some validation logic. If nothing fails, we'll finally return true.
return true;
}
}
/**
* #return Mixed - Boolean|User (object, array...)
*/
public function login() {
if (!$this->validate()) {
return false;
}
$password = $this->data['password'];
try {
// Query db for password (and maybe a username, too)
return ['User' => '...'];
}
catch(PDOExecption $e) {
// Exception handling;
}
}
public function getError() {
return $this->error;
}
public function __construct(array $data, DbConnection $db) {
$this->data = $this->sanitize($data);
$this->db = $db;
}
}
You're login process would then be:
// Mock POST data
$_POST = [
'account_type' => '1',
'password' => 'PwG2c?4tyUzEtD!9',
'mobileno' => '012345678986'
];
// Evaluate login attempt
$attempt = new Login($_POST, new DbConnection());
$user = $attempt->login();
if (!$user) {
var_dump($attempt->getError());
}
else {
var_dump($user);
}
Sources used:
How to validate phone numbers using regex
Regex for Mobile Number Validation
https://github.com/giggsey/libphonenumber-for-php

Registration with restricted email domain, PHP validation

I have this line of code that I want to apply to a login page. I want to restrict the login for only user with certain domain name like "#mycompany.com" no other user can register without having this domain.
But the problem is that I can't get it to work, it passes all domains I have tried and does not return to false
The codes are copied and paste from two different forumpages, one that has no rules for domains and the second code with rules for restricted domains ( from line "//validate tld")that I pasted in and edited. Where does it go wrong, at the moment I can't see where?
public static function validateUserEmail($user_email, $user_email_repeat)
{
if (empty($user_email)) {
Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_FIELD_EMPTY'));
return false;
}
if ($user_email !== $user_email_repeat)
{
Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_REPEAT_WRONG'));
return false;
}
// validate the email with PHP's internal filter
// side-fact: Max length seems to be 254 chars
// #see http://stackoverflow.com/questions/386294/what-is-the-maximum-length-of-a-valid-email-address
if (!filter_var($user_email, FILTER_VALIDATE_EMAIL)) {
//validate tld
$validTlds = str_replace(".", "\.", VALID_EMAIL_TLDS);
$validTlds = "\.".str_replace(",", "|\.", $validTlds);
//$validTlds = str_replace(",", "|\.", $validTlds);
$emailArr = explode("#", $user_email);
$emailTld = $emailArr[1];
if ($emailTld !== 'mycompany.com')
{
Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_DOES_NOT_FIT_DOMAIN'));
return false;
}
if (!preg_match('/^[-a-z0-9]+('.$validTlds.')\z/', strtolower($emailTld))) {
//check main domain here
$exValidTlds = explode(",", VALID_EMAIL_TLDS);
$exValidTlds = array_map('trim', $exValidTlds);
foreach($exValidTlds as $tld) {//if exist then
if(!strstr($emailTld, ".".$tld)) {
if($tld !== strrchr($emailTld, $tld)) {
Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_DOES_NOT_FIT_PATTERN'));
return false;
}
}
}
Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_DOES_NOT_FIT_PATTERN'));
return false;
}
}
return true;
}
This is the original code I started with and the validation of domain I added in later. All this validation domain code seems to be ignored...
public static function validateUserEmail($user_email, $user_email_repeat)
{
if (empty($user_email)) {
Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_FIELD_EMPTY'));
return false;
}
if ($user_email !== $user_email_repeat) {
Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_REPEAT_WRONG'));
return false;
}
// validate the email with PHP's internal filter
// side-fact: Max length seems to be 254 chars
// #see http://stackoverflow.com/questions/386294/what-is-the-maximum-length-of-a-valid-email-address
if (!filter_var($user_email, FILTER_VALIDATE_EMAIL)) {
Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_DOES_NOT_FIT_PATTERN'));
return false;
}
return true;
}
EDIT...
I finally made it to work and this is how, so far it is working for me... The goal is that I don't want other people outside the organisation to be able to log in to the website.
if (filter_var($user_email, FILTER_VALIDATE_EMAIL)) {
$server = strstr($user_email, '#');
if ($server !== '#mycompany.com') {
Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_DOES_NOT_FIT_PATTERN'));
return false;
}
}
Your not operator is on the wrong side of the variable. It should be like this...
if ($emailTld !== 'mycompany.com')

Password and verification is true altough one of them is not set.

i have some function for checking password is required and compare it with verification here's my function:
public function required($field= array())
{
foreach($field as $value) {
if (isset($this->_input[$value])) {
if (empty(Security::clean($this->_input[$value]))) {
$messages = "is Required.";
error::inputError($value, $messages);
}
} else{
$messages = "Not Found.";
error::inputError($field, $messages);
}
}
}
public function password($field, $confirmasion){
if (isset($this->_input[$field] , $this->_input[$confirmasion])){
if ($this->_input[$field] != $this->_input[$confirmasion])
{
$messages = "is different with $confirmasion.";
error::inputError($field, $messages);
error::inputError($confirmasion, $messages);
}
}
}
In my class $this->_input refers to $_POST. and then i have a class to set an error like this:
public static function inputError($field, $messages)
{
if (is_array($field)) {
foreach ($field as $key){
$newName = General::changeName($key);
$messagesError = "$newName $messages";
if (isset(self::$_errors[$key])){
return;
}else{
self::$_errors[$key] = $messagesError;
}
}
}else{
$newName = General::changeName($field);
$messagesError = "$newName $messages";
if (isset(self::$_errors[$field])){
return;
}else{
self::$_errors[$field] = $messagesError;
}
}
}
i'm expecting when when i submit form and my password and verification fields is empty it display "password is required" or "verification is required" only without showing error "password is different from verification”. but when i'm only fill my password fields it showing “verification is required“ and the second error "password is different different from verification” because my verification is still empty. Is it something wrong with my logic or something?
isset($this->_input['fieldname'])
this code will return true. Hence, having the verification field empty will still compare it to the password field.here's the solution:
(!empty($this->_input[$field]) && !empty($this->_input[$confirmasion]))

the best approach to giving an error message when validating

I am a new programmer and am attempting to do some validation for a basic registration form. I have built a basic registration form that sends the user back to the same page when submitted. I have also created a user class and have created some basic validation functions. However, the functions have the error messages built into them. I obviously put the functions on the top of the registration form so when there is an error the errors are posted on the registration form. However, I have no control on how the error messages look and would like to know if there is a lot better way to somehow echo the error messages from outside the class so I can use some type of css or something else for better control of how they look. I hope that makes sense. Also when there is an error the user is sent back to an empty registration form. I was trying to figure out how to keep the valid information in the text boxes and just make them redo the invalid information. Here is a basic example of a validation I have done. I know its basic but I am very new to programming
function validate_password($password)
{
$valid = TRUE;
if ($password == '')
{
echo "<p> Please enter a value for the password </p>";
$valid = FALSE;
}
elseif($_POST['pwd'] !== $_POST['pwd2'])
{
echo "The passwords do not match please try again";
$valid = FALSE;
}
return $valid;
}
Don't echo them right away, instead store them for later use. You mentioned this is inside a class, so you can use a class property to hold error messages.
class YourClass
{
public $error;
function validate_password($password)
{
$valid = TRUE;
if ($password == '')
{
// Set the error message
$this->error = "Please enter a value for the password";
$valid = FALSE;
}
// etc...
}
}
Later, when you need to, you can output it in the HTML:
if (!empty($yourclass->error)) {
echo "<p class='errmsg'>{$yourclass->error}</p>\n";
}
You then just need a CSS class errmsg and you can style it how you like:
.errmsg {
color: #FF0000;
font-size: 36px;
}
Now if you have that working, you can expand it further to make the $error class property into an array and push multiple messages onto it:
// In the class, initialize it as an array
$this->error = array();
// Use the [] notation to append messages to the array.
$this->error[] = "Another error message..."
$this->error[] = "And yet another error message..."
In your presentation code, use a loop to output the messages:
// Output a big stack of error messages...
foreach ($yourclass->error as $err) {
echo "<p class='errmsg'>$err</p>\n";
}
What I normally do with classes and their errors is have a variable specifically for the errors.
So something like:
class User
{
private $_ValidationErrors = array();
function validate_password($password)
{
$this->_ValidationErrors = array();
$valid = TRUE;
if ($password == '')
{
$this->_ValidationErrors[] = "Please enter a value for the password";
$valid = FALSE;
}
elseif($_POST['pwd'] !== $_POST['pwd2'])
{
$this->_ValidationErrors[] = "The passwords do not match please try again";
$valid = FALSE;
}
return $valid;
}
function ValidationErrors ()
{
if (count($this->_ValidationErrors) == 0)
return FALSE;
return $this->_ValidationErrors;
}
}
Then to use:
$user = new User();
if (!$user->validate_password('somepass'))
echo implode('<BR>',$user->ValidationErrors ());
EDIT: To display errors by the user something like:
<?php
if (isset($_POST["submit"]))
{
$user = new User();
$passwordErrors = (!$user->validate_password($_POST["pass1"]))?$user->ValidationErrors():array();
}
?>
<form action="<?php echo $_SERVER["php_self"]; ?>" method="post">
<input type="text" name="pass1" value="<?php echo htmlspecialchars($_POST["pass1"]); ?>" /><BR/>
<?php
echo ((isset($passwordErrors) && count($passwordErrors) == 0)?"":implode("<BR/>", $passwordErrors));
?>
<input type="submit" name="submit" value="Register" />
</form>

More professional error handling

I have a contact form and I handle errors by checking each field one-by-one with an "if" statement. I find this hard and I can't seem to find a better/more productive way to get them working. I would also like a heading saying "Error" if one (or more) is true. But I cant get them to work with the separate "if" statements.
Here is my code:
$name = $_POST['name']; //get data from the form
$email = $_POST['email'];//get data from the form
$message = $_POST['message'];//get data from the form
if($name == ""){
echo"<p class='error'>Please enter a name.</p>";
}
if (!eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$",$email)){
echo "<p class='error'>Your email address is not valid.</p>";
}
if($message == ""){
echo"<p class='error'>Please enter a message.</p>";
}
else{
echo"all ok, send email code...";
}
Edit: These errors are for the validation of the form.
But I cant get them to work with the separate "if" statements.
Just store error in a variable
$error = array();
if($name == ""){
$error[] = "Please enter a name.";
}
if (!eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$",$email)){
$error[] = "Your email address is not valid.";
}
if($message == ""){
$error[] = "Please enter a message.";
}
if (!$error) {
// do not echo anything here
// but send an email
// and use header("Location:") to redirect a user to thanks page
} else {
echo "Error";
foreach ($error as $line) {
echo "<p class='error'>$line</p>";
}
}
You are looking for validator class. Also see:
Building An Extensible Form Validator Class
The most professional way would be to have each field be an object with a validation method.
Then you can call each field object and ask them to validate themself.
If you would like to go any further (might be overkill though) you put your objects in a list.
Each of these objects are child to an interface with the validation method. So for each object in the list, you call the validation method.
Well, you can't check all fields together as different rules may apply to each one. So what you are doing is fine, except for a mistake you made: The else part should only be echoed, when no error occurred, but in your situation the else only applies to the last if. So even if the validation of name and email fails, as long as the message one does not, the final action is done.
You could easily add some $has_error variable that contains true as soon as an error was found. Or you could use an array that holds all error messages like this:
$errors = array();
if ( empty( $name ) )
$errors[] = 'Please enter a name.';
if ( !eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $email ) )
$errors[] ='Your email address is not valid.';
if ( empty( $message ) )
$errors[] = 'Please enter a message.';
// individual checks done
if ( sizeof( $errors ) > 0 )
{
echo '<p class="error"><strong>Errors found:</strong><br />';
echo implode( '<br />', $errors );
echo '</p>';
}
else
{
echo 'No error, everything is fine.';
}
First, don't use ereg*() functions for regular expressions matching, these are deprecated and slow. Use the preg_*() functions instead.
Also take a look at PHP's filter extension.
It provides functions to check and validate various data which you can use directly or incorporate into your own validator functions.
EDIT: Example for checking an e-mail address (see also examples on php.net):
if ( !filter_var($email, FILTER_VALIDATE_EMAIL) ) {
echo 'Invalid e-mail "'.$email.'"';
Speaking of validation in an object-oriented manner, you could have a generic validator class with basic validation functions (where you could also integrate filter functions for a consistent API).
Additionally, if your data logically belongs together such that you can group them into objects and manage them as such, implement a validate() method in the classes of these objects that checks the object's properties by utilizing the filter functions and/or your validator class.
class Message {
private $name;
private $email;
private $text;
...
public function getName() {
return $this->name;
}
public function setName($name) {
$this->name = $name;
}
public function getEMail() {
return $this->email;
}
public function setEMail($email) {
$this->email = $email;
}
...
public function validate() {
$errors = array();
$nameLength = strlen($this->name);
if ( ($nameLength === 0) or ($nameLength > self::NAME_MAX_LENGTH) )
$errors['name'] = 'Name must be between 1 and '.self::NAME_MAX_LENGTH.' characters.';
if ( !Validator::isEMail($this->email) )
$errors['email'] = 'Invalid e-mail "'.$this->email.'"';
// Other checks
...
// Return TRUE if successful, otherwise array of errors
return ( count($errors) === 0 ? true : $errors );
}
}
Then, you could load all your form inputs into your object like this:
$message = new Message();
$message->setName($_POST['name']);
$message->setEMail($_POST['email']);
$message->setText($_POST['text']);
...
$result = $message->validate();
if ( $result === true ) {
// Success
} else {
// Error
foreach ($result as $validationError) {
// Print error
echo htmlentities($validationError).'<br />';
}
}

Categories