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.
Related
403 error when this type data save.
this problem is only Namecheap server
when save then result in this
**but without unEscape HTML content data save successfully **
data seve with unEscape HTML content.
.................. /admin/page/update route point code below
public function update(Request $request)
{
$input = $request->all();
$content = $request->except(['page_code', 'status', '_token']);
$pageCode = $input['page_code'];
$page = Page::where('code', $pageCode)->first();
if ($page->type == 'dynamic') {
$content = [
'section_id' => $input['section_id'] ?? null,
'meta_keywords' => $input['meta_keywords'],
'meta_description' => $input['meta_description'],
'content' => Purifier::clean(htmlspecialchars_decode($input['content'])),
];
$data = [
'title' => $input['title'],
'data' => json_encode($content),
'status' => $input['status'],
];
} else {
$oldData = json_decode($page->data, true);
foreach ($content as $key => $value) {
if (is_file($value)) {
$oldValue = Arr::get($oldData, $key);
$content[$key] = self::imageUploadTrait($value, $oldValue);
} elseif ($key == 'content') {
$content[$key] = Purifier::clean(htmlspecialchars_decode($value));
}
}
$content = array_merge($oldData, $content);
$data = [
'status' => $input['status'] ?? true,
'data' => json_encode($content)
];
}
$page->update($data);
if ($page->type == 'dynamic') Cache::pull('pages');
notify()->success($page->title . ' ' . __(' Updated
Successfully'));
return redirect()->back();
}
$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']);
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.
How do i apply same validation rule for 50 fields in 2.0
i am not interested in repeating rule for different field
public $validate = array(
'company' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Cannot be Empty',
),
),
// rule for other 50 fields....
);
Possible solution:
$validate_items = array('company', 'other', 'one_more');
$validate_rule = array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Cannot be Empty')
);
$validate = array();
foreach ($validate_items as $validate_item) {
$validate[$validate_item] = $validate_rule;
}
echo "<pre>".print_r($validate, true)."</pre>";
Don't understand why you want to determinate same validation 50 times. You can declare just one rule and use it for all your fields.
May be I misunderstood your question?
You can dynamically build your $validate rules before you perform the save in your controller:
public function add() {
if (!empty($this->request->data) {
$validate = array();
foreach($fields as $field) {
$validate[$field] = array(
'required'=>array(
'rule'='notEmpty',
'message'=>'Cannot be empty'
)
);
}
$this->ModelName->validate = $validate;
if (!$this->ModelName->save($this->request->data)) {
// didn't save
}
else {
// did save
}
}
}
Where $fields is an array containing a list of the fields you want to apply the validation to.
Idealy, You'd shift the code that builds the validation array to the model, but the effect is the same
You can apply the same technique to allow you to have multiple validation rules for a model.
New example:
$fields_to_check = array('company', 'field_2', 'field_5'); // declare here all the fields you want to check on "not empty"
$errors = 0;
foreach ($_POST as $key => $value) {
if (in_array($key, $fields_to_check)) {
if ($value == "") $errors++;
}
}
if ($errors > 0) echo "There are ".$errors." errors in the form. Chech if all requered fields are filled in!"; //error! Not all fields are set correctly
else //do some action