Currently I'm trying to validate an email address via OOP php with arrays so I can add additional functions later, however when I insert a valid email address the validation still fails, I think perhaps my arrays are set up wrong but I'm not entirely sure, additionally I had tried different different operators to check if the email function would output different results however as mentioned it always seems to fail, any advice would be appreciated
class Login
{
private
$email,
$password,
$database,
$db = null;
public function __construct()
{
$this->db = new Database;
}
public function validEmail($email)
{
return (filter_var($email, FILTER_VALIDATE_EMAIL) !== FALSE);
}
}
<?php
require "classes/Login.class.php";
$validate = new Login();
require "loadclasses.php";
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$email = $pass = "";
$post = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
$email = $post['email-login'];
$pass = $post['password-login'];
$errors = array();
$fields = array(
'email-login' => array(
'validate' => 'validEmail',
'message' => 'Enter a valid email address'
)
);
foreach($fields as $key => $value)
{
if(isset($fields[$key]))
{
$errors[] = ['name' => $key, 'error' => $fields[$key]['message']];
}
}
if(empty($errors))
{
$success = ['response' => 'true'];
session_start();
}
}
header('Content-Type: application/json');
if (empty($errors))
{
echo json_encode($success);
}
else
{
echo json_encode(["errors" => $errors]);
}
As already mentioned in comments - you don't use functions from your Login class.
So, how you current code works:
$fields = array(
'email-login' => array(
'validate' => 'validEmail',
'message' => 'Enter a valid email address'
)
);
foreach($fields as $key => $value)
{
// isset($fields[$key]) is ALWAYS true
if(isset($fields[$key]))
{
$errors[] = ['name' => $key, 'error' => $fields[$key]['message']];
}
}
What you really should do is something like:
$fields = array(
'email-login' => array(
'validate' => 'validEmail',
'message' => 'Enter a valid email address'
)
);
// instantiate object of Login class
$login = new Login();
foreach($fields as $key => $value)
{
// call a function `$value['validate']` (it is `validEmail`)
$validation_result = $login->{$value['validate']}($email);
// if validation fails - add error message
if(!$validation_result)
{
$errors[] = ['name' => $key, 'error' => $value['message']];
}
}
And btw $post is a wrong variable name, I suppose it is $_POST.
Related
$data = array(
array(
'username' => 'bharatbhai#gmail.com',
'password' => '12345'
),
array(
'username' => 'test#gmail.com',
'password' => '8520'
),
array(
'username' =>'abc#gmail.com',
'password' => '123123'
)
);
and my condition is here
my task is only match one username to one password
but i got error
$check_email = false;
if(array_search($email,array_column($data,'username')) !== FALSE){
$check_email = true;
}
$check_pass = false;
if(array_search($password,array_column($data,'password')) !== FALSE){
$check_pass = true;
}
if(!empty($check_email) && !empty($check_pass)){
echo "<h2>Email and Password matched</h2>";
}
else{
echo '<h2>Oh no email and password not matched.</h2>';
i am match my condition using array_column funcation.
You need to update your logic which checks if both username and password are same in each sub array. I made quick logic you should apply to your code.
<?php
$email = "bharatbhai#gmail.com";
$password = "12345";
$data = array(
array(
'username' => 'bharatbhai#gmail.com',
'password' => '12345'
),
array(
'username' => 'test#gmail.com',
'password' => '8520'
),
array(
'username' =>'abc#gmail.com',
'password' => '123123'
)
);
$hasSameMailAndPass = false;
foreach($data as $key => $value){
if($value["username"] == $email and $value["password"] == $password){
$hasSameMailAndPass = true;
}
}
if($hasSameMailAndPass){
echo "<h2>Email and Password matched</h2>";
} else {
echo '<h2>Oh no email and password not matched.</h2>';
}
?>
I think you can perform a multilevel conditional check.
Actually it seems you search the existancce of the email and of the password, but not actually for the same user.
Does this email exits? yes or no?
does this passwrod exists? yes or no?
Actually should be the following:
does this email exists? yesr or no?
if yes, does that email fit with this password? yes or no?
So you could check if a user exists and has right credentials
$data = array(
array(
'username' => 'bharatbhai#gmail.com',
'password' => '12345'
),
array(
'username' => 'test#gmail.com',
'password' => '8520'
),
array(
'username' =>'abc#gmail.com',
'password' => '123123'
)
);
/**
* #param array $login array('email'=> 'loginemail', 'password'=> 'loginpwd')
* #return bool
*/
function canBeAuthenticate(array $data, array $login)
{
$hasMail = false;
$userIndex = null;
# check if email exists in system
# if not, not even check pwd and return false
# if exites, get ID of user and then check pwd
foreach ($users as $index => $userData) {
if ( $userData == $login['email'] ) {
$hasMail = true;
$userIndex = $index;
}
}
if (!$hasMail) {
echo 'Email not in system';
return false;
}
if ($data[$userIndex]['password'] == $login['password']) {
echo 'Match';
return true;
}
echo 'wrong password';
return false;
}
Basically I'm trying to create a login, the email validation doesn't seem to pass. I've been looking around for an example but I'm genuinely not sure, doing it statically seems easy enough, however I vaguely suspect using static method would be incorrect to use as a login method(perhaps I'm over thinking it)
<?php
require ("Database.class.php");
class Login
{
private
$email,
$password,
$database,
$db = null;
public function __construct()
{
$this->db = new Database;
}
public function validEmail($email)
{
return (filter_var($email, FILTER_VALIDATE_EMAIL) !== FALSE);
}
public function emptyPassword($password)
{
return(empty($password) !== TRUE);
}
public function validPassword($password)
{
$query = $this->db->prepare("select * from username");
return $query->fetch(PDO::FETCH_ASSOC);
}
}
<?php
require "classes/Login.class.php";
require "loadclasses.php";
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$email = $pass = "";
$post = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
$email = $post['email-login'];
$pass = $post['password-login'];
$errors = array();
$fields = array(
'email-login' => array(
'validate' => 'validEmail',
'message' => 'Enter a valid email address'
),
'password-login' => array(
'validate' => 'emptyPassword',
'message' => 'Password required'
)
);
$login = new Login();
foreach($fields as $key => $value)
{
$validation_result = $login->$value['validate']($value);
if(!$validation_result)
{
$errors[] = ['name' => $key, 'error' => $value['message']];
}
}
if(empty($errors))
{
$success = ['response' => 'true'];
session_start();
}
}
header('Content-Type: application/json');
if (empty($errors))
{
echo json_encode($success);
}
else
{
echo json_encode(["errors" => $errors]);
}
As mentioned I'm aware I could do something similar to this:
$errors = array();
$fields = array(
'username' => array(
'validator' => 'validateUsername',
'message' => 'Username must be between three and fourteen alphanumeric characters'
),
'email' => array(
'validator' => 'validateEmail',
'message' => 'Please enter a valid email',
),
'password' => array(
'validator' => 'validatePassword',
'message' => 'Password must be a minimum of seven characters'
)
);
if(!Validation::validateRepeatPassword($password, $repeatPassword))
{
$errors[] = ["name" => "repeatPassword", "error" => "Passwords must match"];
}
foreach($post as $key => $value)
{
if(isset($fields[$key]))
{
if(!Validation::{$fields[$key]['validator']}($value))
{
$errors[] = ['name' => $key, 'error' => $fields[$key]['message']];
}
}
}
The main problem as I mentioned is I'm fairly sure that would be the wrong way to approach this problem
The problem seems to be here:
$validation_result = $login->$value['validate']($value);
When you do that, you're actually passing $value which is an array (according to the foreach). You're not actually passing the email
So, according to your code, you should change your validation array to something like:
$fields = array(
'email-login' => array(
'validate' => 'validEmail',
'message' => 'Enter a valid email address',
'value' => $email,
),
'password-login' => array(
'validate' => 'emptyPassword',
'message' => 'Password required',
'value' => $pass,
)
);
And then, change your validation line to:
$validation_result = $login->$value['validate']($value['value']);
I know this question has been asked here a ton of times and I have seen the answers, but none of them solves my problem.
I have two REST API's Controllers and in both of them, the form_validation always returns false. When I comment out the validation section, both my controllers work fine.
This is my code.
The first controller is used for registration.
class ApiController extends REST_Controller{
public function create_password($password){
return hash("sha256", $password);
}
public function data_post(){
$this->form_validation->set_rules(
'username','User Name','trim|required|min_length[5]|max_length[30]|is_unique[users.user_name]|xss_clean');
$this->form_validation->set_rules('firstname','First Name','trim|required|alpha|min_lenght[3]|max_length[30]|xss_clean');
$this->form_validation->set_rules('lastname','Last Name','trim|required|alpha|min_lenght[3]|max_length[30]|xss_clean');
$this->form_validation->set_rules('email','Email','trim|required|valid_email|is_unique[users.user_email]');
$this->form_validation->set_rules('password','Password','trim|required');
$this->form_validation->set_rules('cpassword','Confirm Password','trim|required|matches[password]');
$this->form_validation->set_rules('gender','Gender','required');
$this->form_validation->set_rules('dob','Date of Birth','required');
$this->form_validation->set_rules('phone','Mobile Number','required');
if($this->form_validation->run() === FALSE){
$errors = validation_errors();
$message = array(
'status' => FALSE,
'message' => $errors
);
//$this->response($message, REST_Controller::HTTP_NOT_ACCEPTABLE);
echo validation_errors();
return;
}
$userpass = $this->create_password($this->post('password'));
$data = array('user_name'=>$this->post('username'),
'first_name'=>$this->post('firstname'),
'last_name'=>$this->post('lastname'),
'user_email'=>$this->post('email'),
'password'=>$userpass,
'date_of_birth'=> $this->post('dob'),
'mobile_phone' => $this->post('phone'),
'user_gender' => $this->post('gender')
);
$recordEntered = $this->mainModel->insert($data);
$message = '';
if($recordEntered == 1){
$message = array(
'status' => TRUE,
'message' => 'Data Inserted Successfully'
);
}
$this->response($message, REST_Controller::HTTP_CREATED);
}
And this is the 2nd Controller, used for login
class Authentication extends REST_Controller{
function index_post(){
$this->form_validation->set_rules('username','User Name','trim|required|max_length[30]|xss_clean');
$this->form_validation->set_rules('password','Password','trim|required');
if($this->form_validation->run() === false){
$errors = validation_errors();
$message = array(
'status' => FALSE,
'message' => $errors
);
$this->response($message, REST_Controller::HTTP_NOT_ACCEPTABLE);
return;
}
$username = $this->post('username');
$password = $this->create_password($this->post('password'));
$message = '';
if($this->verify_user($username, $password)){
$data = array(
'email' => $this->post('username'),
'is_logged_in' => 1
);
$this->session->set_userdata($data);
$message = array(
'status' => TRUE,
'message' => 'Log In Successful'
);
$this->response($message, REST_Controller::HTTP_OK);
}
else{
$message = array(
'status' => FALSE,
'message' => 'Invalid Email/Username or Password'
);
$this->response($message, REST_Controller::HTTP_NOT_FOUND);
}
}
public function verify_user($username, $password){
if($this->mainModel->getUser($username, $password)){
return true;
}
else{
return false;
}
}
public function create_password($password){
return hash("sha256", $password);
}
}
I am relatively new to Codeigniter and I am under a deadline which expires today.
Any help would be greatly appreciated.
First Change :
Sometimes you may want to validate an array that does not originate from $_POST data.
In this case, you can specify the array to be validated:
$data = array(
'username' => 'johndoe',
'password' => 'mypassword',
'passconf' => 'mypassword'
);
$this->form_validation->set_data($data);
Creating validation rules, running the validation, and retrieving error messages works the same whether you are validating $_POST data or another array of your choice.
You have to call the set_data() method before defining any validation rules.
see this link :
https://www.codeigniter.com/user_guide/libraries/form_validation.html#validating-an-array-other-than-post
Second Change :
In ApiController controller
Please remove xss_clean from the set_rules. xss_clean is not a native rule
$this->form_validation->set_rules('username','User Name','trim|required|min_length[5]|max_length[30]|is_unique[users.user_name]');
$this->form_validation->set_rules('firstname','First Name','trim|required|alpha|min_lenght[3]|max_length[30]');
$this->form_validation->set_rules('lastname','Last Name','trim|required|alpha|min_lenght[3]|max_length[30]');
AND Also from
In Authentication controller
$this->form_validation->set_rules('username','User Name','trim|required|max_length[30]');
Please read this for the reference :
https://www.codeigniter.com/user_guide/libraries/form_validation.html#rule-reference
For security helper ( xss_clean )
https://www.codeigniter.com/user_guide/helpers/security_helper.html
removing the xss_clean makes my code works perfectly
I'm trying to validate a form in the actual form itself, but it doesn't get validated at all. If I type "someemail&*!([]#gmail.com", it doesn't really give a crap and moves on.
Form:
class RecoverPasswordForm extends Form {
public function __construct($options = null) {
parent::__construct("RecoverPassword");
$username = new Element("username");
$username->setLabel("Email");
$username->setAttributes(
array('filters' => array(
array('name' => 'StringTrim'),
array('name' => 'StripTags')),
'validators' => array(
array(
'name' => 'Regex',
'options' => array(
'pattern' => '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/',
'messages' => array(
Regex::NOT_MATCH => 'The email your provided has invalid characters.',
),
),
'break_chain_on_failure' => true
),
array(
'name' => 'EmailAddress',
'options' => array(
'messages' => array(
EmailAddress::INVALID_FORMAT => "Email address is invalid",
EmailAddress::INVALID => "",
EmailAddress::INVALID_LOCAL_PART => "",
EmailAddress::INVALID_HOSTNAME => "",
EmailAddress::INVALID_SEGMENT => "",
EmailAddress::DOT_ATOM => "",
EmailAddress::INVALID_MX_RECORD => "",
),
),
),
),
'label' => 'Email'));
$this->add(array(
$username,
));
}
}
How I'm getting (or trying to get) the filters and validators in the controller:
public function recoverPasswordAction() {
$this->cache = new Container("cache");
$request = $this->getRequest();
$form = new RecoverPasswordForm();
// $form->get("submit")->setValue("Send mail");
$this->view->form = $form;
if ($request->isPost()) {
$user = new User();
$form->getInputFilter()->getValues();
$form->setInputFilter($form->getInputFilter());
$data = $request->getPost();
$form->setData($data);
$username = $data['username'];
$userData = $this->getServiceLocator()->get("UserTable")->fetchList("`username` LIKE '$username'");
if (!count($userData) > 0) {
$this->cache->error = "A user with this email does not exist, plese try again.";
}
if ($form->isValid()) {
foreach ($userData as $user) {
$user->sendMail(6);
$this->cache->success = "A message has been send to this email, containing your password.";
}
}
}
return $this->view;
}
Try like this...
$request = $this->getRequest();
$form = new Form();
if($request->isPost()) {
if($form->isValid($reguest->getPost())) {
$values = $form->getValues(); //filtered valid array of values
$username = $form->getValue('username');
}
}
$this->view->form = $form;
I think it's because of wrong implementation of validators.
Could you try to implement InputProviderInterface on your form? Basic example is given in the docs. There it is set on an Element, but you can do this on your form too. This interface define getInputSpecification where you have to return an array with filter and validator specification.
I'm trying to customize a php script to make it adapted to my needs.
Here's the code :
<?php
if (isset($_POST['email']))
{
$error = '';
$name = $_POST['name'];
$email = $_POST['email'];
if($name=='' || $email=='')
{
$error = 'Name and email are mandatory';
}
if ($error == '')
{
$custom_field1 = $_POST['custom_field1'];
$custom_field2 = $_POST['custom_field2'];
$custom_field3 = $_POST['custom_field3'];
$boolean = 'true';
$postdata = http_build_query(
array(
'name' => $name,
'email' => $email,
'custom_field1' => $custom_field1,
'custom_field2' => $custom_field2,
'custom_field3' => $custom_field3,
'list' => $list,
'boolean' => 'true'
)
);
$opts = array('http' => array('method' => 'POST', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => $postdata));
$context = stream_context_create($opts);
$result = file_get_contents($app_url.'/signin', false, $context);
if ($result != 1)
$error = $result;
}
}
?>
By default the name and the email are the two mandatory fields, i would like the custom fields 1 & 2 to be mandatory as well.
I'd also like the error message to be specific to the missing field(s).
With the current code, even if the name is filled, the message says :
Name and email are mandatory
Thanks
try this:
$name = $_POST['name'];
$email = $_POST['email'];
$custom_field1 = $_POST['custom_field1'];
$custom_field2 = $_POST['custom_field2'];
$error = array();
if($name=='')
{
$error[] = 'Name are mandatory';
}
if($email == '')
{
$error[] = 'Email are mandatory';
}
if($custom_field1 == '')
{
$error[] = 'Custom field 1 is mandatory';
}
if($custom_field2 == '')
{
$error[] = 'Custom field 2 is mandatory';
}
if (!empty($error))
{
$custom_field3 = $_POST['custom_field3'];
$boolean = 'true';
$postdata = http_build_query(
array(
'name' => $name,
'email' => $email,
'custom_field1' => $custom_field1,
'custom_field2' => $custom_field2,
'custom_field3' => $custom_field3,
'list' => $list,
'boolean' => 'true'
)
);
$opts = array('http' => array('method' => 'POST', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => $postdata));
$context = stream_context_create($opts);
$result = file_get_contents($app_url.'/signin', false, $context);
if ($result != 1)
$error[] = $result;
}
}
When you displaying the error messages, make a loop in $error array
foreach ($error as $errstr)
{
echo "<p>{$errstr}</p>";
}
or implode to string and echoes like
echo "<p>" . implode("</p><p>", $error) . "</p>";
This block says if name is empty || (or) email is empty the error is "Name and email are mandatory".
if($name=='' || $email=='') {
$error = 'Name and email are mandatory';
}
If you would like to create seperate error messages, just follow this pattern. I'm sure you will figure it out if you give it a try.
You can make an if statement with a custom error for each field you'd like to check:
if ($name == '')
{
$error = 'Name is mandatory';
}
You can repeat this pattern for each field you'd like to check. You will need to assign $custom_field1 and $custom_field2 before you do this check (your script is doing this on the two lines after it checks to make sure $error is empty).
You may want to read through the PHP manual about variables and the if statement.
The most simple solution would be to create an array with the required fields and loop though them. This enables you to both check mandatory fields in a flexible way and have error messages for individual fields:
// required fields
$required = [
'name' => 'Name',
'email' => 'Emailaddress',
'custom_field1' => 'My awesome field 1',
'custom_field2' => 'My awesome field 2',
];
// list of errors
$errors = [];
if (isset($_POST['email'])) {
// loop through required fields
foreach ($required as $key => $name) {
if ($_POST[$key] !== '') {
continue;
}
$errors[$key] = $name . ' is required';
}
}
// check if there were errors
if (!empty($errors)) {
// display errors
}
The advantage of this solution is that you can easily add more required field by simply adding it to the $required array.
You could even easily add other validation like that. For example:
// validation of fields
$validation= [
'name' => [
'name' => 'Name',
'required' => true,
],
'email' => [
'name' => 'Emailaddress',
'required' => true,
'validation' => 'email',
],
'custom_field1' => [
'name' => 'My awesome field 1',
'required' => true,
'validation' => '/^[a-z]{2,}$/i',
],
'custom_field2' => [
'name' => 'My awesome field 2',
'required' => true,
],
];
function validateEmail($key, $data, $errors) {
if (!filter_var($_POST[$key], FILTER_VALIDATE_EMAIL)) {
$errors[$key] = $data['name'] . ' must be a valid emailaddress';
}
return $errors;
}
function validatePattern($key, $data, $errors) {
if (preg_match($data['validation'], $_POST[$key]) !== 1) {
$errors[$key] = $data['name'] . ' has an incorrect format';
}
return $errors;
}
// list of errors
$errors = [];
if (isset($_POST['email'])) {
// loop fields to be validated
foreach ($validationas $key => $data) {
if (array_key_exists('validation', $data)) {
switch($data['validation']) {
case 'email':
$errors = validateEmail($key, $data, $errors);
break;
default:
validatePattern($key, $data, $errors)
break;
}
}
if ($data['required'] !== true) {
continue;
}
if ($_POST[$key] === '') {
$errors[$key] = $data['name'] . ' is required';
}
}
}
You could also add client side validation as in LMT-PhD's answer but you should always have at least server side validation. Client side validation should be treated as a nice thing to do for users and nothing more.