<?php defined('SYSPATH') or die('No direct access allowed.');

/**
 * This class provides Authentication using Facebook
 *
 * @package    OAuth
 * @category   Classes
 * @author     Deon George
 * @copyright  (c) 2009-2013 Open Source Billing
 * @license    http://dev.osbill.net/license.html
 */
class Auth_Facebook extends Auth_ORM_External {
	// Our Facebook config data
	private $config;
	private $data;
	private $me;
	// Facebook UID
	private $uid;

	public function __construct(Model_Oauth $oo) {
		// If our user refused, then no point continuing
		if ($problem = Arr::get($_REQUEST,'error'))
			switch ($problem) {
				case 'access_denied':
					HTTP::redirect('login');

				default:
					throw HTTP_Exception::factory(501,'Unknown OAuth Problem :problem',array(':problem'=>$problem));
			}

		parent::__construct($oo);

		include Kohana::find_file('vendor', 'facebook');

		// Load configuration "config/facebook"
		$this->config = Kohana::$config->load('facebook');

		// Create new Facebook object
		$this->ao = new Facebook(array(
			'appId' => $oo->app_id,
			'secret' => $oo->secret,
			'cookie' => $this->config->cookie,
			'session_type' => $this->config->session_type,
		));

		try {
			$this->me = $this->ao->api('/' . $this->ao->getUser(), 'GET');

		} catch (FacebookApiException $e) {
			// Do nothing.
		}
	}

	/**
	 * Returns user data, default in case of failure.
	 *
	 * @param $key
	 * @param null $default
	 * @return mixed
	 * @throws FacebookApiException
	 */
	public function get($key,$default=NULL) {
		if (! $uid = $this->user_id()) {
			$this->login_url();

			throw new FacebookApiException('User is not logged in.');
		}

		if (empty($this->data))
			$this->data = $this->ao->api(array(
				'method' => 'fql.query',
				'query' => sprintf('SELECT %s FROM user WHERE uid = %s',$this->config_fields,$uid),
			));

		return (! empty($this->data[0][$key])) ? $this->data[0][$key] : $default;
	}

	/**
	 * Is user currently logged into facebook?
	 */
	public function logged_in($role=NULL,$debug=NULL) {
		return $this->ao->getUser() ? TRUE : FALSE;
	}

	/**
	 * Creates a login url, based on scope, redirect_uri and display.
	 *
	 * @return string
	 */
	public function login_url() {
		return urldecode($this->ao->getLoginUrl(array(
			'scope' => $this->config->scope,
			'redirect_uri' => $this->config->redirect_uri,
			'display' => $this->config->display,
		)));
	}

	/**
	 * Creates a logout url based on next.
	 *
	 * @return string
	 */
	public function logout_url() {
		return urldecode($this->ao->getLogoutUrl(array('next'=>$this->config->next)));
	}

	/**
	 * Return user id if success, otherwise FALSE.
	 */
	public function user_id() {
		if ($this->logged_in()) {
			$this->uid = $this->ao->getUser();

			return $this->uid;

		} else {
			return FALSE;
		}
	}
}
?>
