Error in simple PHP registration form / function - php

I have the following PHP function that attempts to register a user in a database with a temporary password when they post an email adress via a form:
public function registerNewUser() {
$temp_pass = '';
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$random_string_length=8;
for ($i = 0; $i < $random_string_length; $i++) {
$temp_pass .= $characters[rand(0, strlen($characters) - 1)];
}
if (empty($_POST['user_email'])) {
$this->errors[] = FEEDBACK_EMAIL_FIELD_EMPTY;
} elseif (strlen($_POST['user_email']) > 64) {
$this->errors[] = FEEDBACK_EMAIL_TOO_LONG;
} elseif (!filter_var($_POST['user_email'], FILTER_VALIDATE_EMAIL)) {
$this->errors[] = FEEDBACK_EMAIL_DOES_NOT_FIT_PATTERN;
} elseif (!empty($_POST['user_email'])
&& strlen($_POST['user_email']) <= 64
&& filter_var($_POST['user_email'], FILTER_VALIDATE_EMAIL)) {
$this->user_email = htmlentities($_POST['user_email'], ENT_QUOTES);
$this->user_password = $temp_pass;
$this->hash_cost_factor = (defined('HASH_COST_FACTOR') ? HASH_COST_FACTOR : null);
$this->user_password_hash = password_hash($this->user_password, PASSWORD_DEFAULT, array('cost' => $this->hash_cost_factor));
$sth = $this->db->prepare("SELECT * FROM users WHERE user_email = :user_email ;");
$sth->execute(array(':user_email' => $this->user_email));
$count = $sth->rowCount();
if ($count == 1) {
$this->errors[] = FEEDBACK_USEREMAIL_ALREADY_TAKEN;
} else {
$this->user_activation_hash = sha1(uniqid(mt_rand(), true));
$sth = $this->db->prepare("INSERT INTO users (user_email, user_password_hash, user_activation_hash) VALUES(:user_email, :user_password_hash, :user_activation_hash) ;");
$sth->execute(array(':user_email' => $this->user_email, ':user_password_hash' => $this->user_password_hash, ':user_activation_hash' => $this->user_activation_hash));
$count = $sth->rowCount();
if ($count == 1) {
$this->user_id = $this->db->lastInsertId();
// send a verification email
if ($this->sendVerificationEmail()) {
// when mail has been send successfully
$this->messages[] = FEEDBACK_ACCOUNT_SUCCESSFULLY_CREATED;
$this->registration_successful = true;
return true;
} else {
$sth = $this->db->prepare("DELETE FROM users WHERE user_id = :last_inserted_id ;");
$sth->execute(array(':last_inserted_id' => $this->db->lastInsertId() ));
$this->errors[] = FEEDBACK_VERIFICATION_MAIL_SENDING_FAILED;
}
} else {
$this->errors[] = FEEDBACK_ACCOUNT_CREATION_FAILED;
}
}
} else {
$this->errors[] = FEEDBACK_UNKNOWN_ERROR;
}
// standard return. returns only true of really successful (see above)
return false;
}
I keep tripping the FEEDBACK_ACCOUNT_CREATION_FAILED error, but can't figure out why. Any ideas?

Have you dumped "$sth" after it does the insert?
What does that give you?
If you are using mysql you can turn the general_log (http://dev.mysql.com/doc/refman/5.1/en/query-log.html) to see the mysql query that gets executed.
This way you can see if the query is getting created properly.
Turning on mysql logging can be very useful if you are not sure whats happening at the other end.

Related

PHP MySQL - Validate email in PHP

currently I do a checking function to know email already exist or not in db. If exist then error, if not update data. But if existing user edit their data such as weight. Then it will give error because it detect email already exist. But the user only edit the weight data, not the email. can anyone help me how to solve this problem or have any recommendation to do this part. I'm using a CodeIgniter framework.
This is my controller
if (!empty($this->input->post()))
{
$data["weight"] = $this->input->post("weight");
$data["height"] = $this->input->post("height");
$data["username"] = $this->input->post("username");
$data["email"] = $this->input->post("email");
if (strlen($this->input->post("username")) < 6)
{
$result = $this->Global_model->GenerateOutputMsgArray("0", "Username should be at least 6 alphanumerics, please try again.");
}
elseif (!$this->Profile_model->ValidateEmail($this->input->post()))
{
$result = $this->Global_model->GenerateOutputMsgArray("0", "Email has been taken, please try another.");
} else {
$result["status"] == "1";
$this->Profile_model->UpdateProfile($data["weight"], $data["height"], $data["username"], $data["email"]);
$result = $this->Global_model->GenerateOutputMsgArray("1", "Your profile has been updated.", $data);
}
this is my model (validate email function and update data)
public function ValidateEmail($post)
{
$stat = "0";
$msg = "";
$data = array();
$output = array();
$query = $this->db->get_where("user", array("email" => $post["email"]));
$result = $query->row();
$result = (array)($result);
return ($result) ? false : true;
}
function UpdateProfile($weight, $height,$username, $email)
{
$data= array(
"weight" => $weight,
"height" => $height,
"username" => $username,
"email" => $email
);
$this->db->where("user_id", $this->session->userdata("user_id"));
$this->db->update("user", $data);
}
````````````````
You must be having user_id with email.
Try with this one.
public function ValidateEmail($post)
{
$stat = "0";
$msg = "";
$data = array();
$output = array();
$query = $this->db->get_where("user", array("email" => $post["email"]));
if($query->num_rows() > 0){
$result = $query->row();
if($result->user_id == $this->session->userdata("user_id")){
return false; // force doesn't exist
}else{
return true; // exists
}
}else{
return false; // as there is no row returned. it will return as doesn't exist
}
}

Throttling attempts not being recorded into database

Hi I am trying to create login throttling with object oriented php, I have successfully created it with structured code but I can not get it to work with object oriented so far heres the code:
public function find_failed_login($email = null) {
if(!empty($email)) {
$query = "SELECT * FROM {$this->table} WHERE email = '".$this->db->escape($email)."'";
return $this->db->query($query);
}
}
public function record_failed_login($email) {
$count = 1;
$time = time();
$failed_login = $this->find_failed_login($email);
if(!$failed_login) {
$query = "INSERT INTO {$this->table} (email, count, last_time) VALUES ('".$this->db->escape($email)."', {$count}, {$time})";
return $this->db->query($query);
} else {
$query = "UPDATE {$this->table} SET email = '{$email}', count = count + 1, last_time = {$time}";
return $this->db->query($query);
}
}
public function clear_failed_logins($email = null) {
if(!empty($email)) {
$failed_login = $this->find_failed_login($email);
if(isset($failed_login)) {
$query = "DELETE FROM {$this->table} WHERE email = '".$this->db->escape($email)."'";
return $this->db->query($query);
}
}
}
public function throttle_failed_logins($email = null) {
if(!empty($email)) {
$throttle_at = 3;
$delay_in_minutes = 1;
$delay = 60 * $delay_in_minutes;
$failed_login = $this->find_failed_login($email);
if(isset($failed_login)) {
while($failed = mysqli_fetch_assoc($failed_login)) {
if(isset($failed) && $failed['count'] >= $throttle_at) {
$remaining_delay = ($failed['last_time'] + $delay) - time();
$remaining_delay_in_minutes = ceil($remaining_delay / 60);
return $remaining_delay_in_minutes;
} else {
return 0;
}
}
}
}
}
and in the login page I am calling it like this:
$objLogin = new Login();
if($objForm->isPost('login_email')) {
$throttle_delay = $objLogin->throttle_failed_logins($objForm->getPost('login_email'));
if($throttle_delay > 0) {
$objValid->add2Errors('failed_logins');
}
when I try this I get no error or anything for that matter, its like it is dead code, would appreciate some professional help :)

PDO is not allowing insert query to be done

I am facing a weird issue that is causing me to go crazy. I never run into anything like this. even though I can predict that it will be something really easy but I am over looking it.
I am executing queries based on the business roles logic. so in somecases i do select and update, in others i do a select, update and then insert so on an so fourth. Here is the overall structure on how I handle my code
Open PDO connection
1 getDataSet 1 (select)
2 ProcessQuery (update)
3 getDataSet 1 (select)
4 ProcessQuery (Insert)
Close PDO connection by setting the PDO object to null.
For odd reason the insert does not work at all! the select works, the update works no problem but when it comes to the insert part it does not work. it does not even give me any error at all. In fact, I copied the same query and executed it in phpMyAdmin and the query works!
I should note the the table that I am trying to insert into is very large and has over 4 million records with many indexes.
What could be the problem? what else can I check? why the insert is not working form the script and it is working from phpmyadmin??
here is my code
this is my current PDO class that I use to connect to the server
http://pastebin.com/XQ2RrhA1
<?php
class connection {
private $connString;
private $userName;
private $passCode;
private $server;
private $pdo;
private $errorMessage;
protected $lastQueryTime;
protected $lastQuery;
private $pdo_opt = array (
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
);
function __construct($dbName, $serverName = 'localhost'){
//sets credentials
$this->setConnectionCredentials($dbName, $serverName);
//start the connect
$this->startConnection();
}
function startConnection(){
$this->pdo = new PDO($this->connString, $this->userName, $this->passCode, $this->pdo_opt);
if( ! $this->pdo){
$this->errorMessage = 'Failed to connect to database. Please try to refresh this page in 1 minute. ';
$this->errorMessage .= 'However, if you continue to see this message please contact your system administrator.';
echo $this->getError();
}
}
//this will close the PDO connection
public function endConnection(){
$this->pdo = null;
}
//return a dataset with the results
public function getDataSet($query, $data = NULL)
{
$start = microtime(true);
$cmd = $this->pdo->prepare( $query );
$cmd->execute($data);
$ret = $cmd->fetchAll();
//$cmd->closeCursor();
$this->lastQueryTime = microtime(true) - $start;
$this->lastQuery = $query;
return $ret;
}
public function processQuery($query, $data = NULL)
{
$start = microtime(true);
//$this->pdo->beginTransaction();
$cmd = $this->pdo->prepare( $query );
$ret = $cmd->execute($data);
//$this->pdo->commit();
//$cmd->closeCursor();
$this->lastQueryTime = microtime(true) - $start;
$this->lastQuery = $query;
return $ret;
}
//return last insert id
public function lastInsertId($name = NULL) {
if(!$this->pdo) {
return false;
}
return $this->pdo->lastInsertId($name);
}
public function getOneResult($query, $data = NULL){
$cmd = $this->pdo->prepare( $query );
$cmd->execute($data);
return $cmd->fetchColumn();
}
public function getError(){
if($this->errorMessage != '')
return $this->errorMessage;
else
return true; //no errors found
}
//this where you need to set new server credentials with a new case statment
function setConnectionCredentials($dbName, $serv){
switch($serv){
case default:
$this->connString = 'mysql:host='.$serv.';dbname='.$dbName.';charset=utf8';
$this->userName = 'USER';
$this->passCode = 'PASSWORD';
break;
}
}
public function lastQueryTime() {
if(!$this->lastQueryTime) {
throw new Exception('no query has been executed yet');
}
return $this->lastQueryTime;
}
public function lastQuery() {
if(!$this->lastQuery) {
throw new Exception('no query has been executed yet');
}
return $this->lastQuery;
}
}
?>
This is my actual code
<?php
require('../classes/connection.php');
$db = new connection(DATABASE_NAME, DATABASE_HOST);
$sendUpdate = 0;
$id = 0;
$resultCode = 0;
$callCode = 0;
$total_attempts = 0;
$account_id = 0;
$timer = 0;
$notes = '';
$triggerOn = '';
$subject = '';
if(isset($_POST['sendUpdate'])){
$sendUpdate = 1;
}
if(isset($_POST['current_call_id'])){
$id = bigint($_POST['current_call_id']);
}
if(isset($_POST['result_code_menu'])){
$resultCode = bigint($_POST['result_code_menu']);
}
if(isset($_POST['selected_call_code'])){
$callCode = bigint($_POST['selected_call_code']);
}
if(isset($_POST['total_attempts'])){
$total_attempts = bigint($_POST['total_attempts']);
}
if(isset($_POST['account_id'])){
$account_id = bigint($_POST['account_id']);
}
if(isset($_POST['notes'])){
$notes = trim($_POST['notes']);
}
if(isset($_POST['triggerOn'])){
$triggerOn = convertTimeToUTCzone( $_POST['triggerOn'], USER_TIME_ZONE );
}
$subject = $resultCode;
if(isset($_POST['timer'])){
$timer = convertTimeToSeconds($_POST['timer']);
}
//CONVERT $time to seconds
$error_list = '';
$pass_message = '';
if($id < 1){
$error_list .= '<li>You have selected an invalid link</li>';
}
if($callCode == 0){
$error_list .= '<li>You must select a call code.</li>';
}
if($resultCode == 0){
$error_list .= '<li>You must select a result code.</li>';
}
if($timer == 0){
$error_list .= '<li>You can not reset timer before submitting the form.</li>';
}
//if pass all check
if($error_list == ''){
$pass_all = 0;
//Find out what is the next action
$action = $db->getDataSet('SELECT result FROM result_codes WHERE result_code_id = '.$resultCode.' LIMIT 1;' );
if( count($action) == 1){
$next_action = $action[0]['result'];
} else {
$error_list .= '<li>Error #95: Unknown Error: result code was not found.</li>';
$pass_all = 0;
}
//Close existing open phone call
if( $next_action == 'FINISH' || $next_action == 'CREATE NEW CALL' || $next_action == 'TRY AGAIN' ){
$statment = $db->processQuery('UPDATE phone_calls SET result_code_id= ?, call_notes= ?, call_duration = ?,
first_attempt_on = if(first_attempt_on IS NULL, NOW(), first_attempt_on),
first_attempt_by = if(first_attempt_by = "", '.USER_ID.',first_attempt_by),
last_attempt_on = NOW(), total_attempts = total_attempts+1, status=2 WHERE phone_call_id = '.$id.' LIMIT 1;'
, array($resultCode, $notes, $timer) );
if($statment){
$pass_all = 1;
} else {
$error_list .= '<li>Error #96: System could not update Phone Call</li>';
$pass_all = 0;
}
$statment = null;
}
//Update the existing phone call & Keep it open to be called again
if( $next_action == 'TRY AGAIN'){
$new_call = $db->getDataSet('SELECT call_code_title AS subject FROM call_codes WHERE call_code_id= '.$callCode.' LIMIT 1;' );
if( count($new_call) == 1 ){
$subject = $new_call[0]['subject'];
} else {
$error_list .= '<li>Error #79: Unknown Error: call code was not found.</li>';
}
$new_call = null;
$this_attempt = $total_attempts+1;
if($this_attempt >= 1){
$subject = $subject . ' attempt: ' . $this_attempt;
}
$statment = $db->processQuery('INSERT INTO phone_calls (account_id, call_code_id, trigger_on, created_on, call_subject, status, last_call_id
, call_direction, owner_id, workflow_generated, call_notes)
VALUES('.$account_id.', '.$callCode.', "'.$triggerOn.'", NOW(), "'.$subject.'", 1, '.$id.', "OUTBOUND", '.USER_ID.', 1, "");');
if($statment ){
$pass_all = 1;
} else {
$error_list .= '<li>Error #80: System could not generate a new attempt</li>';
$pass_all = 0;
}
$statment = null;
}
//Update the existing phone call THEN assign the activity to the master user define in APP_configuration.php
if( $next_action == 'MGR REVIEW'){
$statment = $db->processQuery('UPDATE phone_calls SET result_code_id= ?, call_notes= ?, call_duration = ?,
first_attempt_on = if(first_attempt_on IS NULL, NOW(), first_attempt_on),
first_attempt_by = if(first_attempt_by = "", '.USER_ID.',first_attempt_by),
last_attempt_on = NOW(), total_attempts = total_attempts+1,
trigger_on = ?, owner_id = '.CMS_ADMIN_ID.' WHERE phone_call_id = '.$id.' LIMIT 1;'
, array($resultCode, $notes, $timer, $triggerOn) );
if($statment){
$pass_all = 1;
} else {
$error_list .= '<li>Error #98: System could not update Phone Call</li>';
$pass_all = 0;
}
$statment = null;
}
if($sendUpdate == 1 && $error_list == '' && $pass_all == 1 ){
$statment = $db->processQuery('DELETE FROM phone_calls WHERE last_call_id = '.$id.' LIMIT 1;');
if($statment){
$pass_all = 1;
} else {
$error_list .= '<li>Error #81: System could not run reverse system flow.</li>';
$pass_all = 0;
}
$statment = null;
}
//Generate new phone call
if( $next_action == 'CREATE NEW CALL'){
//Find the nect call code to generate
$new_call = $db->getDataSet('SELECT ie.action_id, CONCAT(cc.call_code_name, " - ", cc.call_code_title) AS subject FROM inventory_engine AS ie
INNER JOIN call_codes AS cc ON ie.action_id = cc.call_code_id
WHERE ie.call_code_id= ? AND ie.result_code_id = ? LIMIT 1;', array($callCode,$resultCode ) );
if( count($new_call) == 1 ){
$new_callcode_id = $new_call[0]['action_id'];
$subject = $new_call[0]['subject'];
} else {
$error_list .= '<li>Error #94: Unknown Error: call code was not found.</li>';
}
$new_call = null;
$statment = $db->processQuery('INSERT INTO phone_calls (account_id, call_code_id, trigger_on, created_on, call_subject, status, last_call_id
, call_direction, owner_id, workflow_generated, call_notes)
VALUES(?, ?, ?, NOW(), ?, 1, ?, "OUTBOUND", ?, 1, "");',
array($account_id, $new_callcode_id, $triggerOn, $subject, $id, USER_ID ) );
if($statment){
$pass_all = 1;
} else {
$error_list .= '<li>Error #99: System could not update Phone Call</li>';
$pass_all = 0;
}
$statment = null;
}
if($pass_all == 1 && $error_list == ''){
$pass_message = '<li>You have successfully complete the phone call.</li>';
} else {
$error_list .= '<li>Error #100: Unknown Error: Please contact your system admin</li>';
}
}
//close database connection
$db->endConnection();
$return = array();
if($pass_message != ''){
$return['msg'] = '<ul>'.$pass_message.'</ul>';
$return['error'] = false;
} else {
$return['msg'] = '<ul>'. $error_list.'</ul>';
$return['error'] = true;
}
echo json_encode($return);
?>
This here is my actual code the does not insert a records
http://pastebin.com/QSt03qqx
Thanks for your help :)
PS
this is the query that won't run in my code but it runs when i run it in PHPmyadmin
INSERT INTO phone_calls (account_id, call_code_id, trigger_on, created_on, call_subject, status, last_call_id , call_direction, owner_id, workflow_generated, call_notes) VALUES(11601, 1, "2013-04-11 16:36:00", NOW(), "Initial Development attempt: 1", 1, 17132, "OUTBOUND", 1, 1, "");
What could be the problem? what else can I check? why the insert is not working form the script and it is working from phpmyadmin?
Welcome to programmer's word.
As a matter of fact, programming is not only writing code.
But, unfortunately, up to the 50% of programmer's time being spent answering the very questions you asked above. And it's not an easy job. Considerable efforts have to be spent. The bad news, such a kind of questions scarcely can have an answer on a Q&A site. What'd you answer yourself? So, your own hands are your last resort. Thus roll up your sleeves and start for debugging:
Make sure you can see every error PHP raises.
Make sure PDO does throw an exception on error.
Make sure you aren't gagging these errors with #, try..catches and zero error reporting.
Set up watchdogs to log erroneous queries, their data and get diagnosis from mysql (at least SHOW PROCESSLIST).

how to crypt passwords and use it in a function?

hello i have problems while using crypt function. i would like to check passwords from a database and an entered one.
the problem i have is that when i will enter a password it even will redirect even in case when it is a totally different password? this is strange to me.
so i use this function:
function salt_crypt($login_password, $rounds = 7) {
$salt = "";
$salt_chars = array_merge(range('A','Z'), range('a','z'), range(0,9)); for($i=0; $i < 22; $i++) {
$salt .= $salt_chars[array_rand($salt_chars)];
}
return crypt($login_password, sprintf('$2a$%02d$', $rounds) . $salt);
i will get the stored password from a function that returns an array:
function ab($a){
global $db;
$query = $db->query("SELECT col_a, col_b FROM table WHERE Field= '$a' ");
$check = $query->fetch_assoc();
return ($check);
}
and this will be used in this function:
function login($a, $login_password){
$user_data = user_data($a);
global $db;
$uname = sanitize($uname);
$crypted_password = salt_crypt($login_password);
if(crypt($user_data['col_b'], $crypted_password) == $crypted_password) {
$query = $db->query("SELECT col_a FROM table WHERE Field_a= '$a' AND Field_b = '$crypted_password' ");
$check = $query->num_rows;
return ($check == 1) ? true : false;
}
}
this function wil be called and in case of the returning result header with:
$login = login($a, $login_password);
if ($login === false){
$errors[] = "text";
} else {
header('Location: page.php');
}
Not all code paths return a value -> your function will return true, even if the if statement is false. Try it with something like this:
function login($a, $login_password){
//All your stuff
if(crypt($user_data['col_b'], $crypted_password) == $crypted_password) {
//Your stuff
}
return false
}

Reason for: Trying to get property of non-object in php

if(isset($_POST['uname']))
{
$query = "SELECT * FROM user_info";
$res = $mysqli->query($query);
$num = $res->num_rows;
$i = 0;
$cpwd = $_POST["pswd"];
$hpwd = SHA1($cpwd);
$tmp = $_POST["uname"];
while($i < $num)
{
$row = $res->fetch_object();
$name = $row->Username;
$pwd = $row->Password;
if($name == $tmp)
{
//check if user is blocked
}
//hashed pwd
if($pwd == $hpwd)
{
//success
exit();
}
//request for pwd change
else if($pwd == $cpwd)
{
//change
exit();
}
else if($pwd != $hpwd)
{
//incorrect pwd
}
}
$i++;
}
if($i == $num)
{
//new user
}
}
I'd guess that you're somehow looping past the end of the array and $row is actually NULL.
So $res->fetch_object() did not return an object. Take a look at the documentation of this function. What does it return when it finds nothing?
some times num_rows return 1, even if no rows effected. Try to use
while($row = $res->fetch_object())
or
you forget to increment $i :)
get rid of that junk and make it like this
$query = "SELECT * FROM user_info WHERE Username = ? AND Password = ?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param('ss', $_POST["uname"], SHA1($_POST["pswd"]));
$stmt->execute() or trigger_error($mysqli->error());
if (!$mysqli->affected_rows) {
//no such user
}
I've never used mysqli myself, so, there may be typos.
But I hope you'll be able to get the idea.

Categories