<?php

/**

* HybridAuth

* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth

* (c) 2009-2014, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html 

*/



/**

 * Hybrid_Provider_Model provide a common interface for supported IDps on HybridAuth.

 *

 * Basically, each provider adapter has to define at least 4 methods:

 *   Hybrid_Providers_{provider_name}::initialize()

 *   Hybrid_Providers_{provider_name}::loginBegin()

 *   Hybrid_Providers_{provider_name}::loginFinish()

 *   Hybrid_Providers_{provider_name}::getUserProfile()

 *

 * HybridAuth also come with three others models

 *   Class Hybrid_Provider_Model_OpenID for providers that uses the OpenID 1 and 2 protocol.

 *   Class Hybrid_Provider_Model_OAuth1 for providers that uses the OAuth 1 protocol.

 *   Class Hybrid_Provider_Model_OAuth2 for providers that uses the OAuth 2 protocol.

 */

abstract class Hybrid_Provider_Model

{

	/**

	 * IDp ID (or unique name)

	 * @var Numeric/String

	 */

	public $providerId = NULL;



	/**

	 * specific provider adapter config

	 * @var array

	 */

	public $config     = NULL;



   	/**

	 * provider extra parameters

	 * @var array

	 */

	public $params     = NULL;



	/**

	 * Endpoint URL for that provider

	 * @var String

	 */

	public $endpoint   = NULL; 



	/**

	 * Hybrid_User obj, represents the current loggedin user

	 * @var object

	 */

	public $user       = NULL;



	/**

	 * the provider api client (optional)

	 * @var String

	 */

	public $api        = NULL; 



	/**

	 * Common providers adapter constructor

	 * @param Numeric/String $providerId

	 * @param Array $config

	 * @param Array $params

	 */

	function __construct( $providerId, $config, $params = NULL )

	{

		# init the IDp adapter parameters, get them from the cache if possible

		if( ! $params ){

			$this->params = Hybrid_Auth::storage()->get( "hauth_session.$providerId.id_provider_params" );

		}

		else{

			$this->params = $params;

		}



		// idp id

		$this->providerId = $providerId;



		// set HybridAuth endpoint for this provider

		$this->endpoint = Hybrid_Auth::storage()->get( "hauth_session.$providerId.hauth_endpoint" );



		// idp config

		$this->config = $config;



		// new user instance

		$this->user = new Hybrid_User();

		$this->user->providerId = $providerId;



		// initialize the current provider adapter

		$this->initialize(); 



		Hybrid_Logger::debug( "Hybrid_Provider_Model::__construct( $providerId ) initialized. dump current adapter instance: ", serialize( $this ) );

	}



	// --------------------------------------------------------------------



	/**

	* IDp wrappers initializer

	*

	* The main job of wrappers initializer is to performs (depend on the IDp api client it self): 

	*     - include some libs needed by this provider,

	*     - check IDp key and secret,

	*     - set some needed parameters (stored in $this->params) by this IDp api client

	*     - create and setup an instance of the IDp api client on $this->api 

	*/

	abstract protected function initialize(); 



	// --------------------------------------------------------------------



	/**

	* begin login 

	*/

	abstract protected function loginBegin();



	// --------------------------------------------------------------------



	/**

	* finish login

	*/

	abstract protected function loginFinish();



	// --------------------------------------------------------------------



   	/**

	* generic logout, just erase current provider adapter stored data to let Hybrid_Auth all forget about it

	*/

	function logout()

	{

		Hybrid_Logger::info( "Enter [{$this->providerId}]::logout()" );



		$this->clearTokens();



		return TRUE;

	}



	// --------------------------------------------------------------------



	/**

	* grab the user profile from the IDp api client

	*/

	function getUserProfile()

	{

		Hybrid_Logger::error( "HybridAuth do not provide users contacts list for {$this->providerId} yet." );

		

		throw new Exception( "Provider does not support this feature.", 8 ); 

	}



	// --------------------------------------------------------------------



	/**

	* load the current logged in user contacts list from the IDp api client  

	*/

	function getUserContacts() 

	{

		Hybrid_Logger::error( "HybridAuth do not provide users contacts list for {$this->providerId} yet." );

		

		throw new Exception( "Provider does not support this feature.", 8 ); 

	}



	// --------------------------------------------------------------------



	/**

	* return the user activity stream  

	*/

	function getUserActivity( $stream ) 

	{

		Hybrid_Logger::error( "HybridAuth do not provide user's activity stream for {$this->providerId} yet." ); 

		

		throw new Exception( "Provider does not support this feature.", 8 ); 

	}



	// --------------------------------------------------------------------



	/**

	* set user status

	*/ 

	function setUserStatus( $status )

	{

		Hybrid_Logger::error( "HybridAuth do not provide user's activity stream for {$this->providerId} yet." ); 

		

		throw new Exception( "Provider does not support this feature.", 8 ); 

	}





	/**

	* return the user status

	*/ 

	function getUserStatus( $statusid )

	{

		Hybrid_Logger::error( "HybridAuth do not provide user's status for {$this->providerId} yet." ); 

		

		throw new Exception( "Provider does not support this feature.", 8 ); 

	}



	// --------------------------------------------------------------------



	/**

	* return true if the user is connected to the current provider

	*/ 

	public function isUserConnected()

	{

		return (bool) Hybrid_Auth::storage()->get( "hauth_session.{$this->providerId}.is_logged_in" );

	}



	// --------------------------------------------------------------------



	/**

	* set user to connected 

	*/ 

	public function setUserConnected()

	{

		Hybrid_Logger::info( "Enter [{$this->providerId}]::setUserConnected()" );

		

		Hybrid_Auth::storage()->set( "hauth_session.{$this->providerId}.is_logged_in", 1 );

	}



	// --------------------------------------------------------------------



	/**

	* set user to unconnected 

	*/ 

	public function setUserUnconnected()

	{

		Hybrid_Logger::info( "Enter [{$this->providerId}]::setUserUnconnected()" );

		

		Hybrid_Auth::storage()->set( "hauth_session.{$this->providerId}.is_logged_in", 0 ); 

	}



	// --------------------------------------------------------------------



	/**

	* get or set a token 

	*/ 

	public function token( $token, $value = NULL )

	{

		if( $value === NULL ){

			return Hybrid_Auth::storage()->get( "hauth_session.{$this->providerId}.token.$token" );

		}

		else{

			Hybrid_Auth::storage()->set( "hauth_session.{$this->providerId}.token.$token", $value );

		}

	}



	// --------------------------------------------------------------------



	/**

	* delete a stored token 

	*/ 

	public function deleteToken( $token )

	{

		Hybrid_Auth::storage()->delete( "hauth_session.{$this->providerId}.token.$token" );

	}



	// --------------------------------------------------------------------



	/**

	* clear all existent tokens for this provider

	*/ 

	public function clearTokens()

	{ 

		Hybrid_Auth::storage()->deleteMatch( "hauth_session.{$this->providerId}." );

	}

}

