Файл: model/M_Users.php
Строк: 332
<?php
include_once('model/MSQL.php');
//
// Менеджер пользователей
//
class M_Users
{
private static $instance; // экземпляр класса
private $msql; // драйвер БД
private $sid; // идентификатор текущей сессии
private $uid; // идентификатор текущего пользователя
private $onlineMap; // карта онлайн пользователей
//
// Получение экземпляра класса
// результат - экземпляр класса MSQL
//
public static function Instance() {
if (self::$instance == null)
self::$instance = new M_Users();
return self::$instance;
}
//
// Конструктор
//
public function __construct() {
$this->msql = MSQL::Instance();
$this->sid = null;
$this->uid = null;
}
//
// Очистка неиспользуемых сессий
//
public function ClearSessions($id_user = null) {
if($id_user != null) {
$t = "id_user = '%s'";
$where = sprintf($t, $id_user);
} else {
$min = date('Y-m-d H:i:s', time() - 60 * 20);
$t = "time_last < '%s'";
$where = sprintf($t, $min);
}
$this->msql->Delete('sessions', $where);
}
//
// Проверка активности пользователя.
//
public function checkOpenSession($id_user) {
$query = "SELECT * FROM sessions WHERE id_user = '$id_user'";
$result = $this->msql->Select($query);
if(!$result)
$this->OpenSession($id_user);
}
//
// Авторизация
// $login - логин
// $password - пароль
// $remember - нужно ли запомнить в куках
// результат - true или false
//
public function Login($login, $password, $remember = true) {
// вытаскиваем пользователя из БД
$user = $this->GetByLogin($login);
if ($user == null)
return false;
$id_user = $user['id_user'];
// проверяем пароль
if ($user['password'] != md5($password))
return false;
// запоминаем имя и md5(пароль)
if ($remember) {
$expire = time() + 3600 * 24 * 100;
setcookie('login', $login, $expire);
setcookie('password', md5($password), $expire);
}
// открываем сессию и запоминаем SID
$this->sid = $this->OpenSession($id_user);
return true;
}
//
// Выход
//
public function Logout() {
setcookie('login', '', time() - 1);
setcookie('password', '', time() - 1);
unset($_COOKIE['login']);
unset($_COOKIE['password']);
unset($_SESSION['sid']);
$this->sid = null;
$this->uid = null;
}
//
// Получение пользователя
// $id_user - если не указан, брать текущего
// результат - объект пользователя
//
public function Get($id_user = null) {
// Если id_user не указан, берем его по текущей сессии.
if ($id_user == null)
$id_user = 'id'.$this->GetUid();
if ($id_user == null)
return null;
if(substr($id_user, 0, 2) === 'id') {
$id_user = substr($id_user, 2);
$where = "profile.id_user = '%d'";
} else {
$where = "profile.screen_name = '%s'";
}
// А теперь просто возвращаем пользователя по id_user.
$t = "SELECT *
FROM users
INNER JOIN profile
ON users.id_user = profile.id_user
AND users.id_profile = profile.id_profile
WHERE ".$where;
$query = sprintf($t, $id_user);
$result = $this->msql->Select($query);
$result = $result[0];
if ($result == null)
return null;
/*
if($result['home_city'])
{
$CountrySity = $this->GetSity($result['home_city']);
$result['home_city_select'] = $CountrySity['city_name'];
}
if($result['country'] and $result['city'])
{
$CountrySity = $this->GetCountrySity($result['country'], $result['city']);
$result['country_select'] = $CountrySity['country_name'];
$result['city_select'] = $CountrySity['city_name'];
}
if($result['relation_uid'])
$result['relation_uid_select'] = $this->GetNameUser($result['relation_uid']);
if($result['relatives'])
{
$relativ = explode(',', $result['relatives']);
foreach($relativ as $relatives)
$rel[] = $this->GetNameUser($relatives);
$result['relatives_select'] = $rel;
}
*/
$result['online'] = $this->IsOnline($result['id_user']);
$result['full_name'] = $result['first_name'].' '.$result['last_name'];
return $result;
}
//
// Получает имена пользователей.
//
public function GetNameUser($id_user) {
if ($id_user == null)
return null;
$t = "SELECT id_user,
first_name,
last_name
FROM profile WHERE id_user = '%d'";
$query = sprintf($t, $id_user);
$result = $this->msql->Select($query);
return $result[0];
}
//
// Получает последнюю запись в БД.
//
public function PreviousId($table, $id_column) {
if($table && $id_column)
{
$result = $this->msql->Select("SELECT MAX(".$id_column.") AS maxid FROM ".$table);
return $result[0]['maxid'] + 1;
}
else
return false;
}
//
// Получает город и страну одновременно.
//
public function GetCountrySity($country_id, $city_id) {
if ($country_id == null)
return null;
$query = "SELECT *
FROM country
INNER JOIN city
ON country.country_id = city.country_id
AND city.city_id = $city_id
WHERE country.country_id = $country_id";
$result = $this->msql->Select($query);
return $result[0];
}
//
// Получает город.
//
public function GetSity($city_id) {
if ($city_id == null)
return null;
$query = "SELECT city_id, city_name FROM city WHERE city_id = $city_id";
$result = $this->msql->Select($query);
return $result[0];
}
//
// Получает страну.
//
public function GetCountry($country_id) {
if ($country_id == null)
return null;
$query = "SELECT country_id, name WHERE country_id = $country_id";
$result = $this->msql->Select($query);
return $result[0]['name'];
}
//
// Получает пользователя по логину
//
public function GetByLogin($login) {
$t = "SELECT * FROM users WHERE login = '%s'";
$query = sprintf($t, mysql_real_escape_string($login));
$result = $this->msql->Select($query);
return $result[0];
}
//
// Проверка наличия привилегии
// $priv - имя привилегии
// $id_user - если не указан, значит, для текущего
// результат - true или false
//
public function Can($priv, $id_user = null) {
// Если id_user не указан, берем его по текущей сессии.
if ($id_user == null)
$id_user = $this->GetUid();
if ($id_user == null)
return false;
$user = $this->Get($id_user);
$id_role = $user['id_role'];
$query = "SELECT *
FROM privs2roles
INNER JOIN privs
ON privs2roles.id_priv = privs.id_priv
AND privs.name = '$priv'
WHERE id_role = '$id_role'";
$result = $this->msql->Select($query);
if ($result)
return true;
return false;
}
//
// Проверка активности пользователя
// $id_user - идентификатор
// результат - true если online
//
public function IsOnline($id_user) {
// SELECT id_user FROM sessions
// и записать этот список в $this->onlineMap
// return $this->onlineMap[$id_user] != null
$time = date('Y-m-d H:i:s', time() - 60 * 5);
if(!is_array($id_user)) {
$t = "SELECT * FROM sessions
WHERE id_user = '%d' AND time_last > '%s'";
$query = sprintf($t, $id_user, $time);
$result = $this->msql->Select($query);
return ($result) ? true : false;
} else {
$impl = implode(',', $id_user);
$t = "SELECT * FROM sessions
WHERE id_user IN($impl) AND time_last > '%s'";
$query = sprintf($t, $time);
$result = $this->msql->Select($query);
foreach($result as $k => $isOnl) {
$resultRet[$isOnl['id_user']] = ($isOnl) ? true : false;
}
return $resultRet;
}
}
//
// Получение количества зарегистрированных пользователей
//
public function GetUsersCount() {
$query = "SELECT count(*) as count FROM users ";
$result = $this->msql->Select($query);
return $result[0]['count'];
}
//
// Получение всех пользователей
// результат - массив пользователей
//
public function GetUsers() {
$query = "SELECT * FROM users ";
$result = $this->msql->Select($query);
return $result;
}
//
// Получение id текущего пользователя
// результат - UID
//
public function GetUid() {
// Проверка кеша.
if ($this->uid != null)
return $this->uid;
// Берем по текущей сессии.
$sid = $this->GetSid();
if ($sid == null)
return null;
$t = "SELECT id_user FROM sessions WHERE sid = '%s'";
$query = sprintf($t, mysql_real_escape_string($sid));
$result = $this->msql->Select($query);
// Если сессию не нашли - значит пользователь не авторизован.
if (count($result) == 0)
return null;
// Если нашли - запоминм ее.
$this->uid = $result[0]['id_user'];
return $this->uid;
}
//
// Поиск по пользователям.
//
public function search() {
//$t = "SELECT * FROM profile WHERE id_user = '%s'";
//$query = sprintf($t, mysql_real_escape_string($sid));
//$result = $this->msql->Select($query);
$query = "SELECT *
FROM users
INNER JOIN profile
ON users.id_user = profile.id_user
AND users.id_profile = profile.id_profile";
$result = $this->msql->Select($query);
$id_user = array();
foreach($result as $user)
$id_user[] = $user['id_user'];
$result['online'] = $this->IsOnline($id_user);
//$result['full_name'] = $result['first_name'].' '.$result['last_name'];
return $result;
}
//
// Изменения статуса пользователя.
//
public function editStatus($oid, $info) {
$status['status'] = $info;
$t = "id_user = '%d'";
$where = sprintf($t, $oid);
$this->msql->Update('profile', $status, $where);
}
//
// Начало регистрации
//
public function register($fname, $lname, $sex) {
$_SESSION['reg']['fname'] = strip_tags(trim($fname));
$_SESSION['reg']['lname'] = strip_tags(trim($lname));
$_SESSION['reg']['sex'] = strip_tags(trim($sex));
return true;
}
//
// Окончание регистрации.
//
public function registerFinish($pass, $email, $phone) {
// Подготовка.
$fname = $_SESSION['reg']['fname'];
$lname = $_SESSION['reg']['lname'];
$sex = $_SESSION['reg']['sex'];
$email = strip_tags(trim($email));
$phone = strip_tags(trim($phone));
if(!$fname || !$lname || !$sex || !$email || !$phone)
return false;
// Последняя запись в users
$lastIdUser = $this->PreviousId('users', 'id_user');
$profile = array();
$profile['first_name'] = $fname;
$profile['last_name'] = $lname;
$profile['sex'] = $sex;
$profile['mobile_phone'] = $phone;
$profile['id_user'] = $lastIdUser;
$lastIdProfile = $this->msql->Insert('profile', $profile);
$user = array();
$user['login'] = $email;
$user['password'] = md5($pass);
$user['id_role'] = 1;
$user['id_profile'] = $lastIdProfile;
$this->msql->Insert('users', $user);
$this->Login($email, $pass);
unset($_SESSION['reg']);
return true;
}
//
// Генерация случайной последовательности
// $length - ее длина
// результат - случайная строка
//
private function GenerateStr($length = 10) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPRQSTUVWXYZ0123456789";
$code = "";
$clen = strlen($chars) - 1;
while (strlen($code) < $length)
$code .= $chars[mt_rand(0, $clen)];
return $code;
}
//
// Функция возвращает идентификатор текущей сессии
// результат - SID
//
private function GetSid() {
// Проверка кеша.
if ($this->sid != null)
return $this->sid;
// Ищем SID в сессии.
$sid = $_SESSION['sid'];
// Если нашли, попробуем обновить time_last в базе.
// Заодно и проверим, есть ли сессия там.
if ($sid != null)
{
$session = array();
$session['time_last'] = date('Y-m-d H:i:s');
$t = "sid = '%s'";
$where = sprintf($t, mysql_real_escape_string($sid));
$affected_rows = $this->msql->Update('sessions', $session, $where);
if ($affected_rows == 0)
{
$t = "SELECT count(*) FROM sessions WHERE sid = '%s'";
$query = sprintf($t, mysql_real_escape_string($sid));
$result = $this->msql->Select($query);
if ($result[0]['count(*)'] == 0)
$sid = null;
}
}
// Нет сессии? Ищем логин и md5(пароль) в куках.
// Т.е. пробуем переподключиться.
if ($sid == null && isset($_COOKIE['login']))
{
$user = $this->GetByLogin($_COOKIE['login']);
if ($user != null && $user['password'] == $_COOKIE['password'])
$sid = $this->OpenSession($user['id_user']);
}
// Запоминаем в кеш.
if ($sid != null)
$this->sid = $sid;
// Возвращаем, наконец, SID.
return $sid;
}
//
// Открытие новой сессии
// результат - SID
//
private function OpenSession($id_user) {
// генерируем SID
$sid = $this->GenerateStr(10);
// вставляем SID в БД
$now = date('Y-m-d H:i:s');
$session = array();
$session['id_user'] = $id_user;
$session['sid'] = $sid;
$session['time_start'] = $now;
$session['time_last'] = $now;
$this->msql->Insert('sessions', $session);
// регистрируем сессию в PHP сессии
$_SESSION['sid'] = $sid;
// возвращаем SID
return $sid;
}
}