Unable to get data from session after browser restart in php - php

Am using following lib to manage session, Am storing session values in database, everything works great i can get and set session values.
But after restart i can't get session values.
When i try to set session values i creates new row in database instead of updating.
LIB.php
<?php
/**
* #category Security
* #version 1.0
* #author First Last
* */
class mySessionHandler {
private $_db = NULL;
private $_table_name = 'sessions';
private $_cookie_name = 'session_cookie';
private $_seconds_till_expiration = 43200; // 2 hours
private $_renewal_time = 300; // 5 minutes
private $_expire_on_close = FALSE;
private $_ip_address = FALSE;
private $_user_agent = FALSE;
private $_secure_cookie = FALSE;
private $_session_id = FALSE;
private $_data = array();
public function __construct(array $config) {
$this->_setConfig($config);
if ($this->_read()) {
$this->_update();
} else {
$this->_create();
}
$this->_cleanExpired();
$this->_setCookie();
}
public function regenerateId() {
$old_session_id = $this->_session_id;
$this->_session_id = $this->_generateId();
$stmt = $this->_db->prepare("UPDATE {$this->_table_name} SET time_updated = ?, session_id = ? WHERE session_id = ?");
$stmt->execute(array(time(), $this->_session_id, $old_session_id));
$this->_setCookie();
}
public function setData($key, $value) {
$this->_data[$key] = $value;
$this->_write();
}
public function unsetData($key) {
if (isset($this->_data[$key])) {
unset($this->_data[$key]);
}
}
function getData($key) {
return isset($this->_data[$key]) ? $this->_data[$key] : FALSE;
}
public function getAllData() {
return $this->_data;
}
public function destroy() {
if (isset($this->_session_id)) {
$stmt = $this->_db->prepare("DELETE FROM {$this->_table_name} WHERE session_id = ?");
$stmt->execute(array($this->_session_id));
}
setcookie($this->_cookie_name, '', time() - 31500000, NULL, NULL, NULL, NULL);
}
private function _read() {
$session_id = filter_input(INPUT_COOKIE, $this->_cookie_name) ? filter_input(INPUT_COOKIE, $this->_cookie_name) : FALSE;
if (!$session_id) {
return FALSE;
}
$this->_session_id = $session_id;
$stmt = $this->_db->prepare("SELECT data, time_updated, user_agent, ip_address FROM {$this->_table_name} WHERE session_id = ?");
$stmt->execute(array($this->_session_id));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if ($result !== FALSE && count($result) > 0) {
if (!$this->_expire_on_close && (($result['time_updated'] + $this->_seconds_till_expiration) < time())) {
$this->destroy();
return FALSE;
}
if ($this->_ip_address && ($result['ip_address'] != $this->_ip_address)) {
$this->_flagForUpdate();
return FALSE;
}
if ($this->_user_agent && ($result['user_agent'] != $this->_user_agent)) {
$this->_flagForUpdate();
return FALSE;
}
$this->_checkUpdateFlag();
$this->_checkIdRenewal();
$user_data = unserialize($result['data']);
if ($user_data) {
$this->_data = $user_data;
unset($user_data);
}return TRUE;
}return FALSE;
}
private function _create() {
$this->_session_id = $this->_generateId();
$stmt = $this->_db->prepare("INSERT INTO {$this->_table_name} (session_id, user_agent, ip_address, time_updated) VALUES (?, ?, ?, ?)");
$stmt->execute(array($this->_session_id, $this->_user_agent, $this->_ip_address, time()));
}
private function _update() {
$stmt = $this->_db->prepare("UPDATE {$this->_table_name} SET time_updated = ? WHERE session_id = ?");
$stmt->execute(array(time(), $this->_session_id));
}
private function _write() {
if (count($this->_data) == 0) {
$custom_data = '';
} else {
$custom_data = serialize($this->_data);
}
$stmt = $this->_db->prepare("UPDATE {$this->_table_name} SET data = ?, time_updated = ? WHERE session_id = ?");
$stmt->execute(array($custom_data, time(), $this->_session_id));
}
private function _setCookie() {
setcookie(
$this->_cookie_name, $this->_session_id, ($this->_expire_on_close) ? 0 : time() + $this->_seconds_till_expiration, // Expiration timestamp
NULL, NULL, $this->_secure_cookie, // Will cookie be set without HTTPS?
TRUE // HttpOnly
);
}
private function _cleanExpired() {
if (mt_rand(1, 1000) == 1) {
$stmt = $this->_db->prepare("DELETE FROM {$this->_table_name} WHERE (time_updated + {$this->_seconds_till_expiration}) < ?");
$stmt->execute(array(time()));
}
}
function _generateId() {
$salt = 'x7^!bo3p,.$$!$6[&Q.#,//#i"%[X';
$random_number = '9085723012206';
$random_txt = 'sanoj';
$ip_address_fragment = md5(substr(filter_input(INPUT_SERVER, 'REMOTE_ADDR'), 0, 5));
$hash_data = $random_number . $ip_address_fragment . $random_txt . $salt;
$hash = hash('sha256', $hash_data);
return $hash;
}
private function _checkIdRenewal() {
$stmt = $this->_db->prepare("SELECT time_updated FROM {$this->_table_name} WHERE session_id = ?");
$stmt->execute(array($this->_session_id));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if ($result !== FALSE && count($result) > 0) {
if ((time() - $this->_renewal_time) > $result['time_updated']) {
$this->regenerateId();
}
}
}
private function _flagForUpdate() {
$stmt = $this->_db->prepare("UPDATE {$this->_table_name} SET flagged_for_update = '1' WHERE session_id = ?");
$stmt->execute(array($this->_session_id));
}
private function _checkUpdateFlag() {
$stmt = $this->_db->prepare("SELECT flagged_for_update FROM {$this->_table_name} WHERE session_id = ?");
$stmt->execute(array($this->_session_id));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if ($result !== FALSE && count($result) > 0) {
if ($result['flagged_for_update']) {
$this->regenerateId();
$stmt = $this->_db->prepare("UPDATE {$this->_table_name} SET flagged_for_update = '0' WHERE session_id = ?");
$stmt->execute(array($this->_session_id));
}
}
}
private function _setConfig(array $config) {
if (isset($config['database'])) {
$this->_db = $config['database'];
} else {
throw new Exception('Database handle not set!');
}
if (isset($config['cookie_name'])) {
if (!ctype_alnum(str_replace(array('-', '_'), '', $config['cookie_name']))) {
throw new Exception('Invalid cookie name!');
} $this->_cookie_name = $config['cookie_name'];
}
if (isset($config['table_name'])) {
if (!ctype_alnum(str_replace(array('-', '_'), '', $config['table_name']))) {
throw new Exception('Invalid table name!');
} $this->_table_name = $config['table_name'];
}
if (isset($config['seconds_till_expiration'])) {
if (!is_int($config['seconds_till_expiration']) || !preg_match('#[0-9]#', $config['seconds_till_expiration'])) {
throw new Exception('Seconds till expiration must be a valid number.');
}
if ($config['seconds_till_expiration'] < 1) {
throw new Exception('Seconds till expiration can not be zero or less. Enable session expiration when the browser closes instead.');
}
$this->_seconds_till_expiration = (int) $config['seconds_till_expiration'];
}
if (isset($config['expire_on_close'])) {
if (!is_bool($config['expire_on_close'])) {
throw new Exception('Expire on close must be either TRUE or FALSE.');
}
$this->_expire_on_close = $config['expire_on_close'];
}
if (isset($config['renewal_time'])) {
if (!is_int($config['renewal_time']) || !preg_match('#[0-9]#', $config['renewal_time'])) {
throw new Exception('Session renewal time must be a valid number.');
}
if ($config['renewal_time'] < 1) {
throw new Exception('Session renewal time can not be zero or less.');
}
$this->_renewal_time = (int) $config['renewal_time'];
}
if (isset($config['check_ip_address'])) {
if (!is_string($config['check_ip_address'])) {
throw new Exception('The IP address must be a string similar to this: \'172.16.254.1\'.');
}
if (!preg_match('/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/', $config['check_ip_address'])) {
throw new Exception('Invalid IP address.');
}
$this->_ip_address = $config['check_ip_address'];
}
if (isset($config['check_user_agent'])) {
$this->_user_agent = substr($config['check_user_agent'], 0, 999);
} if (isset($config['secure_cookie'])) {
if (!is_bool($config['secure_cookie'])) {
throw new Exception('The secure cookie option must be either TRUE or FALSE.');
}
$this->_secure_cookie = $config['secure_cookie'];
}
}
}
How do i get session values even after restarting browser,
GET.PHP
ob_start();
session_start();
include_once('index.php');
echo $session->getData('fname').'<br>';
echo $session->getData('password').'<br>';
echo $session->getData('email').'<br>';
SET.PHP
ob_start();
session_start();
include_once('index.php');
$session->setData('fname', 'first last');
$session->setData('password', '123456');
$session->setData('email', 'first#last.com');
$sesi = $session->_generateId();
echo $sesi;
$_SESSION['test'] = $sesi;

try replacing _setCookie() so that your cookie won't expire
private function _setCookie() {
setcookie($this->_cookie_name, $this->_session_id, ($this->_expire_on_close) ? 0 : time() + (10 * 365 * 24 * 60 * 60), //Expiration timestamp
NULL, NULL, $this->_secure_cookie, // Will cookie be set without HTTPS?
TRUE // HttpOnly
);
}

Related

Class not found when include is working

I have these files:
/index.php
/Auth.class.php
/Config.class.php
/logcheck.php
/register.php
I am trying to include Auth.class.php and Config.class.php in register.php and logcheck.php, which is working fine like this:
include("Auth.class.php");
include("Config.class.php");
But when i'm trying to create an object of one of these classes in register.php i'm getting the Fatal Error: Class 'Config' not found in.... error message.
The imports are working but creating an object not. Config.class.php and Auth.class.php both belong to PHPAuth. I didn't use short tags. If you need any more information, just ask.
Edit:
register.php
<?php
include("languages/en_GB.php");
include("Config.class.php");
include("Auth.class.php");
$dbh = new PDO("mysql:host=localhost;dbname=phpauth", "root", "");
$config = new Config($dbh);
$auth = new Auth($dbh, $config, $lang);
$register = $auth->register($_POST['email'], $_POST['password'], $_POST['password']);
if($register['error']) {
// Something went wrong, display error message
echo '<div class="error">' . $register['message'] . '</div>';
} else {
// Logged in successfully, set cookie, display success message
/* setcookie($config->cookie_name, $login['hash'], $login['expire'], $config->cookie_path, $config->cookie_domain, $config->cookie_secure, $config->cookie_http);*/
echo '<div class="success">' . $login['message'] . '</div>';
}
?>
Config.class.php
<?php
namespace PHPAuth;
/**
* PHPAuth Config class
*/
class Config
{
private $dbh;
private $config;
private $config_table = 'config';
/**
*
* Config::__construct()
*
* #param \PDO $dbh
* #param string $config_table
*/
public function __construct(\PDO $dbh, $config_table = 'config')
{
$this->dbh = $dbh;
if (func_num_args() > 1)
$this->config_table = $config_table;
$this->config = array();
$query = $this->dbh->query("SELECT * FROM {$this->config_table}");
while($row = $query->fetch()) {
$this->config[$row['setting']] = $row['value'];
}
$this->setForgottenDefaults(); // Danger foreseen is half avoided.
}
/**
* Config::__get()
*
* #param mixed $setting
* #return string
*/
public function __get($setting)
{
return $this->config[$setting];
}
/**
* Config::__set()
*
* #param mixed $setting
* #param mixed $value
* #return bool
*/
public function __set($setting, $value)
{
$query = $this->dbh->prepare("UPDATE {$this->config_table} SET value = ? WHERE setting = ?");
if($query->execute(array($value, $setting))) {
$this->config[$setting] = $value;
return true;
}
return false;
}
/**
* Config::override()
*
* #param mixed $setting
* #param mixed $value
* #return bool
*/
public function override($setting, $value){
$this->config[$setting] = $value;
return true;
}
/**
* Danger foreseen is half avoided.
*
* Set default values.
* REQUIRED FOR USERS THAT DOES NOT UPDATE THEIR `config` TABLES.
*/
private function setForgottenDefaults()
{
// verify* values.
if (! isset($this->config['verify_password_min_length']) )
$this->config['verify_password_min_length'] = 3;
if (! isset($this->config['verify_password_max_length']) )
$this->config['verify_password_max_length'] = 150;
if (! isset($this->config['verify_password_strong_requirements']) )
$this->config['verify_password_strong_requirements'] = 1;
if (! isset($this->config['verify_email_min_length']) )
$this->config['verify_email_min_length'] = 5;
if (! isset($this->config['verify_email_max_length']) )
$this->config['verify_email_max_length'] = 100;
if (! isset($this->config['verify_email_use_banlist']) )
$this->config['verify_email_use_banlist'] = 1;
// emailmessage* values
if (! isset($this->config['emailmessage_suppress_activation']) )
$this->config['emailmessage_suppress_activation'] = 0;
if (! isset($this->config['emailmessage_suppress_reset']) )
$this->config['emailmessage_suppress_reset'] = 0;
}
}
Auth.class.php
<?php
namespace PHPAuth;
use ZxcvbnPhp\Zxcvbn;
use PHPMailer\PHPMailer\PHPMailer;
/***
* Auth class
* Required PHP 5.4 and above.
*/
class Auth
{
private $dbh;
public $config;
public $lang;
/***
* Initiates database connection
*/
public function __construct(\PDO $dbh, $config, $language = "en_GB")
{
$this->dbh = $dbh;
$this->config = $config;
if (version_compare(phpversion(), '5.4.0', '<')) {
die('PHP 5.4.0 required for PHPAuth engine!');
}
if (version_compare(phpversion(), '5.5.0', '<')) {
require("files/password.php");
}
// Load language
require "languages/{$language}.php";
$this->lang = $lang;
date_default_timezone_set($this->config->site_timezone);
}
/***
* Logs a user in
* #param string $email
* #param string $password
* #param int $remember
* #param string $captcha = NULL
* #return array $return
*/
public function login($email, $password, $remember = 0, $captcha = NULL)
{
$return['error'] = true;
$block_status = $this->isBlocked();
if($block_status == "verify")
{
if($this->checkCaptcha($captcha) == false)
{
$return['message'] = $this->lang["user_verify_failed"];
return $return;
}
}
if ($block_status == "block") {
$return['message'] = $this->lang["user_blocked"];
return $return;
}
$validateEmail = $this->validateEmail($email);
$validatePassword = $this->validatePassword($password);
if ($validateEmail['error'] == 1) {
$this->addAttempt();
$return['message'] = $this->lang["email_password_invalid"];
return $return;
} elseif($validatePassword['error'] == 1) {
$this->addAttempt();
$return['message'] = $this->lang["email_password_invalid"];
return $return;
} elseif($remember != 0 && $remember != 1) {
$this->addAttempt();
$return['message'] = $this->lang["remember_me_invalid"];
return $return;
}
$uid = $this->getUID(strtolower($email));
if(!$uid) {
$this->addAttempt();
$return['message'] = $this->lang["email_password_incorrect"];
return $return;
}
$user = $this->getBaseUser($uid);
if (!password_verify($password, $user['password'])) {
$this->addAttempt();
$return['message'] = $this->lang["email_password_incorrect"];
return $return;
}
if ($user['isactive'] != 1) {
$this->addAttempt();
$return['message'] = $this->lang["account_inactive"];
return $return;
}
$sessiondata = $this->addSession($user['uid'], $remember);
if($sessiondata == false) {
$return['message'] = $this->lang["system_error"] . " #01";
return $return;
}
$return['error'] = false;
$return['message'] = $this->lang["logged_in"];
$return['hash'] = $sessiondata['hash'];
$return['expire'] = $sessiondata['expiretime'];
return $return;
}
/***
* Creates a new user, adds them to database
* #param string $email
* #param string $password
* #param string $repeatpassword
* #param array $params
* #param string $captcha = NULL
* #param bool $sendmail = NULL
* #return array $return
*/
public function register($email, $password, $repeatpassword, $params = Array(), $captcha = NULL, $sendmail = NULL)
{
$return['error'] = true;
$block_status = $this->isBlocked();
if($block_status == "verify")
{
if($this->checkCaptcha($captcha) == false)
{
$return['message'] = $this->lang["user_verify_failed"];
return $return;
}
}
if ($block_status == "block") {
$return['message'] = $this->lang["user_blocked"];
return $return;
}
if ($password !== $repeatpassword) {
$return['message'] = $this->lang["password_nomatch"];
return $return;
}
// Validate email
$validateEmail = $this->validateEmail($email);
if ($validateEmail['error'] == 1) {
$return['message'] = $validateEmail['message'];
return $return;
}
// Validate password
$validatePassword = $this->validatePassword($password);
if ($validatePassword['error'] == 1) {
$return['message'] = $validatePassword['message'];
return $return;
}
$zxcvbn = new Zxcvbn();
if($zxcvbn->passwordStrength($password)['score'] < intval($this->config->password_min_score)) {
$return['message'] = $this->lang['password_weak'];
return $return;
}
if ($this->isEmailTaken($email)) {
$this->addAttempt();
$return['message'] = $this->lang["email_taken"];
return $return;
}
$addUser = $this->addUser($email, $password, $params, $sendmail);
if($addUser['error'] != 0) {
$return['message'] = $addUser['message'];
return $return;
}
$return['error'] = false;
$return['message'] = ($sendmail == true ? $this->lang["register_success"] : $this->lang['register_success_emailmessage_suppressed'] );
return $return;
}
/***
* Activates a user's account
* #param string $key
* #return array $return
*/
public function activate($key)
{
$return['error'] = true;
$block_status = $this->isBlocked();
if ($block_status == "block") {
$return['message'] = $this->lang["user_blocked"];
return $return;
}
if(strlen($key) !== 20) {
$this->addAttempt();
$return['message'] = $this->lang["activationkey_invalid"];
return $return;
}
$getRequest = $this->getRequest($key, "activation");
if($getRequest['error'] == 1) {
$return['message'] = $getRequest['message'];
return $return;
}
if($this->getBaseUser($getRequest['uid'])['isactive'] == 1) {
$this->addAttempt();
$this->deleteRequest($getRequest['id']);
$return['message'] = $this->lang["system_error"] . " #02";
return $return;
}
$query = $this->dbh->prepare("UPDATE {$this->config->table_users} SET isactive = ? WHERE id = ?");
$query->execute(array(1, $getRequest['uid']));
$this->deleteRequest($getRequest['id']);
$return['error'] = false;
$return['message'] = $this->lang["account_activated"];
return $return;
}
/***
* Creates a reset key for an email address and sends email
* #param string $email
* #return array $return
*/
public function requestReset($email, $sendmail = NULL)
{
$return['error'] = true;
$block_status = $this->isBlocked();
if ($block_status == "block") {
$return['message'] = $this->lang["user_blocked"];
return $return;
}
$validateEmail = $this->validateEmail($email);
if ($validateEmail['error'] == 1) {
$return['message'] = $this->lang["email_invalid"];
return $return;
}
$query = $this->dbh->prepare("SELECT id FROM {$this->config->table_users} WHERE email = ?");
$query->execute(array($email));
if ($query->rowCount() == 0) {
$this->addAttempt();
$return['message'] = $this->lang["email_incorrect"];
return $return;
}
$addRequest = $this->addRequest($query->fetch(\PDO::FETCH_ASSOC)['id'], $email, "reset", $sendmail);
if ($addRequest['error'] == 1) {
$this->addAttempt();
$return['message'] = $addRequest['message'];
return $return;
}
$return['error'] = false;
$return['message'] = ($sendmail == true ? $this->lang["reset_requested"] : $this->lang['reset_requested_emailmessage_suppressed']);
return $return;
}
/***
* Logs out the session, identified by hash
* #param string $hash
* #return boolean
*/
public function logout($hash)
{
if (strlen($hash) != 40) {
return false;
}
return $this->deleteSession($hash);
}
/***
* Hashes provided password with Bcrypt
* #param string $password
* #param string $password
* #return string
*/
public function getHash($password)
{
return password_hash($password, PASSWORD_BCRYPT, ['cost' => $this->config->bcrypt_cost]);
}
/***
* Gets UID for a given email address and returns an array
* #param string $email
* #return array $uid
*/
public function getUID($email)
{
$query = $this->dbh->prepare("SELECT id FROM {$this->config->table_users} WHERE email = ?");
$query->execute(array($email));
if($query->rowCount() == 0) {
return false;
}
return $query->fetch(\PDO::FETCH_ASSOC)['id'];
}
/***
* Creates a session for a specified user id
* #param int $uid
* #param boolean $remember
* #return array $data
*/
private function addSession($uid, $remember)
{
$ip = $this->getIp();
$user = $this->getBaseUser($uid);
if(!$user) {
return false;
}
$data['hash'] = sha1($this->config->site_key . microtime());
$agent = $_SERVER['HTTP_USER_AGENT'];
$this->deleteExistingSessions($uid);
if($remember == true) {
$data['expire'] = date("Y-m-d H:i:s", strtotime($this->config->cookie_remember));
$data['expiretime'] = strtotime($data['expire']);
} else {
$data['expire'] = date("Y-m-d H:i:s", strtotime($this->config->cookie_forget));
$data['expiretime'] = 0;
}
$data['cookie_crc'] = sha1($data['hash'] . $this->config->site_key);
$query = $this->dbh->prepare("INSERT INTO {$this->config->table_sessions} (uid, hash, expiredate, ip, agent, cookie_crc) VALUES (?, ?, ?, ?, ?, ?)");
if(!$query->execute(array($uid, $data['hash'], $data['expire'], $ip, $agent, $data['cookie_crc']))) {
return false;
}
$data['expire'] = strtotime($data['expire']);
return $data;
}
/***
* Removes all existing sessions for a given UID
* #param int $uid
* #return boolean
*/
private function deleteExistingSessions($uid)
{
$query = $this->dbh->prepare("DELETE FROM {$this->config->table_sessions} WHERE uid = ?");
$query->execute(array($uid));
return $query->rowCount() == 1;
}
/***
* Removes a session based on hash
* #param string $hash
* #return boolean
*/
private function deleteSession($hash)
{
$query = $this->dbh->prepare("DELETE FROM {$this->config->table_sessions} WHERE hash = ?");
$query->execute(array($hash));
return $query->rowCount() == 1;
}
/**
* Function to check if a session is valid
* #param string $hash
* #return boolean
*/
public function checkSession($hash)
{
$ip = $this->getIp();
$block_status = $this->isBlocked();
if ($block_status == "block") {
$return['message'] = $this->lang["user_blocked"];
return false;
}
if (strlen($hash) != 40) {
return false;
}
$query = $this->dbh->prepare("SELECT id, uid, expiredate, ip, agent, cookie_crc FROM {$this->config->table_sessions} WHERE hash = ?");
$query->execute(array($hash));
if ($query->rowCount() == 0) {
return false;
}
$row = $query->fetch(\PDO::FETCH_ASSOC);
$sid = $row['id'];
$uid = $row['uid'];
$expiredate = strtotime($row['expiredate']);
$currentdate = strtotime(date("Y-m-d H:i:s"));
$db_ip = $row['ip'];
$db_agent = $row['agent'];
$db_cookie = $row['cookie_crc'];
if ($currentdate > $expiredate) {
$this->deleteExistingSessions($uid);
return false;
}
if ($ip != $db_ip) {
return false;
}
if ($db_cookie == sha1($hash . $this->config->site_key)) {
return true;
}
return false;
}
/**
* Retrieves the UID associated with a given session hash
* #param string $hash
* #return int $uid
*/
public function getSessionUID($hash)
{
$query = $this->dbh->prepare("SELECT uid FROM {$this->config->table_sessions} WHERE hash = ?");
$query->execute(array($hash));
if ($query->rowCount() == 0) {
return false;
}
return $query->fetch(\PDO::FETCH_ASSOC)['uid'];
}
/**
* Checks if an email is already in use
* #param string $email
* #return boolean
*/
public function isEmailTaken($email)
{
$query = $this->dbh->prepare("SELECT count(*) FROM {$this->config->table_users} WHERE email = ?");
$query->execute(array($email));
if ($query->fetchColumn() == 0) {
return false;
}
return true;
}
/**
* Adds a new user to database
* #param string $email -- email
* #param string $password -- password
* #param array $params -- additional params
* #return int $uid
*/
private function addUser($email, $password, $params = array(), &$sendmail)
{
$return['error'] = true;
$query = $this->dbh->prepare("INSERT INTO {$this->config->table_users} VALUES ()");
if(!$query->execute()) {
$return['message'] = $this->lang["system_error"] . " #03";
return $return;
}
$uid = $this->dbh->lastInsertId();
$email = htmlentities(strtolower($email));
if($sendmail) {
$addRequest = $this->addRequest($uid, $email, "activation", $sendmail);
if($addRequest['error'] == 1) {
$query = $this->dbh->prepare("DELETE FROM {$this->config->table_users} WHERE id = ?");
$query->execute(array($uid));
$return['message'] = $addRequest['message'];
return $return;
}
$isactive = 0;
} else {
$isactive = 1;
}
$password = $this->getHash($password);
if (is_array($params)&& count($params) > 0) {
$customParamsQueryArray = Array();
foreach($params as $paramKey => $paramValue) {
$customParamsQueryArray[] = array('value' => $paramKey . ' = ?');
}
$setParams = ', ' . implode(', ', array_map(function ($entry) {
return $entry['value'];
}, $customParamsQueryArray));
} else { $setParams = ''; }
$query = $this->dbh->prepare("UPDATE {$this->config->table_users} SET email = ?, password = ?, isactive = ? {$setParams} WHERE id = ?");
$bindParams = array_values(array_merge(array($email, $password, $isactive), $params, array($uid)));
if(!$query->execute($bindParams)) {
$query = $this->dbh->prepare("DELETE FROM {$this->config->table_users} WHERE id = ?");
$query->execute(array($uid));
$return['message'] = $this->lang["system_error"] . " #04";
return $return;
}
$return['error'] = false;
return $return;
}
/**
* Gets basic user data for a given UID and returns an array
* #param int $uid
* #return array $data
*/
private function getBaseUser($uid)
{
$query = $this->dbh->prepare("SELECT email, password, isactive FROM {$this->config->table_users} WHERE id = ?");
$query->execute(array($uid));
if ($query->rowCount() == 0) {
return false;
}
$data = $query->fetch(\PDO::FETCH_ASSOC);
if (!$data) {
return false;
}
$data['uid'] = $uid;
return $data;
}
/**
* Gets public user data for a given UID and returns an array, password is not returned
* #param int $uid
* #return array $data
*/
public function getUser($uid)
{
$query = $this->dbh->prepare("SELECT * FROM {$this->config->table_users} WHERE id = ?");
$query->execute(array($uid));
if ($query->rowCount() == 0) {
return false;
}
$data = $query->fetch(\PDO::FETCH_ASSOC);
if (!$data) {
return false;
}
$data['uid'] = $uid;
unset($data['password']);
return $data;
}
/**
* Allows a user to delete their account
* #param int $uid
* #param string $password
* #param string $captcha = NULL
* #return array $return
*/
public function deleteUser($uid, $password, $captcha = NULL)
{
$return['error'] = true;
$block_status = $this->isBlocked();
if($block_status == "verify")
{
if($this->checkCaptcha($captcha) == false)
{
$return['message'] = $this->lang["user_verify_failed"];
return $return;
}
}
if ($block_status == "block") {
$return['message'] = $this->lang["user_blocked"];
return $return;
}
$validatePassword = $this->validatePassword($password);
if($validatePassword['error'] == 1) {
$this->addAttempt();
$return['message'] = $validatePassword['message'];
return $return;
}
$user = $this->getBaseUser($uid);
if(!password_verify($password, $user['password'])) {
$this->addAttempt();
$return['message'] = $this->lang["password_incorrect"];
return $return;
}
$query = $this->dbh->prepare("DELETE FROM {$this->config->table_users} WHERE id = ?");
if(!$query->execute(array($uid))) {
$return['message'] = $this->lang["system_error"] . " #05";
return $return;
}
$query = $this->dbh->prepare("DELETE FROM {$this->config->table_sessions} WHERE uid = ?");
if(!$query->execute(array($uid))) {
$return['message'] = $this->lang["system_error"] . " #06";
return $return;
}
$query = $this->dbh->prepare("DELETE FROM {$this->config->table_requests} WHERE uid = ?");
if(!$query->execute(array($uid))) {
$return['message'] = $this->lang["system_error"] . " #07";
return $return;
}
$return['error'] = false;
$return['message'] = $this->lang["account_deleted"];
return $return;
}
/**
* Creates an activation entry and sends email to user
* #param int $uid
* #param string $email
* #param string $type
* #param boolean $sendmail = NULL
* #return boolean
*/
private function addRequest($uid, $email, $type, &$sendmail)
{
$return['error'] = true;
if($type != "activation" && $type != "reset") {
$return['message'] = $this->lang["system_error"] . " #08";
return $return;
}
// if not set manually, check config data
if($sendmail === NULL)
{
$sendmail = true;
if($type == "reset" && $this->config->emailmessage_suppress_reset === true ) {
$sendmail = false;
$return['error'] = false;
return $return;
}
if ($type == "activation" && $this->config->emailmessage_suppress_activation === true ) {
$sendmail = false;
$return['error'] = false;
return $return;
}
}
$query = $this->dbh->prepare("SELECT id, expire FROM {$this->config->table_requests} WHERE uid = ? AND type = ?");
$query->execute(array($uid, $type));
if($query->rowCount() > 0) {
$row = $query->fetch(\PDO::FETCH_ASSOC);
$expiredate = strtotime($row['expire']);
$currentdate = strtotime(date("Y-m-d H:i:s"));
if ($currentdate < $expiredate) {
$return['message'] = $this->lang["reset_exists"];
return $return;
}
$this->deleteRequest($row['id']);
}
if($type == "activation" && $this->getBaseUser($uid)['isactive'] == 1) {
$return['message'] = $this->lang["already_activated"];
return $return;
}
$key = $this->getRandomKey(20);
$expire = date("Y-m-d H:i:s", strtotime($this->config->request_key_expiration));
$query = $this->dbh->prepare("INSERT INTO {$this->config->table_requests} (uid, rkey, expire, type) VALUES (?, ?, ?, ?)");
if(!$query->execute(array($uid, $key, $expire, $type))) {
$return['message'] = $this->lang["system_error"] . " #09";
return $return;
}
$request_id = $this->dbh->lastInsertId();
if($sendmail === true)
{
// Check configuration for SMTP parameters
$mail = new PHPMailer;
if($this->config->smtp) {
$mail->isSMTP();
$mail->Host = $this->config->smtp_host;
$mail->SMTPAuth = $this->config->smtp_auth;
if(!is_null($this->config->smtp_auth)) {
$mail->Username = $this->config->smtp_username;
$mail->Password = $this->config->smtp_password;
}
$mail->Port = $this->config->smtp_port;
if(!is_null($this->config->smtp_security)) {
$mail->SMTPSecure = $this->config->smtp_security;
}
}
$mail->From = $this->config->site_email;
$mail->FromName = $this->config->site_name;
$mail->addAddress($email);
$mail->isHTML(true);
if($type == "activation") {
$mail->Subject = sprintf($this->lang['email_activation_subject'], $this->config->site_name);
$mail->Body = sprintf($this->lang['email_activation_body'], $this->config->site_url, $this->config->site_activation_page, $key);
$mail->AltBody = sprintf($this->lang['email_activation_altbody'], $this->config->site_url, $this->config->site_activation_page, $key);
}
else {
$mail->Subject = sprintf($this->lang['email_reset_subject'], $this->config->site_name);
$mail->Body = sprintf($this->lang['email_reset_body'], $this->config->site_url, $this->config->site_password_reset_page, $key);
$mail->AltBody = sprintf($this->lang['email_reset_altbody'], $this->config->site_url, $this->config->site_password_reset_page, $key);
}
if(!$mail->send()) {
$this->deleteRequest($request_id);
$return['message'] = $this->lang["system_error"] . " #10";
return $return;
}
}
$return['error'] = false;
return $return;
}
/**
* Returns request data if key is valid
* #param string $key
* #param string $type
* #return array $return
*/
public function getRequest($key, $type)
{
$return['error'] = true;
$query = $this->dbh->prepare("SELECT id, uid, expire FROM {$this->config->table_requests} WHERE rkey = ? AND type = ?");
$query->execute(array($key, $type));
if ($query->rowCount() === 0) {
$this->addAttempt();
$return['message'] = $this->lang[$type."key_incorrect"];
return $return;
}
$row = $query->fetch();
$expiredate = strtotime($row['expire']);
$currentdate = strtotime(date("Y-m-d H:i:s"));
if ($currentdate > $expiredate) {
$this->addAttempt();
$this->deleteRequest($row['id']);
$return['message'] = $this->lang[$type."key_expired"];
return $return;
}
$return['error'] = false;
$return['id'] = $row['id'];
$return['uid'] = $row['uid'];
return $return;
}
/**
* Deletes request from database
* #param int $id
* #return boolean
*/
private function deleteRequest($id)
{
$query = $this->dbh->prepare("DELETE FROM {$this->config->table_requests} WHERE id = ?");
return $query->execute(array($id));
}
/**
* Verifies that a password is valid and respects security requirements
* #param string $password
* #return array $return
*/
File goes on but Character-Limitation is reached, I also don't think that the main code itself is necessary.
As pointed out by #Jeff in the comments, you have a namespace problem in register.php,
You can do one of the following,
Use use :
If you would use use your register.php would look like:
<?php
include("languages/en_GB.php");
include("Config.class.php");
include("Auth.class.php");
use \PHPAuth\{Config, Auth};
$dbh = new \PDO("mysql:host=localhost;dbname=phpauth", "root", "");
$config = new Config($dbh);
$auth = new Auth($dbh, $config, $lang);
$register = $auth->register($_POST['email'], $_POST['password'], $_POST['password']);
if($register['error']) {
// Something went wrong, display error message
echo '<div class="error">' . $register['message'] . '</div>';
} else {
// Logged in successfully, set cookie, display success message
/* setcookie($config->cookie_name, $login['hash'], $login['expire'], $config->cookie_path, $config->cookie_domain, $config->cookie_secure, $config->cookie_http);*/
echo '<div class="success">' . $login['message'] . '</div>';
}
?>
Or explicit declaration of the namespace when creating the object (that is using the FQN):
Then your register.php would look like:
<?php
include("languages/en_GB.php");
include("Config.class.php");
include("Auth.class.php");
$dbh = new PDO("mysql:host=localhost;dbname=phpauth", "root", "");
$config = new \PHPAuth\Config($dbh);
$auth = new \PHPAuth\Auth($dbh, $config, $lang);
$register = $auth->register($_POST['email'], $_POST['password'], $_POST['password']);
if($register['error']) {
// Something went wrong, display error message
echo '<div class="error">' . $register['message'] . '</div>';
} else {
// Logged in successfully, set cookie, display success message
/* setcookie($config->cookie_name, $login['hash'], $login['expire'], $config->cookie_path, $config->cookie_domain, $config->cookie_secure, $config->cookie_http);*/
echo '<div class="success">' . $login['message'] . '</div>';
}
?>
Hope it helps you!
Suggested Reading:
http://php.net/manual/en/language.namespaces.basics.php
http://php.net/manual/en/language.namespaces.rationale.php
http://php.net/manual/en/language.namespaces.php
Another thing: The use portion I have used in the first example is only compatible with PHP7. If you are using PHP lower than Version 7, then you can use this use declarations:
use \PHPAuth\Config;
use \PHPAuth\Auth;

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 mysql Update error

I seem to have an error I don't really understand. The process works fine, the connection to database is fine, but for some reason it doesn't update. There are no visible errors for me, or that php recognizes. Here is the code: (note that the last missing) on class I know about, and that happened when I copy pasted it, it's fine in the code
public function change_password($user, $pass) {
if($user) {
$password = md5($pass);
$this->_query = $this->_pdo->prepare("UPDATE users SET password = ? WHERE ? = ?");
if($this->_query->execute(array($pass, Check::data($user), $user))) {
return true;
}
}
return false;
}
class Check {
public static function data($data) {
if($data) {
if(is_numeric($data)) {
$_id = 'id';
} else if(filter_var($data, FILTER_VALIDATE_EMAIL)) {
$_id = 'email';
} else {
$_id = 'username';
}
return $_id;
}
return false;
}
}
If anyone is intressed, I resolved the problem, and for future simular problems , I found a way around..
public function change_password($user, $pass) {
if($user) {
$pass = md5($pass);
$id = $this->id($user);
$this->_query = $this->_pdo->prepare("UPDATE users SET password = ? WHERE id = ?");
if($this->_query->execute(array($pass, $id))) {
return true;
}
}
return false;
}
public function id($user) {
if($user) {
$params = $this->fetch($user);
foreach($params as $param) {
if($param['id']) {
return $param['id'];
}
}
}
return false;
}
public function fetch($user) {
if($user) {
if(Check::data($user) === 'id') {
$this->_query = $this->_pdo->prepare("SELECT * FROM users WHERE id = :user");
}
if(Check::data($user) === 'email') {
$this->_query = $this->_pdo->prepare("SELECT * FROM users WHERE email = :user");
}
if(Check::data($user) === 'username') {
$this->_query = $this->_pdo->prepare("SELECT * FROM users WHERE username = :user");
}
$this->_query->execute(array(':user' => $user));
return $this->_query->fetchAll();
}
return false;
}`class Check {
public static function data($data) {
if($data) {
if(is_numeric($data)) {
$_id = 'id';
} else if(filter_var($data, FILTER_VALIDATE_EMAIL)) {
$_id = 'email';
} else {
$_id = 'username';
}
return $_id;
}
return false;
} }

is isset($_SESSION['admin']) a dangerous way to grant access?

If (for argument sake) 'admin-access' was granted in php with:
if (isset($_SESSION['admin'])) // this session would be set
{ // grant access; } // after a successful login
else { //redirect ;}
Would this be a particularly easy thing to bypass and fake, if you knew what the name of the session is (in this case it is admin)?
In other words, can someone easily fake a $_SESSION, if all a script calls for is the session to be 'set'?
Using isset() is not bad for security. It depends on your logic that how you use it. It will be good if you not only check isset() but also its value.
For Example:
if( isset($_SESSION['admin']) && $_SESSION['admin'] == true ) {
// grant access
} else {
//redirect
}
Or something like this:
if( isset($_SESSION['admin']) && $_SESSION['admin'] == '1' ) {
// grant access
} else {
//redirect
}
i prefer a more secure way, like this class i used in my old applications :
class auth {
protected $userID;
protected $password;
protected $username;
protected $remember;
protected $userType;
public function checkAuth($username,$password,$remember=0) {
global $db;
$this->password = sha1($password);
$this->username = strtolower($username);
$this->remember = $remember;
$sth = $db->prepare("SELECT `id`,`username`,`password`,`type` FROM `user` WHERE `username` = :username AND `active` = '1' LIMIT 1");
$sth->execute(array(
':username' => $this->username
));
$result = $sth->fetchAll();
$this->userType = $result[0]['type'];
if (#$result[0]['password'] == $this->password) {
$this->userID = $result[0]['id'];
$this->makeLogin();
return true;
} else {
return false;
exit;
}
}
private function makeLogin() {
$securityInformation = $this->username . '|-|' . $this->password . '|-|' . $this->userID . '|-|' . $this->userType;
$hash = $this->encode($securityInformation);
if ($this->remember) {
setcookie('qdata',$hash,time()+604800,'/');
} else {
$_SESSION['qdata'] = $hash;
}
$this->updateStats();
}
public function isLogin() {
global $db, $ua, $cache;
$data = $this->getUserInfo();
if ($data) {
$sth = $db->prepare('SELECT `password`,`last_login_ip` FROM `user` WHERE `id` = :ID LIMIT 1');
$sth->execute(array(
':ID' => $data['userID']
));
$result = $sth->fetchAll();
if ( ($result[0]['password'] == $data['password']) AND ($result[0]['last_login_ip'] == $ua->getIP()) ) {
return true;
} else {
return false;
}
}
}
public function logout() {
if (#isset($_COOKIE['qdata'])) {
setcookie('qdata','',time()-200, '/');
}
if (#isset($_SESSION['qdata'])) {
unset($_SESSION['qdata']);
}
}
private function parseHash($hash) {
$userData = array();
list($userData['username'],$userData['password'],$userData['userID'],$userData['userType']) = explode('|-|',$this->decode($hash));
return $userData;
}
public function getUserInfo() {
if (#isset($_COOKIE['qdata'])) {
$data = $this->parseHash($_COOKIE['qdata']);
return $data;
} elseif (#isset($_SESSION['qdata'])) {
$data = $this->parseHash($_SESSION['qdata']);
return $data;
} else {
return false;
}
}
private function encode($str) {
$chr = '';
$prt = '';
for($i=0;$i < strlen($str);$i++) {
$prt = (chr(ord(substr($str,$i,1)) + 3)) . chr(ord(substr($str,$i,1)) + 2);
$chr = $prt . $chr;
}
return str_rot13($chr);
}
private function decode($str) {
$chr = '';
$prt = '';
$str = str_rot13($str);
for($i=0;$i < strlen($str);$i++) {
if($i % 2 == 0) {
$prt = (chr(ord(substr($str,$i,1)) - 3));
$chr = $prt . $chr;
}
}
return $chr;
}
}
if you dont like this approach, at least store a special key in admin table and use session with that key in value, also check login is validated every time a page loaded.

How can I implement a voting system on my site limiting votes to a single vote?

I am trying to build a site with news links that can be voted, I have the following code:
case 'vote':
require_once('auth/auth.php');
if(Auth::isUserLoggedIn())
{
require_once('data/article.php');
require_once('includes/helpers.php');
$id = isset($_GET['param'])? $_GET['param'] : 0;
if($id > 0)
{
$article = Article::getById($id);
$article->vote();
$article->calculateRanking();
}
if(!isset($_SESSION)) session_start();
redirectTo($_SESSION['action'], $_SESSION['param']);
}
else
{
Auth::redirectToLogin();
}
break;
The problem right now is how to check so the same user does not vote twice, here is the article file:
<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/config.php');
require_once(SITE_ROOT.'includes/exceptions.php');
require_once(SITE_ROOT.'data/model.php');
require_once(SITE_ROOT.'data/comment.php');
class Article extends Model
{
private $id;
private $user_id;
private $url;
private $title;
private $description;
private $ranking;
private $points;
function __construct($title = ' ', $description = ' ', $url = ' ', $username = ' ', $created = ' ', $modified = '') {
$this->setId(0);
$this->setCreated($created);
$this->setModified($modified);
$this->setUsername($username);
$this->setUrl($url);
$this->setTitle($title);
$this->setDescription($description);
$this->setRanking(0.0);
$this->setPoints(1);
}
function getId(){
return $this->id;
}
private function setId($value){
$this->id = $value;
}
function getUsername(){
return $this->username;
}
function setUsername($value){
$this->username = $value;
}
function getUrl(){
return $this->url;
}
function setUrl($value){
$this->url = $value;
}
function getTitle()
{
return $this->title;
}
function setTitle($value) {
$this->title = $value;
}
function getDescription() {
return $this->description;
}
function setDescription($value)
{
$this->description = $value;
}
function getPoints()
{
return $this->points;
}
function setPoints($value)
{
$this->points = $value;
}
function getRanking()
{
return $this->ranking;
}
function setRanking($value)
{
$this->ranking = $value;
}
function calculateRanking()
{
$created = $this->getCreated();
$diff = $this->getTimeDifference($created, date('F d, Y h:i:s A'));
$time = $diff['days'] * 24;
$time += $diff['hours'];
$time += ($diff['minutes'] / 60);
$time += (($diff['seconds'] / 60)/60);
$base = $time + 2;
$this->ranking = ($this->points - 1) / pow($base, 1.5);
$this->save();
}
function vote()
{
$this->points++;
$this->save();
}
function getUrlDomain()
{
/* We extract the domain from the URL
* using the following regex pattern
*/
$url = $this->getUrl();
$matches = array();
if(preg_match('/http:\/\/(.+?)\//', $url, $matches))
{
return $matches[1];
}
else
{
return $url;
}
}
function getTimeDifference( $start, $end )
{
$uts['start'] = strtotime( $start );
$uts['end'] = strtotime( $end );
if( $uts['start']!==-1 && $uts['end']!==-1 )
{
if( $uts['end'] >= $uts['start'] )
{
$diff = $uts['end'] - $uts['start'];
if( $days=intval((floor($diff/86400))) )
$diff = $diff % 86400;
if( $hours=intval((floor($diff/3600))) )
$diff = $diff % 3600;
if( $minutes=intval((floor($diff/60))) )
$diff = $diff % 60;
$diff = intval( $diff );
return( array('days'=>$days, 'hours'=>$hours, 'minutes'=>$minutes, 'seconds'=>$diff) );
}
else
{
echo( "Ending date/time is earlier than the start date/time");
}
}
else
{
echo( "Invalid date/time data detected");
}
return( false );
}
function getElapsedDateTime()
{
$db = null;
$record = null;
$record = Article::getById($this->id);
$created = $record->getCreated();
$diff = $this->getTimeDifference($created, date('F d, Y h:i:s A'));
//echo 'new date is '.date('F d, Y h:i:s A');
//print_r($diff);
if($diff['days'] > 0 )
{
return sprintf("hace %d dias", $diff['days']);
}
else if($diff['hours'] > 0 )
{
return sprintf("hace %d horas", $diff['hours']);
}
else if($diff['minutes'] > 0 )
{
return sprintf("hace %d minutos", $diff['minutes']);
}
else
{
return sprintf("hace %d segundos", $diff['seconds']);
}
}
function save() {
/*
Here we do either a create or
update operation depending
on the value of the id field.
Zero means create, non-zero
update
*/
if(!get_magic_quotes_gpc())
{
$this->title = addslashes($this->title);
$this->description = addslashes($this->description);
}
try
{
$db = parent::getConnection();
if($this->id == 0 )
{
$query = 'insert into articles (modified, username, url, title, description, points )';
$query .= " values ('$this->getModified()', '$this->username', '$this->url', '$this->title', '$this->description', $this->points)";
}
else if($this->id != 0)
{
$query = "update articles set modified = NOW()".", username = '$this->username', url = '$this->url', title = '".$this->title."', description = '".$this->description."', points = $this->points, ranking = $this->ranking where id = $this->id";
}
$lastid = parent::execSql2($query);
if($this->id == 0 )
$this->id = $lastid;
}
catch(Exception $e){
throw $e;
}
}
function delete()
{
try
{
$db = parent::getConnection();
if($this->id != 0)
{ ;
/*$comments = $this->getAllComments();
foreach($comments as $comment)
{
$comment->delete();
}*/
$this->deleteAllComments();
$query = "delete from articles where id = $this->id";
}
parent::execSql($query);
}
catch(Exception $e){
throw $e;
}
}
static function getAll($conditions = ' ')
{
/* Retrieve all the records from the
* database according subject to
* conditions
*/
$db = null;
$results = null;
$records = array();
$query = "select id, created, modified, username, url, title, description, points, ranking from articles $conditions";
try
{
$db = parent::getConnection();
$results = parent::execSql($query);
while($row = $results->fetch_assoc())
{
$r_id = $row['id'];
$r_created = $row['created'];
$r_modified = $row['modified'];
$r_title = $row['title'];
$r_description = $row['description'];
if(!get_magic_quotes_gpc())
{
$r_title = stripslashes($r_title);
$r_description = stripslashes($r_description);
}
$r_url = $row['url'];
$r_username = $row['username'];
$r_points = $row['points'];
$r_ranking = $row['ranking'];
$article = new Article($r_title, $r_description , $r_url, $r_username, $r_created, $r_modified);
$article->id = $r_id;
$article->points = $r_points;
$article->ranking = $r_ranking;
$records[] = $article;
}
parent::closeConnection($db);
}
catch(Exception $e)
{
throw $e;
}
return $records;
}
static function getById($id)
{/*
* Return one record from the database by its id */
$db = null;
$record = null;
try
{
$db = parent::getConnection();
$query = "select id, username, created, modified, title, url, description, points, ranking from articles where id = $id";
$results = parent::execSQL($query);
if(!$results) {
throw new Exception ('Record not found', EX_RECORD_NOT_FOUND);
}
$row = $results->fetch_assoc();
parent::closeConnection($db);
if(!get_magic_quotes_gpc())
{
$row['title'] = stripslashes($row['title']);
$row['description'] = stripslashes($row['description']);
}
$article = new Article($row['title'], $row['description'], $row['url'], $row['username'], $row['created'], $row['modified']);
$article->id = $row['id'];
$article->points = $row['points'];
$article->ranking = $row['ranking'];
return $article;
}
catch (Exception $e){
throw $e;
}
}
static function getNumberOfComments($id)
{/*
* Return one record from the database by its id */
$db = null;
$record = null;
try
{
$db = parent::getConnection();
$query = "select count(*) as 'total' from comments where article_id = $id";
$results = parent::execSQL($query);
if(!$results) {
throw new Exception ('Comments Count Query Query Failed', EX_QUERY_FAILED);
}
$row = $results->fetch_assoc();
$total = $row['total'];
parent::closeConnection($db);
return $total;
}
catch (Exception $e){
throw $e;
}
}
function deleteAllComments()
{/*
* Return one record from the database by its id */
$db = null;
try
{
$db = parent::getConnection();
$query = "delete from comments where article_id = $this->id";
$results = parent::execSQL($query);
if(!$results) {
throw new Exception ('Deletion Query Failed', EX_QUERY_FAILED);
}
parent::closeConnection($db);
}
catch (Exception $e){
throw $e;
}
}
function getAllComments($conditions = ' ')
{
/* Retrieve all the records from the
* database according subject to
* conditions
*/
$conditions = "where article_id = $this->id";
$comments = Comment::getAll($conditions);
return $comments;
}
static function getTestData($url)
{
$page = file_get_contents($url);
}
}
?>
Any suggestion or comment is appreciated, Thanks.
make another table user_votes for example with structure:
user_id int not null
article_id int not null
primary key (user_id, article_id)
in vote function first try to insert and if insert is successfull then increase $this->points
Have a table that keeps track of a user's vote for an article (something like UserID,ArticleID,VoteTimeStamp). Then you can just do a check in your $article->vote(); method to make sure the currently logged in user doesn't have any votes for that article.
If you want to keep thing fast (so you don't always have to use a join to get vote counts) you could have a trigger (or custom PHP code) that when adding/removing a vote updates the total vote count you currently keep in the article table.
You have these options:
Track the IP of whoever voted, and store it in a database. This is bad beucase many people might share IP and it can be circumvented using means such as proxies.
Another solution is to store a cookie in the browser. This is probably a bit better than the first solution as it lets many people from the same IP vote. It is, however, also easy to circumvent as you can delete your cookies.
The last and only secure method is to require your users to register to vote. This way you pair username and password against the votes and can ensure everyone votes only once, unless they are allowed to have several users.
A last solution might be a combination of the first two solutions, it is still obstructable though.
You could have a table containing a users ID and the article's ID called something like article_votes. So when user x votes for article y a row is inserted with both ID's. This allows you to check if a user has voted for an article.
To count the number of articles you could use a query like this: SELECT COUNT(*) AS votes FROM article_votes WHERE article=[article id]

Categories