I am having a problem while including a php class with ajax.
Basically I have index.php which loads with ajax example.php. example.php includes init.php, which in turn includes a bunch of classes. I narrowed it down to users.php class, which I pasted below. I also put init.php under it just in case.
The file simply will not load with ajax. It works fine if i go directly to it.
<?php
class Users{
private $db;
public function __construct($database) {
$this->db = $database;
}
public function update_user($first_name, $last_name, $gender, $bio, $image_location, $id){
$query = $this->db->prepare("UPDATE `users` SET
`first_name` = ?,
`last_name` = ?,
`gender` = ?,
`bio` = ?,
`image_location`= ?
WHERE `id` = ?
");
$query->bindValue(1, $first_name);
$query->bindValue(2, $last_name);
$query->bindValue(3, $gender);
$query->bindValue(4, $bio);
$query->bindValue(5, $image_location);
$query->bindValue(6, $id);
try{
$query->execute();
}catch(PDOException $e){
die($e->getMessage());
}
}
public function change_password($user_id, $password) {
global $bcrypt;
/* Two create a Hash you do */
$password_hash = $bcrypt->genHash($password);
$query = $this->db->prepare("UPDATE `users` SET `password` = ? WHERE `id` = ?");
$query->bindValue(1, $password_hash);
$query->bindValue(2, $user_id);
try{
$query->execute();
return true;
} catch(PDOException $e){
die($e->getMessage());
}
}
public function recover($email, $generated_string) {
if($generated_string == 0){
return false;
}else{
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `email` = ? AND `generated_string` = ?");
$query->bindValue(1, $email);
$query->bindValue(2, $generated_string);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
global $bcrypt;
$username = $this->fetch_info('username', 'email', $email); // getting username for the use in the email.
$user_id = $this->fetch_info('id', 'email', $email);// We want to keep things standard and use the user's id for most of the operations. Therefore, we use id instead of email.
$charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$generated_password = substr(str_shuffle($charset),0, 10);
$this->change_password($user_id, $generated_password);
$query = $this->db->prepare("UPDATE `users` SET `generated_string` = 0 WHERE `id` = ?");
$query->bindValue(1, $user_id);
$query->execute();
mail($email, 'Your password', "Hello " . $username . ",\n\nYour your new password is: " . $generated_password . "\n\nPlease change your password once you have logged in using this password.\n\n-Example team");
}else{
return false;
}
} catch(PDOException $e){
die($e->getMessage());
}
}
}
public function fetch_info($what, $field, $value){
$allowed = array('id', 'country', 'money', 'flag', 'email'); // I have only added few, but you can add more. However do not add 'password' eventhough the parameters will only be given by you and not the user, in our system.
if (!in_array($what, $allowed, true) || !in_array($field, $allowed, true)) {
throw new InvalidArgumentException;
}else{
$query = $this->db->prepare("SELECT $what FROM `users` WHERE $field = ?");
$query->bindValue(1, $value);
try{
$query->execute();
} catch(PDOException $e){
die($e->getMessage());
}
return $query->fetchColumn();
}
}
public function confirm_recover($email){
$username = $this->fetch_info('username', 'email', $email);// We want the 'id' WHERE 'email' = user's email ($email)
$unique = uniqid('',true);
$random = substr(str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ'),0, 10);
$generated_string = $unique . $random; // a random and unique string
$query = $this->db->prepare("UPDATE `users` SET `generated_string` = ? WHERE `email` = ?");
$query->bindValue(1, $generated_string);
$query->bindValue(2, $email);
try{
$query->execute();
mail($email, 'Recover Password', "Hello " . $username. ",\r\nPlease click the link below:\r\n\r\nhttp://www.example.com/recover.php?email=" . $email . "&generated_string=" . $generated_string . "\r\n\r\n We will generate a new password for you and send it back to your email.\r\n\r\n-- Example team");
} catch(PDOException $e){
die($e->getMessage());
}
}
public function user_exists($username) {
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `username`= ?");
$query->bindValue(1, $username);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
return true;
}else{
return false;
}
} catch (PDOException $e){
die($e->getMessage());
}
}
public function email_exists($email) {
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `email`= ?");
$query->bindValue(1, $email);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
return true;
}else{
return false;
}
} catch (PDOException $e){
die($e->getMessage());
}
}
public function register($username, $password, $email, $country, $timezone, $dst){
global $bcrypt; // making the $bcrypt variable global so we can use here
$date = date( 'Y-m-d' );
$ip = $_SERVER['REMOTE_ADDR']; // getting the users IP address
$email_code = $email_code = uniqid('code_',true); // Creating a unique string.
$password = $bcrypt->genHash($password);
$query = $this->db->prepare("INSERT INTO `users` (`username`, `password`, `email`, `country`, `timezone`, `dst`, `ip`, `regdate`, `email_code`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ");
$query->bindValue(1, $username);
$query->bindValue(2, $password);
$query->bindValue(3, $email);
$query->bindValue(4, $country);
$query->bindValue(5, $timezone);
$query->bindValue(6, $dst);
$query->bindValue(7, $ip);
$query->bindValue(8, $date);
$query->bindValue(9, $email_code);
try{
$query->execute();
mail($email, 'Please activate your account', "Hello " . $username. ",\r\nThank you for registering with us. Please visit the link below so we can activate your account:\r\n\r\nhttp://www.touringlegends.com/register.php?email=" . $email . "&email_code=" . $email_code . "\r\n\r\n-- Example team");
}catch(PDOException $e){
die($e->getMessage());
}
}
public function activate($email, $email_code) {
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `email` = ? AND `email_code` = ? AND `accountlevel` = ?");
$query->bindValue(1, $email);
$query->bindValue(2, $email_code);
$query->bindValue(3, 0);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
$query_2 = $this->db->prepare("UPDATE `users` SET `accountlevel` = ? WHERE `email` = ?");
$query_2->bindValue(1, 1);
$query_2->bindValue(2, $email);
$query_2->execute();
return true;
}else{
return false;
}
} catch(PDOException $e){
die($e->getMessage());
}
}
public function email_confirmed($email) {
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `email`= ? AND `accountlevel` >= ?");
$query->bindValue(1, $email);
$query->bindValue(2, 1);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
return true;
}else{
return false;
}
} catch(PDOException $e){
die($e->getMessage());
}
}
public function login($email, $password) {
global $bcrypt; // Again make get the bcrypt variable, which is defined in init.php, which is included in login.php where this function is called
$query = $this->db->prepare("SELECT `password`, `id` FROM `users` WHERE `email` = ?");
$query->bindValue(1, $email);
try{
$query->execute();
$data = $query->fetch();
$stored_password = $data['password']; // stored hashed password
$id = $data['id']; // id of the user to be returned if the password is verified, below.
if($bcrypt->verify($password, $stored_password) === true){ // using the verify method to compare the password with the stored hashed password.
return $id; // returning the user's id.
}else{
return false;
}
}catch(PDOException $e){
die($e->getMessage());
}
}
public function userdata($id) {
$query = $this->db->prepare("SELECT * FROM `users` WHERE `id`= ?");
$query->bindValue(1, $id);
try{
$query->execute();
return $query->fetch();
} catch(PDOException $e){
die($e->getMessage());
}
}
public function get_users() {
$query = $this->db->prepare("SELECT * FROM `users` ORDER BY `time` DESC");
try{
$query->execute();
}catch(PDOException $e){
die($e->getMessage());
}
return $query->fetchAll();
}
}
init.php:
<?php
session_start();
require($_SERVER['DOCUMENT_ROOT'].'/core/connect/database.php');
require($_SERVER['DOCUMENT_ROOT'].'/core/classes/users.php');
require($_SERVER['DOCUMENT_ROOT'].'/core/classes/general.php');
require($_SERVER['DOCUMENT_ROOT'].'/core/classes/bcrypt.php');
require($_SERVER['DOCUMENT_ROOT'].'/core/classes/garage.php');
// error_reporting(0);
$users = new Users($db);
$general = new General();
$bcrypt = new Bcrypt(12);
$errors = array();
if ($general->logged_in() === true) {
$user_id = $_SESSION['id'];
$user = $users->userdata($user_id);
}
ob_start();
Here is the js loading the files (its a bit weird because its reloading jscrollpane, but working fine with html and php that dosent need external classes):
// Ajax
$(function () {
var api = $("#garagecontent").jScrollPane().data('jsp');
var reinitialiseScrollPane = function()
{
api.reinitialise();
}
// attaching click handler to links
$(document).on('click', '#garagecontainer a[href]', function (e) {
// cancel the default behaviour
e.preventDefault();
// get the address of the link
var href = $(this).attr('href');
// getting the desired element for working with it later
var $wrap = $('#garagecontent');
$wrap
// removing old data
api.getContentPane()
// load the remote page
.load(href, reinitialiseScrollPane , function (){
}
);
});
});
I have narrowed it down to users.php because it will work when I remove it from the includes (and its functions in init.php).
Can anyone spot what is breaking my code?
The solution to this question was using an autoloader. The page was breaking because of duplicate classes being called. My fault for having errors disabled i guess.
Related
The password is hashed and enters the db when i try to verify it it returns false every time i have echoed out the password going in and the db password the column in the database is the correct size
<?php
require_once('dbconfig.php');
class USER
{
private $conn;
public function __construct()
{
$database = new Database();
$db = $database->dbConnection();
$this->conn = $db;
}
public function runQuery($sql)
{
$stmt = $this->conn->prepare($sql);
return $stmt;
}
public function register($uname, $umail, $upass)
{
try
{
$new_password = password_hash($upass, PASSWORD_DEFAULT);
$stmt = $this->conn->prepare("INSERT INTO USERS(USERNAME, EMAIL, PASSWORD) VALUES(:uname, :umail, :upass)");
$stmt->bindparam(":uname", $uname);
$stmt->bindparam(":umail", $umail);
$stmt->bindparam(":upass", $new_password);
$stmt->execute();
return $stmt;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
public function doLogin($uname, $umail, $upass)
{
try
{
$stmt = "SELECT USERID, USERNAME, EMAIL, PASSWORD, FIRSTNAME FROM USERS WHERE USERNAME = :uname OR EMAIL = :umail ";
$stmt = $this->conn->prepare($stmt, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$stmt->bindparam(':uname', $uname);
$stmt->bindparam(':umail', $umail);
$stmt->execute();
$userRow = $stmt->fetch(PDO::FETCH_ASSOC);
$db_password = $userRow['PASSWORD'];
$sql = "SELECT COUNT(*) FROM USERS WHERE USERNAME = :uname OR EMAIL = :umail";
$sql = $this->conn->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$sql->bindparam(':uname', $uname);
$sql->bindparam(':umail', $umail);
$sql->Execute();
$row = $sql->fetch(PDO::FETCH_ASSOC);
if($row == 1)
{
if(password_verify($upass, $userRow['PASSWORD']))
{
$_SESSION['USER_SESSION'] = $userRow['USERID'];
return true;
}
else
{
return false;
}
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
public function is_loggedin()
{
if(isset($_SESSION['USER_SESSION']))
{
return true;
}
}
public function redirect($url)
{
header("Location: $url");
}
public function doLogout()
{
session_destroy();
unset($_SESSION['USER_SESSION']);
return true;
}
}
?>
edit to the code i have added the whole user class but it is still returning false the password in the db looks like this $2y$10$16aMCo14n.QyON8dFsaFL..6Fi92LuBdWMCI3eAv3WHKJTblJKQ6q the column in the db is set to nvarchar (255) not null
I'm new to PHP, I created User class/object which has a function that checks for user, it returns $stmt->rowCount() but when I check for it in code it just skip it, register the user..
Here is the code:
if(empty($name_err) && empty($email_err) && empty($username_err) && empty($password_err) && empty($confirm_password_err)) {
if($user->doesUserExist($email) === 0) {
$password = password_hash($password, PASSWORD_DEFAULT);
$user->register($username, $name, $email, $password);
} else {
$global_err = "Email is already taken";
}
}
Here is the function from User class:
public function doesUserExist($email) {
$query = "SELECT * FROM users WHERE email = :email";
$stmt = $this->connection->prepare($query);
$stmt->bindParam(':email', $email);
$stmt->execute();
$rowcount = $stmt->rowCount($stmt);
return $rowcount;
}
instead of === in your condition of if($user->doesUserExist($email) === 0) try to change to ==
and then try to change your method like this:
public function doesUserExist($email) {
$query = "SELECT * FROM users WHERE email = '" . $email . "';";
$stmt = $this->connection->prepare($query);
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$rowcount = count($stmt->fetchAll());
return $rowcount;
}
You should Try
Call the function
$checkemail=$api->checkuseremail($email);
if($checkemail)
{
echo $mail_check;
}
and define your function like this
public function checkuseremail($email)
{
$db=getDB();
$stmt = $db->prepare("Select id from table_name where email=:email");
$stmt->bindParam("email", $email, PDO::PARAM_STR);
$stmt->execute();
$count = $stmt->rowCount();
if($count)
{
return true;
}
else
{
return false;
}
}
It will return email are already exist or not
im going to insane here, why he jump to else and return false all the time.
i dont understand what im doing wrong.
try
{
$query = 'SELECT userID, firstname, surname, email FROM jinx_users WHERE email = :email AND password = :password';
$this->dbh->beginTransaction();
$stmt = $this->dbh->prepare($query);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
$stmt->bindParam(':password', $password, PDO::PARAM_STR);
$stmt->execute();
if($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
return true;
}else{
return false;
}
$stmt = null;
}
catch (Exception $e)
{
$stmt = null;
$this->dbh->rollback();
exit();
}
The if statement is not a valid statement. Apart from that the Try Catch should be used to check if the database can succesfully be called or params can be set etc. Inside a try/catch you want to avoid return true or false. So with that being said I think what you want is the following:
try {
$query = 'SELECT userID, firstname, surname, email FROM jinx_users WHERE email = :email AND password = :password';
$this->dbh->beginTransaction();
$stmt = $this->dbh->prepare($query);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
$stmt->bindParam(':password', $password, PDO::PARAM_STR);
$stmt->execute();
} catch (Exception $e) {
var_dump($e->getMessage();
die();
}
if($stmt->fetch(PDO::FETCH_ASSOC)) {
return true;
} else {
return false;
}
I create this class but i'm newbie in PHP OOP & PDO and i don't know how and where i must to make check to username is valid , email is valid and e.t.c..
This is my code
Class Users {
private $db;
public function __construct(Database $datebase) {
if (!$database instanceOf Database) {
throw new Exeption();
}
$this->db = $datebase;
}
public function userRegistration($username, $password, $email) {
$username = $_POST['username'];
$password = $_POST['password'];
$email = $_POST['email'];
$regdate = date('d.m.Y');
$query = $this->db->prepare("INSERT INTO `users` (`username`, `password`, `email`, `regdate`) VALUES (?, ?, ?, ?) ");
$query->bindValue(1, $username);
$query->bindValue(2, $password);
$query->bindValue(3, $email);
$query->bindValue(4, $regdate);
return ($query->execute()) ? true : false ;
}
}
If you want to check something, use Respect/Validation. For example:
$usernameValidator = v::alnum()->noWhitespace()->length(1,15);
$usernameValidator->validate($_POST['username']); //true or false
$passwordValidator = v::alnum()->length(10, null);
$passwordValidator->validate($_POST['password']); //true or false
v::email()->validate($_POST['email']); //true or false
To check if the username or email exist in your database you can use SQL to search the email or username.
$query = $this->db->prepare("SELECT * FROM users WHERE email = ? ");
$query->bindValue(1, $email);
If the query returns a value than the email or username already exist in your database. From there you can show your own validation.
To check check if user or email exist you don't need another class, just add another method called userExist or emailExist and run a query and then check if you get a result.
public function emailExist($email){
$query = $this->db->prepare("SELECT * FROM users WHERE email = ? ");
$query->bindValue(1, $email);
try{
$query->execute();
//use the if statement and $query->rowCount() to check if there is a result
$rows = $query->rowCount();
if($rows === 1){
return true;
} else {
return false;
}
}catch (PDOException $e) {
die($e->getMessage());
}
}
I have the following php functions that process a user logging in. The functions are part of a class User.
/*
* detail() function to get a detail from a database
* exists() function to check if something exists in a database
*/
private function generate($password, $username = null) {
if(is_null($username)) {
$date = '0000-00-00';
} else {
$date = $this->_db->detail('last_active', 'users', 'username', $username);
}
// This is not the real thing but it will do as an example
$salt = md5(strrev($password.$date));
$password = md5($salt.$password.$date).strrev($password);
return $password;
}
public function login($data = array()) {
// Check if the user exists
$username = $data['username'];
if($this->_db->exists('username', 'users', 'username', $username)) {
$password = $this->generate($data['password'], $username);
// If the account is active
if ($this->_db->detail('active', 'users', 'username', $username) === 1) {
$stmt = $this->_db->mysqli->prepare("SELECT `username`, `password` FROM `users` WHERE `username` = ? AND `password` = ? AND `active` = 1");
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows >= 1) {
// Function to update last_active
if($this->updateLastActive($username)) {
// Function to update password
if($this->updatePassword($username, $this->generate($password, $username))) {
// Set the session
$this->_session->set('user', $this->_db->detail('id', 'users', 'username', $username));
if($this->_session->exists('user')) {
return true;
} else {
echo 'Logging in went wrong';
return false;
}
} else {
echo 'Editing the password went wrong';
return false;
}
} else {
echo 'Editing last active date went wrong';
return false;
}
} else {
echo 'Wrong username and password combination';
return false;
}
} else {
echo 'Account not active';
return false;
}
} else {
echo 'Username doesn\'t exists';
return false;
}
}
private function updateLastActive($username) {
$date = date('Y-m-d');
$stmt = $this->_db->mysqli->prepare("UPDATE `users` SET `last_active` = ? WHERE `username` = ?");
$stmt->bind_param('ss', $date, $username);
$stmt->execute();
if($stmt->affected_rows >= 1) {
return true;
} else {
return false;
}
}
private function updatePassword($username, $password) {
$stmt = $this->_db->mysqli->prepare("UPDATE `users` SET `password` = ? WHERE `username` = ?");
$stmt->bind_param('ss', $password, $username);
$stmt->execute();
if($stmt->affected_rows >= 1) {
return true;
} else {
return false;
}
}
The user can login with no problem when he just registered. But when the user is logged out and than tries to login again it will fail. The part I get an error on is the following:
$stmt = $this->_db->mysqli->prepare("SELECT `username`, `password` FROM `users` WHERE `username` = ? AND `password` = ? AND `active` = 1");
I tried to find out where the script fails with echo on different places in the functions but I couldn't find the error. The reason why the generate() function has $username = null is because the same function is used for registration.
So all functions are working but they only work once so this leaves me that someting in the generate() function is wrong. I always get the message that there is something wrong with the username / password combination
If someone could point me in the right direction I would be very happy.
Thanks in advance
UPDATE
The detail() and exists() functions are part of a class Database.
public function detail($detail, $table, $column, $value) {
if(is_array($detail)) {
$data = array();
foreach($detail as $key) {
$stmt = $this->mysqli->prepare("SELECT `$key` FROM `$table` WHERE `$column` = ?");
if(is_numeric($value)) {
$stmt->bind_param('i', $value);
} else {
$stmt->bind_param('s', $value);
}
$stmt->execute();
$stmt->bind_result($detail);
$stmt->fetch();
$data[] = $detail;
$stmt = null;
}
return $data;
} else {
$stmt = $this->mysqli->prepare("SELECT `$detail` FROM `$table` WHERE `$column` = ?");
if(is_numeric($value)) {
$stmt->bind_param('i', $value);
} else {
$stmt->bind_param('s', $value);
}
$stmt->execute();
$stmt->bind_result($detail);
$stmt->fetch();
return $detail;
}
}
public function exists($detail, $table, $column, $value) {
$stmt = $this->mysqli->prepare("SELECT `$detail` FROM `$table` WHERE `$column` = ?");
switch(is_numeric($value)) {
case true:
$stmt->bind_param('i', $value);
break;
case false:
$stmt->bind_param('s', $value);
break;
}
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows >= 1) {
return true;
} else {
return false;
}
}
Create a hash field in your table, make it long enough to avoid length issue.
md5() is not acceptable now, you should be using better hash function such as password_hash()
Register:
private function register($username, $password) {
//safer than md5() anyway
$hash = password_hash($password, PASSWORD_DEFAULT);
$sql = 'INSERT INTO table_name (`username`, `hash`) VALUES (?, ?);'
$stmt = $this->_db->mysqli->prepare($sql);
$stmt->bind_param('ss', $username, $hash);
$stmt->execute();
if($stmt->affected_rows >= 1) {
return true;
} else {
return false;
}
}
Login :
public function login($username, $password) {
// Check if the user exists
if($this->_db->exists('username', 'users', 'username', $username)) {
// If the account is active
if ($this->_db->detail('active', 'users', 'username', $username) === 1) {
$sql = 'SELECT `username`, `hash` FROM `users` WHERE `username` = ? AND `active` = 1';
$stmt = $this->_db->mysqli->prepare();
$stmt->bind_param('ss', $username, $hash);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows === 1) {
if (password_verify($password, $hash)) {
// Function to update last_active
if($this->updateLastActive($username)) {
echo 'last active updated, Login successful';
return true;
} else {
echo 'Editing last active date went wrong';
return false;
}
} else {
echo 'Wrong username and password combination';
return false;
}
} else {
echo 'Account not active';
return false;
}
} else {
echo 'Username doesn\'t exists';
return false;
}
}
}
Of course you can still use custom salt, for example
$hash = password_hash($password
,PASSWORD_DEFAULT
,array('salt' =>generate()));//generate() returns the salt