email validation from link php - php

I am trying to build a email verification. Sending an email with a link to the user is working. Now I want to set active = 1 when the user clicks on the link wich he received. I have checked the variables $email and $key they are getting the right information from the url. When the active is set to 1 I want to echo an ahref to login.php. I think there is someting wrong in my SQL query can somebody help?
<?php
if (isset($_GET['email'])) {
$email = $_GET['email'];
}
if (isset($_GET['hash'])){
$key = $_GET['hash'];
}
$query = $mysqli->query("UPDATE `users` SET active=1 WHERE `email` = '". $email ."' AND `mailcheck` ='". $key ."' ");
$result = $query->fetch_row();
if($result == 1){
echo "Your account is now active. You may now Log in";
}
else {
echo "Your account could not be activated. Please recheck the link or contact the system administrator. test";
}
}
?>

Hold on here. fetch_row() http://php.net/manual/en/mysqli-result.fetch-row.php is for a SELECT and not UPDATE.
What you're looking to use is mysqli_affected_rows()
http://php.net/manual/en/mysqli.affected-rows.php
on UPDATE in order to check if the update was successful.
If you're looking to do a SELECT here (which makes more sense really), then you need to use mysqli_num_rows(), and if both exists, then do the UPDATE.
http://php.net/manual/en/mysqli-result.num-rows.php
You should also check for errors against your query:
http://php.net/manual/en/mysqli.error.php
If a row/user exists:
Consult an answer of mine https://stackoverflow.com/a/22253579/1415724 to check if a user exists, where you can base yourself on it.
Plus, a suggestion. Use !empty() instead of isset(). It's usually best to check against values.
What would also work better is to check if any are empty, rather than 2 conditional statements.
If one is left empty, your code will continue to execute and in turn, your query failing.
If you want to keep your present method, then you should exit; after each GET, but I wouldn't recommend it.
More like:
if ( !empty($_GET['email']) && !empty($_GET['hash']) ) {
$email = $_GET['email'];
$key = $_GET['hash'];
}
else{ exit; }
Your present code is open to SQL injection. Use mysqli_* with prepared statements, or PDO with prepared statements.

The problem is because of the following line,
$result = $query->fetch_row();
You're trying to do UPDATE operation but you're actually fetching the result row using ->fetch_row() statement, which by the way doesn't exist because UPDATE operation doesn't return any result set.
Use ->affected_rows property to get the number of affected rows from the UPDATE operation, like this:
$mysqli->query("UPDATE `users` SET active=1 WHERE `email` = '". $email ."' AND `mailcheck` ='". $key ."'");
if($mysqli->affected_rows == 1){
echo "Your account is now active. You may now Log in";
}else{
echo "Your account could not be activated. Please recheck the link or contact the system administrator.";
}
Here's the reference:
mysqli::$affected_rows
Edited:
Your code on the validation page should be like this:
if(isset($_GET['email']) && isset($_GET['hash'])){
$email = htmlentities($_GET['email']);
$key = htmlentities($_GET['hash']);
$mysqli->query("UPDATE `users` SET active=1 WHERE `email` = '". $email ."' AND `mailcheck` ='". $key ."'");
if($mysqli->affected_rows){
echo "Your account is now active. You may now Log in";
}else{
echo "Your account could not be activated. Please recheck the link or contact the system administrator.";
}
}else{
echo "wrong parameters.";
}
Re-edited:
After extensive debugging with OP the issue is resolved now, and this is the final working code,
if (isset($_GET['email']) && isset($_GET['hash'])) {
$email = $_GET['email'];
$key = $_GET['hash'];
$mysqli->query("UPDATE `users` SET active=1 WHERE `email` = '". $email ."' AND `mailcheck` ='". $key ."' ");
if($mysqli->affected_rows) {
echo "Your account is now active";
}else {
echo "Failed";
}
}

Related

How I should fix if else statement didn't work

I want to test if user enter incorrect file number and ic, the message "Inccorect ref no and ic no" will shown, but it didn't work like that. It always shown the message "Thanks you for register attendance with us." Help me please..I'm new.
<?php
require "init.php";
$file_number = $_POST["file_number"];
$ic_no = $_POST["ic_no"];
$attendance = $_POST["attendance"];
//$ic_no = $_REQUEST['ic_no'];
$sql = "INSERT INTO reg_attend(file_number,ic_no,attendance) SELECT reg_meeting.file_number,reg_staff.ic_no,'".$attendance."' FROM reg_meeting,reg_staff WHERE (reg_meeting.file_number = '".$file_number."' AND reg_staff.ic_no = '".$ic_no."')";
$result = mysqli_query($conn,$sql);
$response = array();
if($result)
{
//var_dump($result);
$code = "reg_success";
$message = "Thanks you for register attendance with us.";
array_push($response,array("code"=>$code,"message"=>$message));
echo json_encode($response);
}
else
{
$code = "reg_failed";
$message = "Incorrect REF No. and IC No.";
array_push($response,array("code"=>$code,"message"=>$message));
echo json_encode($response);;
}
mysqli_close($conn);
?>
You need to validate your incoming data before you insert into your DB. It looks like currently, you will be inserting empty values into your reg_attend table. As this is likely successful, you will not be reaching the else.
If you need to validate that the passed in data exists, do a select first e.g.
SELECT reg_meeting.file_number,reg_staff.ic_no,'".$attendance."' FROM reg_meeting,reg_staff WHERE (reg_meeting.file_number = '".$file_number."' AND reg_staff.ic_no = '".$ic_no."')"
then check the results of that, before inserting.
As a side note, please please DO NOT use this code as shown. You should prefer to use query parameters with either PDO or mysqli. See https://www.php.net/manual/en/pdo.prepare.php

Wordpress: PHP delete database row in foreach cycle

Hi guys I am very new to PHP development.
I am writing a smiple script to get and email perameter from the url, cycle through some rows in a database table and delete the row if it is found.
I have got everything except the deleting of the row. I would really appreciate someone talking me through my mistake to help me understand. I think the error lies in the WHERE condition.
The error message I get is:
ERROR: Could not able to execute DELETE FROM wp_email_address_db WHERE alaofolasade#yahoo.com==alaofolasade#yahoo.com.
<?php
$path = $_SERVER['DOCUMENT_ROOT'];
include_once $path . '/wp-load.php';
global $wpdb;
//sanatise and lowercase email addy from URL
$emailToRemove = filter_var ( strtolower($_GET["usermail"]), FILTER_SANITIZE_EMAIL);
//get DB table
$data = $wpdb->get_results("SELECT * FROM wp_email_address_db`");
foreach ($data as $d) {
//sanatise and lowercase email addy from DB
$email = filter_var ( strtolower($d->email_address), FILTER_SANITIZE_EMAIL);
//check if the email addy is in this row
if($email == $emailToRemove){
//get info
echo 'true <br/>';
echo 'id: '.$d->id.'<br/>';
//I need to delete this row
$sql = "DELETE FROM wp_email_address_db WHERE $email = $emailToRemove";
if(mysqli_query($link, $sql)){
echo "Records were deleted successfully.";
} else{
echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
}
}
}
// $columnTitles = ['id','email_address','imported_via'];
?>
You have a typo in email and the value in where clause should be within single quotes:
change this to:
$sql = "DELETE FROM wp_email_address_db WHERE email = '$emailToRemove'";
Your query should be this :
$sql = "DELETE FROM wp_email_address_db WHERE email = '$emailToRemove'";
It is always better to use quotation (single quote', double quote ") also defining the column with back-tick.
Query:
$sql = "DELETE FROM wp_email_address_db WHERE `email` = '".$emailToRemove."'";
Your main error is $email which should be the column name with back-tick here WHERE $email = $emailToRemove
Should not be the query something like
DELETE FROM wp_email_address_db WHERE email_field_name = '$emailToRemove'
instead of
DELETE FROM wp_email_address_db WHERE $email = $emailToRemove
In your query you are passing the value of $email as field name and I assume that the field alaofolasade#yahoo.com does not exist
Try replacing
$sql = "DELETE FROM wp_email_address_db WHERE $email = $emailToRemove";
with
$sql = "DELETE FROM wp_email_address_db WHERE '$email' = '$emailToRemove'";
I removed the foreach, you don't need to retrieve ALL the mails from your database.
Moreover I used the prepared statements to avoid SQL injections
This kind of script which perform delete query to database HAVE to be protected from all users. Only admins should be allow to this script
<?php
$path = $_SERVER['DOCUMENT_ROOT'];
include_once $path . '/wp-load.php';
// WARNING: You should check the identity of the user performing this action, MySql DELETE action is dangerous
global $wpdb;
//sanatise and lowercase email addy from URL
$emailToRemove = filter_var ( strtolower($_GET["usermail"]), FILTER_SANITIZE_EMAIL);
$sqlDeleteQuery = '
DELETE
FROM wp_email_address_db
WHERE email = ?
';
$statement = mysqli_prepare($link, $sqlDeleteQuery);
// Bind the email to your query (the ? ), this avoid the SQL injection attack
$statement->bind_param('s', $emailToRemove);
if (false !== mysqli_stmt_execute($statement)) {
die('The MySql query failed ! Error : ' . mysqli_error($link));
}
$emailsDeleted = mysqli_stmt_affected_rows($statement);
echo sprintf('"%d" emails deleted', $emailsDeleted);
I can't try the above code, so please let me know if something is wrong :)
Solved it by:
<?php
require_once($_SERVER["DOCUMENT_ROOT"]."/wp-load.php");
if (isset($_GET["usermail"])) {
global $wpdb;
$remove = filter_var(strtolower($_GET["usermail"]), FILTER_SANITIZE_EMAIL);
$wpdb->query("DELETE FROM wp_email_address_db WHERE email_address='$remove'");
echo "You have successfully been unsubscribed.";
}
?>

how to disable user account php/mysql

I am trying to have user accounts that can be enabled or disabled.
I have a active field in my table that is set to either yes or no.
This is my code for the login page.
<?php
/* User login process, checks if user exists and password is correct */
require_once 'includes/db.php';
// Escape email to protect against SQL injections
$email = $mysqli->escape_string($_POST['email']);
$result = $mysqli->query("SELECT * FROM dxd_membership WHERE email='$email'");
if ( $result->num_rows == 0 ){ // User doesn't exist
$_SESSION['message'] = "User with that email doesn't exist!";
header("location: error.php");
}
else { // User exists
$user = $result->fetch_assoc();
$active = $mysqli->query("SELECT * FROM dxd_membership WHERE email = '$email' AND active = 'YES'");
if ($active == '1')
{
if ( password_verify($_POST['password'], $user['password']) ) {
$userid = $_SESSION['userid'];
$_SESSION['email'] = $user['email'];
$_SESSION['firstname'] = $user['firstname'];
$_SESSION['lastname'] = $user['lastname'];
$_SESSION['username'] = $user['username'];
$_SESSION['paynum'] = $user['paynum'];
$_SESSION['empnum'] = $user['empnum'];
$_SESSION['phone'] = $user['phone'];
$_SESSION['active'] = $user['active'];
$_SESSION['lastlogin'] = $user['lastlogin'];
$_SESSION['signup'] = $user['signup'];
$_SESSION['lastupdate'] = $user['lastupdate'];
// This is how we'll know the user is logged in
$_SESSION['logged_in'] = true;
$update = $mysqli->query("UPDATE dxd_membership SET lastlogin=NOW() WHERE email = '$email'");
header("location: welcome.php");
}
else {
$_SESSION['message'] = "You have entered wrong password please try again!";
header("location: error.php");
}
}
else {
header("location: disabled.php");
}
}
?>
I am sure it is a silly error i have here but it will not check the active field and then either let the user login to the welcome.php page if active is yes or send them to the disabled.php page if their account active is set to no (disabled).
Can anyone help me with correcting the code so that it will work.
Thanks
Look, I see several issues in your code. The first is the double query for the same data. You can simplify this whole thing to one query.
Another (and more important) is the fact that you're just appending data to the SQL query, where the whole objective of MySQLi is to avoid injections by binding params. So a -more- correct way to do it would be this one:
EDIT: escape_string avoids this. I completely ignored it.
<?php
/* User login process, checks if user exists and password is correct */
require_once 'includes/db.php';
// Escape email to protect against SQL injections
$email = $mysqli->escape_string($_POST['email']);
$result = $mysqli->query("SELECT * FROM dxd_membership WHERE email = '{$email}'");
if ( $result->num_rows == 0 ){ // User doesn't exist
$_SESSION['message'] = "User with that email doesn't exist!";
header("Location: error.php");
exit; // Add an "exit" here, because if you add something else, it will run too (even if you asked to redirect... basically is the browser the one that chooses if it follows the redirect or not, but your script still goes on).
}
else { // User exists
$user = $result->fetch_assoc();
// There's no point in filtering using another MySQL query, since YOU ALREADY HAVE THIS DATA. Just use PHP to read it and act appropiately.
// Doing another query is just WASTING resources for no useful purpose.
//$active = $mysqli->query("SELECT * FROM dxd_membership WHERE email = '$email' AND active = 'YES'");
if ( $user['active'] == 'YES' ) {
// Your processing here, you get the idea
}
}
?>
Of course, the best alternative is to use a MySQLi statement and use bind_param/execute. This example is only to follow your style of using MySQLi.
It's pretty obvious
$active = $mysqli->query("SELECT * FROM dxd_membership WHERE email = '$email' AND active = 'YES'");
if ($active == '1') //<-- see it
{
if ( password_verify($_POST['password'], $user['password']) )
Try this
if ($active->num_rows == 1 ) //or != 0 This is false or a result set.
Even if you did have the value of their active filed in there ( you have select * ) you would still be checking string '1' against string 'YES'
Please note I haven't used mysqli in about 4 years, as I use PDO. So that might not be the entire problem, but just seemed wrong..
In fact that second query is not needed as you already have the data you seek, so you can change it.
Now if you are sure active will always be YES for them being active, the $user already contains this data, so why not use it like this, and save the query.
$email = $mysqli->escape_string($_POST['email']);
$result = $mysqli->query("SELECT * FROM dxd_membership WHERE email='$email'");
if ( $result->num_rows == 0 ){ // User doesn't exist
$_SESSION['message'] = "User with that email doesn't exist!";
header("location: error.php");
}else { // User exists
$user = $result->fetch_assoc();
/* comment these next 2 lines out when not debugging */
echo "<pre>"; //whitespace formating
var_export( $user );
if ($user['active'] == 'YES'){
// .....
}
}
One thing I feel compelled to mention is that you should look into prepared statements. You can find information on that here
http://php.net/manual/en/mysqli.quickstart.prepared-statements.php
Whenever you concatenate in a SQL query you should be using a prepared statement instead, as it opens you application to SQL injection attacks. Now that I look closer you are using escape_string while this is good, the preferred way is prepared statements. This is because with a prepared statement, the variables are entirely separate from the query commands and so the DB knows not to execute anything in them. Even with escaping there could be edge cases that may be an issue, I don't know of any per-say, but something like using a Hexadecimal version of a quote are things I have seen in examples, or weird character strings that the DB would see as a quote.

Check if activation_code is not activeted at login. "ONLY" activation_code

This is the code I use at login:
$q = $lacz->query("SELECT email, pass, activation_code
FROM users
WHERE email='". $nazwa_uz_l ."'
AND pass = '". $haslo_l ."'
AND activation_code IS NULL ");
if($q->num_rows>0) {
$_SESSION['prawid_uzyt'] = $nazwa_uz_l; }
else
{
echo 'Pass or Log are wrong, or activation code is not confirmed (check email).';
exit;
}
In this query I check for all 3 things: email, password and activation code, and then output an error. What I want to do is to output an first error when Pass or Log are wrong and second error (something like elseif) when activation code IS not NULL. I tried else if and two queries, but I was getting the errors. Can You help me? I check the answers and give points, thanks.
Remove "AND activation_code IS NULL" from your query and do something like
if($q->num_rows>0)
{
$row = $q->fetch_assoc();
if(!is_null($row['activation_code']))
{
$_SESSION['prawid_uzyt'] = $nazwa_uz_l;
}
else
{
echo 'Activation code is not confirmed (check email).';
exit;
}
}
else
{
echo 'Pass or Log are wrong.';
exit;
}
Don't check the activation code in the query. Just get the user information, along with the activation code field:
SELECT email, pass, activation_code
..
WHERE email='foo' and pass='bar'
Then you can test the individual conditions in your code:
if (number_of_rows == 0) {
... bad username/password
} else if ($activation_code == '') {
... code is blank/null
}
If you remove the AND activation_code IS NULL from the query's WHERE clause, you'll be able to pull data for a user matching the given email/password. Then, with that, you'll be able to determine if the user exists, or if their activation code is empty:
$q = $lacz->query("SELECT email, pass, activation_code
FROM users
WHERE email='". $nazwa_uz_l ."'
AND pass = '". $haslo_l ."'");
if ($q->num_rows === 0) {
echo 'Password or email address are wrong.';
exit;
} else {
$row = $result->fetch_assoc();
if (empty($row['activation_code'])) {
echo 'Activation code is not confirmed.';
exit;
} else {
$_SESSION['prawid_uzyt'] = $nazwa_uz_l;
}
}
Side-note (not answer related): I highly suggest using a parameterized query instead of directly inserting the values into the SQL; if you prefer the current way, make sure you're sanitizing the input first to prevent SQL Injection.

I don't know what's wrong with this code SQL

I'm new to PHP and Mysql, for some reason it only checks for statement if($email == $result2 ) wether the input is username or email. I don't know why? can someone explain it logically, i'm stuck for hours figuring it out. :( Thanks Please be kind.
<?php
session_start();
include_once("connect.php");
$email = $_POST['email'];
$username = $_POST['username'];
//echo $_POST['email'];
if(isset($_POST['email']) )
{
$extract= mysql_query("SELECT username, email FROM users");
$resultq = mysql_num_rows($extract);
while($row= mysql_fetch_array($extract))
{
$result = $row['username'];
$result2 = $row['email'];
//$pass = $_POST['pass'];
if($email == $result2 )
{ //check if there is already an entry for that username
echo "Email Address is already used!";
exit(); //break;
}
if ($username == $result )
{
echo " Username is already Taken!";
//mysql_query("INSERT INTO users (Username, Password) VALUES ('$user', '$pass')");
//header("location:index.php");
exit(); //break;
}
else
{
}
}
}
It's behaving as written. If either if() test succeeds, you tell the script to exit().
Remove the exit() calls...
You also really REALLY need to learn about WHERE clauses in queries. You are sucking across your entire user table and comparing the records one at a time. This is the equivalent of driving to the grocery store, buying up the ENTIRE store's inventory, driving it home... then throwing it all in the garbage because all you really wanted was one candy bar.
I think you better use unique in your email and username column, then you don't need to check it anymore, mysql will do that for you!
Does it go into the second if statement ( if ($username == $result ) ) after you comment out the first one ( if ($username == $result )) ?
If so, then it keeps hitting that exit() function.
Guys i kinda guessed the answer from combining some of your comments. for some reason i need to include isset($_POST['username']) along with isset($_POST['email']) in order for my if Statements to be all executed... perhaps it was the isset checking if there is a value for username.
try this
if($email == $result2 )
{ //check if there is already an entry for that username
echo "Email Address is already used!";
//---------removed that line
}
else if ($username == $result ) //add else if instead of if
{
echo " Username is already Taken!";
//mysql_query("INSERT INTO users (Username, Password) VALUES ('$user', '$pass')");
//header("location:index.php");
//----------removed that line
}
else
{
}
EDIT:
change this
if(isset($_POST['email']) )
to
if(isset($_POST['email']) or isset($_POST['username']))
this to check them both. you are checking just email thats why you dont get the second if.
change this line the following line:
$extract= mysql_query("SELECT username, email FROM users");
Then use where clause as follows:
$extract= mysql_query("SELECT username, email FROM users where username='$username' and email='$email'");

Categories