<?php
if (!defined("ROOT_PATH"))
{
	header("HTTP/1.1 403 Forbidden");
	exit;
}
/**
 * 
 * @author Dimitar Ivanov
 * @version 1.0.0
 *
 */
class pjFacebook
{
	protected $client_id;
	
	protected $client_secret;
	
	protected $redirect_uri;
	
	protected $http;
	
	protected $access_token;
	
	protected $user;
	
	protected $scope = 'email';
	
	protected $error;
	
	private $api_graph = 'https://graph.facebook.com/';
	
	private $api_url = 'https://www.facebook.com/';
	
	private $api_version = '2.9';
	
	private $session_var = 'pjFacebookComponent';
	
	public function setClientId($value)
	{
		$this->client_id = (string) $value;
		
		return $this;
	}
	
	public function setClientSecret($value)
	{
		$this->client_secret = (string) $value;
	
		return $this;
	}
	
	public function setRedirectUri($value)
	{
		$this->redirect_uri = (string) $value;
	
		return $this;
	}
	
	protected function request($uri, $params=array())
	{
		if ($uri === 'access_token')
		{
			$url = sprintf("%sv%s/oauth/%s", $this->api_graph, $this->api_version, $uri);
		} else {
			$url = sprintf("%s%s", $this->api_graph, $uri);
		}
	
		$queryString = http_build_query($params, null, '&');
		
		$response = $this->http
			->setMethod('GET')
			->curlRequest($url . '?' .$queryString)
			->getResponse();
		
		if (empty($response))
		{
			return false;
		}
		
		if ($this->http->getError())
		{
			return false;
		}
	
		$result = json_decode($response, true);
		
		return $result;
	}
		
	public function requestAccessToken($code)
	{
		$params = array(
			'client_id' => $this->client_id,
			'client_secret' => $this->client_secret,
			'redirect_uri' => $this->redirect_uri,
			'code' => $code,
		);
		
		$result = $this->request('access_token', $params);
		
		if (isset($result['error']))
		{
			$this->error = $result['error'];
			throw new Exception('Access token is not retrieved.', 1);
		}
		
		$this->setAccessToken($result['access_token']);
		
		return $this;
	}

	public function setAccessToken($value)
	{
		$this->access_token = (string) $value;
		
		return $this;
	}

	public function getAccessToken()
	{
		return $this->access_token;
	}
	
	public function requestValidateToken()
	{
		$params = array(
			'input_token' => $this->getAccessToken(),
			'access_token' => $this->client_id.'|'.$this->client_secret
		);
		$result = $this->request('debug_token', $params);
		
		if (isset($result['error']))
		{
			$this->error = $result['error'];
			throw new Exception('Access token is not valid.', 2);
		}
		
		return $this;
	}
	
	public function requestUser()
	{
		$params = array(
			'access_token' => $this->getAccessToken(),
			'fields' => 'id,email,first_name,last_name,name,website,link'
		);
		$result = $this->request('me', $params);
		
		if (isset($result['error']))
		{
			$this->error = $result['error'];
			throw new Exception('User is not retrieved.', 3);			
		}
		
		$this->user = new stdClass();
		$this->user->identifier = @$result['id'];
		$this->user->email = @$result['email'];
		$this->user->firstName = @$result['first_name'];
		$this->user->lastName = @$result['last_name'];
		$this->user->displayName = @$result['name'];
		$this->user->webSiteURL = @$result['website'];
		$this->user->profileURL = @$result['link'];
		
		$_SESSION[$this->session_var] = $this->user;
		
		return $this;
	}
	
	public function getUser()
	{
		return $this->user;
	}
	
	public function getUserFromSession()
	{
		if (isset($_SESSION[$this->session_var]) && !empty($_SESSION[$this->session_var]))
		{
			return $_SESSION[$this->session_var];
		}
		
		return null;
	}
	
	public function setScope($value)
	{
		$this->scope = (string) $value;
		
		return $this;
	}
	
	public function getLoginUrl()
	{
		$queryString = http_build_query(array(
			'client_id' => $this->client_id,
			'redirect_uri' => $this->redirect_uri,
			'scope' => $this->scope,
			), null, '&');
			
		return sprintf('%sv%s/dialog/oauth?%s', $this->api_url, $this->api_version, $queryString);
	}
	
	public function login()
	{
		header('Location: ' . $this->getLoginUrl());
		exit;
	}
	
	public function getError()
	{
		return $this->error;
	}
	
	public function __construct($client_id, $client_secret, $redirect_uri=null)
	{
		$this->http = new pjHttp();
		
		$this->setClientId($client_id);
		
		$this->setClientSecret($client_secret);
		
		$this->setRedirectUri($redirect_uri);
	}
}
?>