<?php

/**
 * 
 *
 * @version $Id$
 * @copyright 2003 
 **/

class sco_ajax {
	var $cb_get_option;
	function __construct( $cb_get_option=false ){
		$this->cb_get_option = $cb_get_option;
			
		add_action('wp_ajax_sco_social_connect',		array(&$this,'sco_social_connect') );
		add_action('wp_ajax_nopriv_sco_social_connect', array(&$this,'sco_social_connect') );	

		add_filter('sco_enabled_network', array(&$this,'sco_enabled_network'), 10, 1);
		add_filter('sco_enabled_network_names', array(&$this,'sco_enabled_network_names'), 10, 1);
		add_filter('sco_installed_networks', array(&$this,'sco_installed_networks'), 10, 1);
		add_filter('sco_installed_networks', array(&$this,'sco_installed_networks_sort'), 999999, 1);
	}
	
	function sco_social_connect(){
		$reload  = true;
		$network = isset($_REQUEST['network']) ? $_REQUEST['network'] : '';
		$allowed_network = apply_filters('sco_enabled_network', array() );
		if(in_array($network, $allowed_network)){
			$path 			= plugin_dir_path(__FILE__);
			$filename 		= sprintf('login_with_%s.php', $network);
			$window_close	= isset($_REQUEST['window_close']) && '1'==$_REQUEST['window_close']?'1':'0';
			$redirect_uri	= apply_filters('sco_redirect_uri', admin_url( '/admin-ajax.php?action=sco_social_connect&network='.$network.'&window_close='.$window_close ) );
			
			$filename = apply_filters( 'sco_social_connect_filename', $filename, $this );		
			include $filename;
			
			$this->handle_post_social_auth();
		}else{
			die( sprintf( __('Settings error, network is not allowed. (%s)', 'rhsco'), $network ) );
		}
		die();
	}

	function handle_post_social_auth(){
		if(isset($_REQUEST['window_close'])){
			echo "<script>window.close();</script>";
		}	
	}
	
	function sco_installed_networks( $installed_networks=array() ){
		include 'map_network_names.php';
		return array_merge($installed_networks, $sco_installed_networks);	
	}
	
	function sco_installed_networks_sort( $networks ){
		$order = $this->get_option( 'network_order', array(), true );

		$sorted_networks = array();
		if( is_array($order) && count($order)>0 ){
			foreach($order as $network){
				if(isset($networks[$network])){
					$sorted_networks[$network]=$networks[$network];
					unset($networks[$network]);
				}
			}
		}
		
		if( is_array($networks) && count($networks) > 0 ){
			foreach($networks as $index => $value){
				$sorted_networks[$index]=$value;
			}
		}
		
		return $sorted_networks;
	}
	
	function sco_enabled_network($options){
		$options = is_array($options)?$options:array();	
		foreach( apply_filters('sco_installed_networks', array()) as $network => $n  ){
			if( '1' == $this->get_option($n->option, '', true) ){
				$options[] = $network;
			}
		}
	
		return $options;
	}
	
	function sco_enabled_network_names($options){
		$options = is_array($options)?$options:array();	
		foreach( apply_filters('sco_installed_networks', array()) as $network => $n ){
			if( '1' == $this->get_option($n->option, '', true) ){
				$options[$network] = $n->name;
			}
		}

		return $options;
	}
	
	function error_message($msg){
		die($msg);
	}
	
	function get_option($name, $default='', $default_if_empty=true){
		return call_user_func( $this->cb_get_option, $name, $default, $default_if_empty );
	}	
}

class SCO_Profile {
	var $wp_user_id=0;
	var $network='';
	var $user_id='';//network uniq id
	var $username='';
	var $fullname='';
	var $first_name='';
	var $last_name='';
	var $email='';
	var $link='';
	var $picture='';
	var $cb_get_option=false;
	var $verified = false;
	var $usermeta='';
	var $max_username_search_iterations=100;
	var $last_error='';
	//--
	var $logged_in = false;
	function __construct( $network, $data, $cb_get_option=false, $do_login=true, $addon_network=false, $token=false ){
		if( !is_callable($cb_get_option) )return false;
		$this->network = $network;
		$this->cb_get_option = $cb_get_option;
		
		//handle networks added by addon
		if( $addon_network ){
			$method = 'handle_addon_network';
		}else{
			$method = 'handle_'.$network;
		}
	
		if(method_exists($this,$method)){
			if( $this->$method($data,$token) ){

				if( ( $this->wp_user_id = $this->get_wp_user_id() ) && $do_login ){
					if( $this->do_user_login() ){
						
					}else{	
						$this->last_error = __( 'Local profile found, but could not automatically login.','rhsco');
					}
					return true;
				}else{
					if(empty($this->last_error))
						$this->last_error = __( 'Could not find or create local profile.','rhsco');
				}

			}
		}else{
			$this->last_error = sprintf( __('Settings error, %s not available.','rhsco'), $network );
		}
		return false;
	}

	private function handle_addon_network( $data, $token=null ){
		foreach(array(
			'user_id'	=> 'id',
			'username'	=> 'username',
			'fullname'	=> 'name',
			'first_name'=> 'first_name',
			'last_name'	=> 'last_name',
			'email'		=> 'email',
			'link'		=> 'link'
		) as $property => $field){
			$this->$property = isset($data[$field])?$data[$field]:'';
		}

		$this->verified = true;
		$this->usermeta = sprintf('sco_%s',$this->network);
		
		return true;
	}

	private function handle_twitter( $data ){
		foreach(array(
			'user_id'	=> 'id',
			'username'	=> 'screen_name',
			'first_name'=> 'name',
			//'last_name'	=> 'last_name',
			//'email'		=> 'email',
			'link'		=> 'url'
		) as $property => $field){
			$this->$property = isset($data[$field])?$data[$field]:'';
		}
		
		$this->verified = true;
		$this->usermeta = sprintf('sco_%s',$this->network);

		return true;
	}	

	private function handle_facebook( $data ) {
		foreach( array(
			'user_id'  => 'id',
			'fullname' => 'name',
			'email'    => 'email',
		) as $property => $field ) {
			$this->$property = isset( $data[ $field ] ) ? $data[ $field ] : '';
		}

		if ( $this->email ) {
			$this->username = $this->email;
		} else {
			$this->username = $this->user_id . '@facebook.com';
		}

		if ( $this->fullname ) {
			$fullname_array = explode( ' ', $this->fullname );

			if ( is_array( $fullname_array ) and count( $fullname_array ) > 1 ) {
				$this->first_name = $fullname_array[0];
				$this->last_name = $fullname_array[1];
			}
		}
		
		$this->verified = true;
		$this->usermeta = sprintf( 'sco_%s', $this->network );

		return true;
	}

	private function handle_microsoft( $data ){
		foreach(array(
			'user_id'	=> 'id',
			'username'	=> 'id',
			'first_name'=> 'first_name',
			'last_name'	=> 'last_name',
			//'email'		=> 'email',
			'link'		=> 'link'
		) as $property => $field){
			$this->$property = isset($data[$field])?$data[$field]:'';
		}
		
		if(isset($data['emails'])){
			$emails = (array)$data['emails'];
			if(isset($emails['preferred'])){
				$this->email = $emails['preferred'];
			}else if( isset($emails['account']) ){
				$this->email = $emails['account'];
			}
		}
		
		if(!empty($this->email)){
			$this->username = $this->email;
		}
		
		$this->verified = true;
		$this->usermeta = sprintf('sco_%s',$this->network);

		return true;
	}	
	
	private function handle_googleplus($data,$token){
		foreach(array(
			'user_id'	=> 'id',
			'username'	=> 'email',
			'first_name'=> 'given_name',
			'last_name'	=> 'family_name',
			'email'		=> 'email',
			'link'		=> 'link'
		) as $property => $field){
			$this->$property = isset($data[$field])?$data[$field]:'';
		}
		
		$this->verified = true;
		$this->usermeta = sprintf('sco_%s',$this->network);

		return true;
	}
		
	private function handle_linkedin($data,$token){
		foreach(array(
			'user_id'	=> 'id',
			'username'	=> 'id',
			'first_name'=> 'firstName',
			'last_name'	=> 'lastName',
			'email'		=> 'emailAddress',
			'link'		=> 'publicProfileUrl'
		) as $property => $field){
			$this->$property = isset($data[$field])?$data[$field]:'';
		}
		
		$this->username = sprintf('%s@%s', $this->user_id, $this->network);
		
		$this->verified = true;
		$this->usermeta = sprintf('sco_%s',$this->network);

		return true;
	}
	
	public function get_wp_user_id(){
		if(!$this->verified)return false;
		global $wpdb;
		
		$sql = sprintf("SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key='%s' AND meta_value='%s' LIMIT 1",
			$this->usermeta,
			$this->user_id
		);
		
		$wp_user_id = intval( $wpdb->get_var($sql,0,0) );
		if( $wp_user_id > 0 ){
			$this->wp_user_id = $wp_user_id;
			return $wp_user_id;
		} 
		
		if( $wp_user_id=$this->create_wp_user_id() ){
			$this->wp_user_id = $wp_user_id;
			return $wp_user_id;
		}else{
			return false;
		}
	}

	private function create_wp_user_id(){	
		$user_data = array (
			'user_login' 	=> $this->get_uniq_user_login(),
			'display_name' 	=> $this->get_display_name(),
			'user_email' 	=> $this->get_uniq_email(),
			'first_name' 	=> $this->first_name,
			'last_name' 	=> $this->last_name,
			'user_url' 		=> $this->link,
			'user_pass' 	=> wp_generate_password ()
		);
	
		// Create a new user
		$user_id = wp_insert_user ($user_data);			
		if( is_wp_error($user_id) ){
			$this->last_error = $user_id->get_error_message();
			return false;
		}else{
			update_user_meta($user_id, $this->usermeta, $this->user_id);
			do_action ('user_register', $user_id);
			//for cases where registraion actions need to be executed here, but not on regular login.
			do_action ('sco_user_register', $user_id);
			return $user_id;
		}
	}
	
	private function do_user_login(){
		if( $this->wp_user_id && ( $user_data = get_userdata ( $this->wp_user_id ) ) ){
			wp_clear_auth_cookie ();
			wp_set_auth_cookie ($user_data->ID, true);
			do_action ('wp_login', $user_data->user_login, $user_data);		
			$this->logged_in = true;
			return true;
		}
		return false;
	}
	
	private function get_uniq_user_login(){
		if( trim($this->username)!='' && ( null===username_exists( $this->username ) || false===username_exists( $this->username ) ) ){
			return $this->username;
		}else if( ($network_email=$this->get_network_email()) && ( null===username_exists( $network_email ) || false===username_exists( $network_email ) ) ){
			return $network_email;
		}else{
			for( $a=0; $a < $this->max_username_search_iterations; $a++){
				$username=sprintf('%s_%s',$this->username,rand(10000,99999));
				if( null===username_exists( $username ) || false===username_exists( $username ) ){
					return $username;
				}
			}
		}
		return false;
	}
	
	private function get_uniq_email(){
		foreach( $this->get_possible_emails() as $email ){
			if( false===email_exists($email) ){
				return $email;
			}
		}
		return false;
	}
	
	private function get_possible_emails(){
		$emails = array();
		//#1 the primary email
		if(false!==is_email($this->email)){
			$emails[] = $this->email;
		}
		
		//#2 the social network email
		if( $network_email=$this->get_network_email() ){
			$emails[]=$network_email;
		}
		
		//#3 a dummy email
		$emails[] = sprintf( '%s@%s',
			$this->username,
			$this->get_option('dummy_email_domain','dummydomain.com',true)
		);
		
		return $emails;
	}
	
	private function get_network_email(){
		switch($this->network){
			case 'facebook':
				return sprintf('%s',$this->username);	
			case 'linkedin':
				return false;
		}	
		return false;
	}
	
	private function get_display_name(){
		if( empty( $this->fullname ) ){
			$fullname = trim(sprintf('%s %s',$this->first_name,$this->last_name));
		}else{
			$fullname = $this->fullname;
		}
		
		return empty ($fullname) ? $this->username : $fullname ;
	}
	
	function get_option( $name, $default='', $default_if_empty=false ){
		return call_user_func( $this->cb_get_option, $name, $default, $default_if_empty );	
	}	
}
?>