<?php
defined('PP_PATH') or exit;
class qq_control extends control {
	public $_uid;
	public $appid;
	public $appkey;
	public $_cfg = array();	// 全站参数
	public function __construct(){
		$this->_uid = session::get('_uid');
		if( $this->_uid ){
			$this->message(0, '你已经登录！',$this->_cfg['weburl'].'member/');
		}
		$this->_cfg = $this->runtime->xget();
		$this->assign('pp', $this->_cfg);
		if( empty($this->_cfg['user']['open_user_model']) ){
			$this->message(0, '用户中心暂时关闭！',$this->_cfg['weburl']);
		}
		if( empty($this->_cfg['qq_login']['off']) ){
			$this->message(0, '未开启QQ第三方登陆！',$this->_cfg['weburl']);
		}
		$_ENV['_hometheme'] 		= $this->_cfg['theme'];
		$this->appid 	= $this->_cfg['qq_login']['appid'];
		$this->appkey 	= $this->_cfg['qq_login']['appkey'];
	}

	public function login() {
		$callback 	= urlencode($this->_cfg['weburl'].'member/index.php?u=qq-token');
		$scope 		= "get_user_info";
		$state 		= md5(uniqid(rand(), TRUE)); //CSRF protection
		$login_url 	= "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=".$this->appid."&redirect_uri=$callback&state=$state&scope=$scope";
		header("Location:$login_url");
	}
	public function token(){
		$callback 	= urlencode($this->_cfg['weburl'].'member/index.php?u=qq-token');
		$state 		= R('state');
		$code 		= R('code');
		$token_url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=".$this->appid."&redirect_uri=$callback&client_secret=".$this->appkey."&code=$code";
		$s = $this->fetch_url($token_url); 
		if(strpos($s, "callback") !== false) {
			$lpos 	= strpos($s, "(");
			$rpos 	= strrpos($s, ")");
			$s  	= substr($s, $lpos + 1, $rpos - $lpos -1);
			$arr 	= json_decode($s,true);
			if(isset($arr['error'])) {
				$error = $arr['error'].'<br />'.$arr['error_description'];
				$this->message(0, $arr['error'].'<br />'.$arr['error_description'],$this->_cfg['weburl'].'member/');
			}
		}
		$params = array();
		parse_str($s, $params);
		if(empty($params["access_token"])) {
			$this->message(0, 'access_token 解码出错。'.$s,$this->_cfg['weburl'].'member/');
		}
		$token = $params["access_token"];
		// 获取 openid
		$openid = $this->qqlogin_get_openid_by_token($token);
		
		// 查询数据表，
		$arrlist = $this->user_qqlogin->find_fetch(array('openid'=>$openid), array(), 0, 1);
		$arr  = array_pop($arrlist) ;
		if(empty($arr)){ //没有登陆记录
			$args 		= str_auth("$openid\t$token", 'ENCODE');
			$url 		= $this->_cfg['weburl']."member/index.php?u=qq-reg";
			session::set('args', $args);
			//$this->message(1, '登录成功！请稍候完善您的帐户信息...',$url);
			header("Location:$url");exit;
		}else{
			$data = $this->user->read($arr['uid']);
			$this->set_login($data);
			if($data){
				$statusFormat = array(
					0 => "账号未通过审核或未激活，请联系客服",
					1 => '正常',
					2 => '该账号已被禁止，请联系客服'
				);
				if($data['status'] != 1 ){
					$this->message(0, $statusFormat[$data['status']],$this->_cfg['webdir']);
				}
				$this->message(1, '登录成功！请稍候...',$this->_cfg['webdir'].'member/');
			}
		}
	}
	public function reg() {
		$this->_cfg['titles'] = 'QQ会员绑定';
		//$args 	= R('args', 'DECODE');
		$args 	= session::get('args');
		$s 		= str_auth($args);
		$arr 	= explode("\t", $s);
		if(count($arr) < 2){
			$this->message(0, '参数错误！',$this->_cfg['webdir'].'member/');
		}
		list($openid, $token) = $arr;
		if(empty($_POST)){
			$qquser 	= $this->qqlogin_get_user_by_openid($openid, $token, $this->appid);
			$username 	= $qquser['nickname'];
			$useravatar = $qquser['figureurl_qq_1']; 	//qq头像
			$this->view->assign('args', $args);
			$this->view->assign('username', $username);
			$this->view->assign('useravatar', $useravatar);
			$this->view->display('register_qq.htm');
		}else{
			$username	= strip_tags(R('username', 'P'));
			$useravatar	= strip_tags(R('useravatar', 'P'));
			$isbind		= (int)R('isbind', 'P');
			$password 	= R('password', 'P');
			if(empty($username) ){
				E(1, '用户名不能为空！');
			}elseif( empty($password) ){
				E(1, '密码不能为空！');
			}
			if(empty($isbind)){//注册新用户
				$repassword = R('repassword', 'P');
				if($password != $repassword ){
					E(1, '两次输入的密码不一致！');
				}
				if($message = $this->user->check_username($username)) E(1, $message);
				if($message = $this->user->check_password($password)) E(1, $message);
				if($this->user->get_user_by_username($username)) E(1, '用户名已被注册！');
				$this->qq_create_user($username, $openid ,$password,$useravatar);
			}else{ //绑定老用户
				$data = $this->user->get_user_by_username($username);
				if($data && $this->user->verify_password($password, $data['salt'], $data['password'])){
					$_isbind = $this->user_qqlogin->find_fetch(array('uid'=>$data['uid']), array(), 0, 1);
					if(empty($_isbind)){ //没有绑定过
						$this->user_qqlogin->create(array('uid'=>$data['uid'],'openid'=>$openid));
						//直接登陆
						$this->set_login($data);
						E(0, '绑定登陆成功！');
					}else{
						E(1, '已经绑定过了！');
					}
				}else{
					$this->user->password_error($ip);
					E(1, '帐号或密码不正确！');
				}
			}
		}
	}
	private function qqlogin_get_openid_by_token($token){
		$url = "https://graph.qq.com/oauth2.0/me?access_token=$token";
		$s  = fetch_url($url);
		if(strpos($s, "callback") !== false) {
			$lpos = strpos($s, "(");
			$rpos = strrpos($s, ")");
			$s  = substr($s, $lpos + 1, $rpos - $lpos -1);
		}
		$arr = json_decode($s,true);
		if (isset($arr['error'])) {
			$error = $arr['error'].'：出错了<br />'.$arr['error_description'];
			//throw new Exception();
			$this->message(0, $error,$this->_cfg['weburl'].'member/');
		}
		return $arr['openid'];
	}
	private function qqlogin_get_user_by_openid($openid, $token, $appid) {
		$get_user_info = "https://graph.qq.com/user/get_user_info?access_token=$token&oauth_consumer_key=".$appid."&openid=$openid&format=json";
		$s = fetch_url($get_user_info);
		
		$arr = json_decode($s, true);
		return $arr;
	}
	private function qq_create_user($username, $openid,$password,$useravatar='') {
		$up_id	= 0 ;
		$code = R($_ENV['_config']['cookie_pre'].'tcode','R');
		if(!empty($code)){
			$up_id = $code;
		}
		$salt 		= random(16, 3, '0123456789abcdefghijklmnopqrstuvwxyz~!@#$%^&*()_+<>,.');
		$email 		= '';	// email 为空
		$ip = ip();
		$user = array(
			'username'	=> $username,
			'password'	=> get_password($password,$salt),
			'salt'		=> $salt,
			'groupid'	=> 4,
			'regip'		=> ip2long($ip),
			'regdate'	=> time(),
			'author'	=> $username,
			'avatar'	=> $useravatar,
			'status'	=> 1,
			'upid'		=> $up_id,
		);
		//处理红包-新用户注册
		if($this->_cfg['user']['gift']>0 && $this->is_hongbao($this->_cfg['user']['gift_mobi_off'],$this->_cfg['user']['gift_email_off'],0,0)){
			$user['money'] = $this->_cfg['user']['gift'];
		}
		$uid = $this->user->create($user);
		$this->user_qqlogin->create(array('uid'=>$uid, 'openid'=>$openid));
		if($uid){
			//直接登陆
			$user['uid'] 	= $uid ;
			$user['logins'] = 1 ;
			$this->set_login($user);

			if(!empty($user['money'])){
				$this->write_record($uid,$username,$user['money']);
			}
			$res_code = 0 ;
			$endStr = '';
			_setcookie('tcode', '', 1);
			E($res_code, 'QQ注册登陆成功！'.$endStr);
		}else{
			E(1, '注册失败，请重试！');
		}
	}
	protected function set_login($user){
		session::set('_uid', $user['uid']);
		// 更新登陆信息
		$ip = ip();
		$user['lastip'] 	= ip2long($ip);
		$user['lastdate'] 	= $_ENV['_time'];
		$user['loginip'] 	= ip2long($ip);
		$user['logindate'] 	= $_ENV['_time'];
		$user['logins']++;
		$this->user->update($user);
	}
	//copy from public
	protected function write_record($uid,$username,$money){
		$record = &$this->record;
		$recordata = array(
			'uid'		=> $uid,
			'username'	=> $username,
			'money'		=> $money,
			'gold'		=> 0,
			'type'		=> 1,
			'created'	=> $_ENV['_time'],
			'status'	=> 0,
			'comment'	=> '注册红包',
		);
		$record->create($recordata);
	}
	//copy from public
	protected function is_hongbao($mobi_off,$email_off,$mobi_status,$email_status){
		if(empty($mobi_off) && empty($email_off)){ //都没有开启
			return true;
		}
		if(!empty($mobi_off) && !empty($email_off)){ //手机、邮箱同时开启
			if(!empty($mobi_status) && !empty($email_status)){
				return true;
			}
		}
		if(!empty($mobi_off) && empty($email_off)){//仅开启了手机
			if(!empty($mobi_status)){
				return true;
			}
		}
		if(!empty($email_off) && empty($mobi_off)){//仅开启了邮箱
			if(!empty($email_status)){
				return true;
			}
		}
		return false;
	}
	protected function fetch_url($url, $timeout = 30) {
		if(substr($url, 0, 5) == 'http:') {
			$opts = array ('http'=>array('method'=>'GET', 'timeout'=>$timeout));
			$context = stream_context_create($opts);
			$html = file_get_contents($url, false, $context);
			return $html;
		}
		$w = stream_get_wrappers();
		$allow_url_fopen = strtolower(ini_get('allow_url_fopen'));
		$allow_url_fopen = (empty($allow_url_fopen) || $allow_url_fopen == 'off') ? 0 : 1;
		if(extension_loaded('openssl') && in_array('https', $w) && $allow_url_fopen) {
			return file_get_contents($url);
		}elseif(!function_exists('curl_init')) {
			throw new Exception('server not installed curl.');
		}
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_HEADER, false);
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在

		curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
		$data = curl_exec($ch);
		if(curl_errno($ch)) {
			throw new Exception('Errno'.curl_error($ch));//捕抓异常
		}
		if(!$data) {
			curl_close($ch);
			return '';
		}
		curl_close($ch);
		return $data;  
	}
}