<?php
/*
* @package LabCMS
* @copyright (c) 2006 Alexander Levin aka Loki (loki_angel@mail.ru)
* @support http://labcms.ru
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*/


include_once LAB_PATH_KERNEL.'/classes/AuthInterface.php';
include_once LAB_PATH_KERNEL.'/classes/Db.php';

class login_user implements AuthInterface
{
    
		protected $id=IS_GUEST;
		protected $group_id=IS_GUEST;
		protected $module='login';
		
		function __construct(&$id, &$group_id)
		{
			$this->id=&$id;
			$this->group_id=&$group_id;
			$this->users[$id]=$group_id;
		}
		
		public function autologin()
		{
			if ($this->id==IS_GUEST && isset($_COOKIE['login']) && isset($_COOKIE['pass']))
			{
				if (!$this->auth(array('login'=>$_COOKIE['login'], 'pass'=>$_COOKIE['pass'], 'hashed_once'=>true, 'rememberme'=>1)))
					$this->_DeleteCookiePass();
			}
			
			if (isset($_COOKIE['openid']) && $this->id==IS_GUEST && !$_GET['openid_mode'])
			{
				//если есть кука с openid - отправляем ее
				$oid=new OpenId();
				$oid->returnTo=$oid->getTrustRoot()
									.call_user_func_array(array('Url_'.LabConfig::$cfg['url_type'], 'create'), array(false, 'openid_auth', false, $this->_getModulePath(), false, false))
									.'?'
									."rememberme=1&"
									."redirect=".urlencode($_SERVER['REQUEST_URI']);
				$oid->SendOpenId($_COOKIE['openid']);
			}
			return $this->id>0;
		}
		
		public function auth($data)
		{
			$this->id=$this->getUserId($data);
			$this->group_id=$this->users[$this->id];
			if ($this->id>0)
			{
				//очищаем данные в сессии, так как там лежат данные гостя
				$_SESSION['user_info']=false;
				//$this->_cleanOnliners();
				$this->_storeLastIP();
				if ($data['rememberme'])
				{
					if ($data['pass']) $this->_SetCookie($data['login'], $data['pass'], $data['hashed_once']);
					elseif ($data['openid']) $this->_SetCookieOpenId($data['openid']);
				}
			}
			return $this->id>0;
		}

		public function getUserId($data)
		{
			if (!empty($data['login']) && !empty($data['pass']))
			{
				$user_id=$this->_getUserIdByLogin($data['login'], $data['pass'], $data['hashed_once']);
			}
			elseif(!empty($data['openid']))
			{
				$user_id=$this->_getUserIdByOpenId($data['openid']);
			}
			if ($user_id)
			{
				return $user_id;
			}
			return IS_GUEST;
		}
		
		protected function _AuthByCookieOpenId()
		{
			if ($_GET['openid_mode'])
			{
				$oid=new OpenId();
				if($openid=$oid->CheckAuthByOpenId())
				{
					if ($user_id=$this->_getUserIdByOpenId($openid))
					{
						$this->id=$user_id;
						$this->group_id=$this->users[$this->id];
						return true;
					}
				}
				$this->_DeleteCookieOpenId();
				return false;
			}
		
			if ($_COOKIE['openid'] && $this->id==IS_GUEST)
			{
				//если есть кука с openid - отправляем ее
				$oid=new OpenId();
				$oid->SendOpenId($_COOKIE['openid']);
			}
		}
		
		public function getUserInfo($user_id)
		{
			//если запрашивают текущего пользователя и данные есть в сессии - возвращаем оттуда
			if ($this->id==$user_id && isset($_SESSION['user_info']) && is_array($_SESSION['user_info']))
			{
				return $_SESSION['user_info'];
			}
			else
			{
				$user_info=$this->_getUserInfo($user_id);
				if($this->id==$user_id) $_SESSION['user_info']=$user_info;
				return $user_info;
			}
			return false;
		}
		
		protected function _SetCookie($login, $pass, $hashed_once=false)
		{
			if ($hashed_once) $pwd=$pass;
			else $pwd=User::PassHashOnce($pass);
			$this->_SetCookieAuth($login, $pwd);
		}
		
		protected function _SetCookieAuth($login, $pwd)
		{
			@setcookie('login', $login, time()+60*60*24*365, "/", LabCMS::getCookieDomain());
			@setcookie('pass', $pwd, time()+60*60*24*365, "/", LabCMS::getCookieDomain());
		}
		
		protected function _SetCookieOpenId($openid)
		{
			@setcookie('openid', $openid, time()+60*60*24*365, "/", LabCMS::getCookieDomain());
		}
		
		protected function _DeleteCookiePass()
		{
			@setcookie('pass', '', 0, "/", LabCMS::getCookieDomain());
		}
		
		protected function _DeleteCookieOpenId()
		{
			@setcookie('openid', '', 0, "/", LabCMS::getCookieDomain());
		}
        
		/**
		 * Разлогинивание. Уничтожает данные текущей сессии. Обнуляет куки с паролем.
		 * @author Loki
		 */
		public function logout()
		{
			$this->_DeleteCookiePass();
			$this->_DeleteCookieOpenId();
		}
        
		/**
		 * проверка существования логина в БД
		 * заменяет по очереди все русские на английские аналоги, потом все английские на русские
		 * @param string	проверяемый логин
		 * @return integer
		 * @author Loki
		 */	
		public function isLoginExists($login)
		{
			$eng=array('a', '6', 'e', 'k', 'o', 'p', 'c', 'y', 'x', 'A', 'B', 'E', 'K', 'M', 'H', 'O', 'P', 'C', 'T', 'X');
			$rus=array('а', 'б', 'е', 'к', 'о', 'р', 'с', 'у', 'х', 'А', 'В', 'Е', 'К', 'М', 'Н', 'О', 'Р', 'С', 'Т', 'Х');
			$login=preg_replace('/\s+/', ' ', trim($login));
			$result[]=str_replace($eng, $rus, $login);
			$result[]=str_replace($rus, $eng, $login);
			return $this->_CountUsersByLogins($result);
		}
        
		protected function _CountUsersByLogins($logins)
		{
			return Db::i()->selectCell("SELECT COUNT(user_id) FROM ?_users WHERE login IN (?a) AND user_id!=?", $logins, IS_GUEST);
		}
        
		protected function _getUserInfo($user_id)
		{
			return Db::i()->selectRow("SELECT *, user_id as id, UNIX_TIMESTAMP(last_visit) as last_visit_ut  FROM ?_users WHERE user_id=?", $user_id);
		}
		
		protected function _storeLastIP()
		{
			Db::i()->query("UPDATE ?_users SET last_ip=INET_ATON(?) WHERE user_id=? LIMIT 1", User::getIP(), $this->id);
		}
		
		public function saveLastRequests($maxlifetime)
		{
			Db::i()->query("UPDATE ?_users u LEFT JOIN ?_users_online o ON u.user_id=o.user_id SET u.last_visit=o.request_time WHERE o.request_time<NOW() - INTERVAL ?d SECOND", $maxlifetime);
		}
		
		/**
		 * проверки логина и пароля
		 * @param string	логин
		 * @param string	пароль
		 * @param boolean	ключ указывающий что пароль уже один раз хэширован (например, взят из кук)
		 * @return integer	id пользователя, либо false	
		 * @author Loki
		 */
		protected function _getUserIdByLogin($login, $pass, $hashed_once=false)
		{
			$info=Db::i()->selectRow("SELECT user_id, group_id FROM ?_users WHERE login=? AND pass=? AND status = 1", $login, User::PassHash($pass, $hashed_once));
			$this->users[$info['user_id']]=$info['group_id'];
			return $info['user_id'];
		}
		
		private function _getUserIdByOpenId($openid)
		{
			$info=Db::i()->selectRow("SELECT o.user_id, group_id FROM ?_openid o JOIN ?_users u ON o.user_id=u.user_id WHERE openid=?", $openid);
			$this->users[$info['user_id']]=$info['group_id'];
			return $info['user_id'];
		}
		
		protected function _getModulePath()
		{
			return LabCMS::i()->getModuleNodePath($this->module);
		}
		
		private function _getGroup($user_id)
		{
			return $this->users[$user_id];
		}
		
		public function getGroupByUserId($user_id)
		{
			if ($user_id==-1) return -1;
			return Db::i()->selectCell("SELECT group_id FROM ?_users WHERE user_id=?", $user_id);
		}
}