<?php

// -----------------------------------------------------------------------
// This file is part of aroundme
// 
// Copyright (C) 2003, 2005 Barnraiser
// http://www.barnraiser.org/
// info@barnraiser.org
// 
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option) any
// later version.
// 
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with program; see the file COPYING. If not, write to the Free
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
// -----------------------------------------------------------------------

class SocialNetwork {
	// CLASS FUNCTIONS
	// SocialNetwork
	// getFriends
	// createNetwork
	// getDegree
	// getDegreePaths
	// updateSnStatistics
	// getNewestAcquaintance
	// getBlockStatus
	// setBlockUser
	// unSetBlockUser
	// insertRelation
	// updateRelation
	// checkRelation
	// getBlockedUsers
	// sendInvite
	// getPendingRelations
	// checkUserBlocked
	// getNewestFriends
	
	

	function SocialNetwork($user_id, $db, $node_id=null, $max_degree=null) {
		$this->user_id = $user_id;
		$this->db = $db;
		
		if (isset($node_id)) {
		    $this->node_id = $node_id;
		}
		
		if (isset($max_degree)) {
		$this->max_degree  = $max_degree;
		}
		
	}

	
	
	// getFriends --------------------------------------------------------------------
	// get friends of a user (degree=1)
	// erik sundelof - 8th January 2004
	//
	function getFriends($user_id){
		$query = "
			SELECT r.user_id_friend
			FROM " . $this->db->prefix . "_user_relation r, " . $this->db->prefix . "_user u  
			WHERE 
			r.user_id=" . $user_id . " AND 
			r.user_id_friend=u.user_id AND 
			r.user_id_friend!=" . $this->user_id . " AND 
			r.relation_type_id=" . $this->relation_type_ids['approved'] . " AND 
			u.status_id=" . $this->status_ids['active'] . " 
			order by r.user_id_friend"
		;
		//echo $query . "<br>";
		
		$result = $this->db->Execute($query);

		if (isset($result->fields)) {
			$temp = array();

			while (!$result->EOF) {
				$temp1 = $result->fields["user_id_friend"];
				array_push($temp, $temp1);
				$result->MoveNext();
			}

			$result->Close();
			
			return $temp;
		}
		else {
			$error_info = "function=getFriends class=getSocialNetwork.class.php -- " . $query . " -- " . $this->db->ErrorMsg();
			$GLOBALS['am_error_log'][] = array(1, 1, $error_info);
		}
	}//EO getFriends
	
	
	
	// createNetwork --------------------------------------------------------------------
	// erik sundelof - 8th January 2004
	//
	function createNetwork($user_id=null, $degree=0, $path=null){
		
		if (!isset($path)) {
		    $path = array();
		}
		
		//statistics
		if (!isset($this->sn_degree_count[$degree])) {
		    $this->sn_degree_count[$degree] = 1;
		}
		else {
			$this->sn_degree_count[$degree] = $this->sn_degree_count[$degree]+1;
		}
		
		
		if(empty($user_id)){
			$user_id = $this->user_id;
			$path[] = $user_id;
			$this->tree = array();
		}
		else {
			$path[] = $user_id;
			
			$temp1 = array(
				"relation" => $path,
				"user_id" => $user_id,
				"degree" => $degree);
						
			$this->tree[$user_id][] =  $temp1;
		}
		//user_id check removed by tom as it stops the social network totals being built in sn_network.php
		//if($degree<$this->max_degree && !isset($this->tree[$user_id])) {
		if($degree<$this->max_degree) {
			
			$tmp = $this->getFriends($user_id);
			
			if(!empty($tmp)){
				foreach($tmp as $key => $user_id_friend){
					//if($user_id_friend!=$this->user_id){
					//if($user_id_friend!=$this->user_id && $user_id_friend!=$user_id){
					if(!in_array($user_id_friend,$path)) { // fix by Yuki Shida - 4th May 2005
						$this->tree = $this->createNetwork($user_id_friend, ($degree+1), $path);
					}
				}
			}
			
			return $this->tree;

		}
		else {
			return $this->tree;
		}
		
	}//EO createNetwork
	
	
	
	
	// getDegree --------------------------------------------------------------------
	// erik sundelof - 8th January 2004
	//
	function getDegree($user_id_friend){
		if ($this->user_id != $user_id_friend) {
			if (isset($this->tree[$user_id_friend])) {
			    usort($this->tree[$user_id_friend], "compare");
				return $this->tree[$user_id_friend][0];
			}
			else {
				return false;
			}
		}
		else {
			return array("degree" => 0); //me therefore degree = 0
		}
	}//EO getDegree
	
	
	
	// getDegreePaths --------------------------------------------------------------------
	// erik sundelof - 8th January 2004
	//
	function getDegreePaths($user_id_friend){
		if (isset($this->tree[$user_id_friend])) {
		    usort($this->tree[$user_id_friend], "compare");
			return $this->tree[$user_id_friend];
		}
		else {
			return false;
		}
	}//EO getDegreePaths
	
	
	
	// updateSnStatistics --------------------------------------------------------------------
	// tom calthrop - 8th January 2004
	//
	function updateSnStatistics(){
		$this->sn_degree_count = $this->_getSnDegreeCount();
		
		if (!empty($this->sn_degree_count)) {
			
			foreach($this->sn_degree_count as $key => $i):
				$query = "
					SELECT * FROM " . $this->db->prefix . "_sn
					WHERE 
					user_id=" . $this->user_id . " AND 
					degree_id=" . $key
				;
				
				$result = $this->db->Execute($query);
				
				$rec = array();
				$rec['sn_total'] = $i;
				$rec['sn_update_datetime'] = time();
				
				$query = $this->db->GetUpdateSQL($result, $rec, false, get_magic_quotes_gpc());
				$result = $this->db->Execute($query);
				
			endforeach;
		}
		
		
		
	}//EO updateSnStatistics
	
	
	
	// updateSnStatistics --------------------------------------------------------------------
	// Yuki Shida - 4th May 2005
	//
		function _getSnDegreeCount() {
 	        if(!isset($this->max_degree)) {
 	                $this->max_degree = 4;
 	        }
 		for($counter = 0 ; $counter <= $this->max_degree ; $counter++) {
 		        $sn_degree_count[$counter] = 0;
 		}
 	        if(isset($this->tree)) {
 		        foreach($this->tree as $user_id_friend => $user_relations) {
 			        $degree_array = $this->getDegree($user_id_friend);
 				$sn_degree_count[$degree_array['degree']]++;
 			}
 		}
 		return $sn_degree_count;
 	}
	
	
	// getNewestAcquaintance --------------------------------------------------------------------
	// receives social network array and looks through it to get newest date
	// tom calthrop - 25th April 2004
	//
	function getNewestAcquaintance() {
		$newestDate = "0000-00-00 00:00:00";

		if (isset($this->sn_arr)) {
		
		foreach ($this->sn_arr as $key => $r) :
			if (!empty($r['acquaintance'])) {
			
			foreach ($r['acquaintance'] as $key => $i) :
				if ($newestDate <= $i['user_create_datetime']) {
				    $newestDate = $i['user_create_datetime'];
					$newest_profile_id = $i['profile_id'];
				}
			endforeach;
			}

		endforeach;
		}

		if (isset($newest_profile_id)) {
		    return $newest_profile_id;
		}
	}//EO getNewestAcquaintance
	
	
	
	// getBlockStatus --------------------------------------------------------------------
	// returns true if a user is blocked or not
	// tom calthrop - 25th April 2004
	//
	function getBlockStatus($user_id_friend) {

		$query = "
			SELECT user_id_blocked
			FROM " . $this->db->prefix . "_user_blocked
			WHERE
			user_id_blocker=" . $this->user_id . " and
			user_id_blocked=" . $user_id_friend
		;
		
	    $result = $this->db->Execute($query);

		if (isset($result->fields)) {
			$result->Close();
			
			if (isset($result->fields['user_id_blocked'])) {
				return true;
			}
		}
		else {
			$error_info = "function=getBlockStatus class=getSocialNetwork.class.php -- " . $query . " -- " . $this->db->ErrorMsg();
			$GLOBALS['am_error_log'][] = array(1, 1, $error_info);
		}
	}//EO getBlockStatus
	
	
	
	// setBlockUser --------------------------------------------------------------------
	// sets a user to blocked status
	// tom calthrop - 25th April 2004
	//
	function setBlockUser($user_id_friend, $block_description) {
		
		$rec = array();
		$rec['user_id_blocker'] = $this->user_id;
		$rec['user_id_blocked'] = $user_id_friend;
		$rec['block_description'] = $block_description;
		$rec['block_datetime'] = time();
		
		$table = $this->db->prefix . "_user_blocked";
			
		$query = $this->db->GetInsertSQL($table, $rec, get_magic_quotes_gpc());
		$result = $this->db->Execute($query);
		
	} //EO setBlockUser
	
	
	
	// unSetBlockUser --------------------------------------------------------------------
	// sets a user to blocked status
	// tom calthrop - 25th April 2004
	//
	function unSetBlockUser($user_id_friend) {

		$query = "
			DELETE FROM " . $this->db->prefix . "_user_blocked
			WHERE
			user_id_blocker=" . $this->user_id . " and
			user_id_blocked=" . $user_id_friend
		;
		
	    $result = $this->db->Execute($query);

		if (empty($result)) {
			$error_info = "function=unblockUser class=getSocialNetwork.class.php -- " . $query . " -- " . $this->db->ErrorMsg();
			$GLOBALS['am_error_log'][] = array(1, 1, $error_info);
		}

	} //EO unSetBlockUser


	
	// insertRelation --------------------------------------------------------------------
	// inserts a users relationship to another user
	// tom calthrop - 19th April 2004
	//
	function insertRelation ($relation_id, $relation_type_id) {
		
		if (!$this->checkRelation($this->user_id, $relation_id)) {
			
			$rec = array();
			$rec['user_id'] = $this->user_id;
			$rec['user_id_friend'] = $relation_id;
			$rec['node_id'] = $this->node_id;
			$rec['relation_create_datetime'] = time();
			$rec['relation_type_id'] = $relation_type_id;
			
			$table = $this->db->prefix . "_user_relation";
				
			$query = $this->db->GetInsertSQL($table, $rec, get_magic_quotes_gpc());
			$result = $this->db->Execute($query);
			
			if ($result) {
				
				if (!$this->checkRelation($relation_id, $this->user_id)) {
					
					$rec = array();
					$rec['user_id'] = $relation_id;
					$rec['user_id_friend'] = $this->user_id;
					$rec['node_id'] = $this->node_id;
					$rec['relation_create_datetime'] = time();
					$rec['relation_type_id'] = $relation_type_id;
					
					$table = $this->db->prefix . "_user_relation";
						
					$query = $this->db->GetInsertSQL($table, $rec, get_magic_quotes_gpc());
					$result = $this->db->Execute($query);
					
					if ($result) {
						return true;
					}
				}
			}
		}
	}//EO insertRelation

	
	
	// updateRelation --------------------------------------------------------------------
	// updates a users relationship to another user
	// tom calthrop - 19th April 2004
	//
	function updateRelation ($relation_id) {

		if ($this->checkRelation($this->user_id, $relation_id)) {
			
			$query = "
				SELECT * FROM " . $this->db->prefix . "_user_relation 
				WHERE 
				user_id=" . $this->user_id .  " AND 
				user_id_friend=" . $relation_id
			;
			
			$result = $this->db->Execute($query);
			
			$rec = array();
			$rec['relation_type_id'] = $this->relation_type_ids['approved'];
			
			$query = $this->db->GetUpdateSQL($result, $rec, false, get_magic_quotes_gpc());
			$result = $this->db->Execute($query);
			
			if ($this->checkRelation($relation_id, $this->user_id)) {
				
				$query = "
					SELECT * FROM " . $this->db->prefix . "_user_relation  
					WHERE 
					user_id=" . $relation_id .  " AND 
					user_id_friend=" . $this->user_id
				;
				
				$result = $this->db->Execute($query);
				
				$rec = array();
				$rec['relation_type_id'] = $this->relation_type_ids['approved'];
				
				$query = $this->db->GetUpdateSQL($result, $rec, false, get_magic_quotes_gpc());
				$result = $this->db->Execute($query);
				
				$_SESSION['s_social_network'] = $this->createNetwork();
				$this->updateSnStatistics();
				return true;
			}
		}
	}//EO updateRelation

	
	
	// checkRelation --------------------------------------------------------------------
	// checks userA has a relationship with userB
	// tom calthrop - 19th April 2004
	//
	function checkRelation($user_id, $relation_id) {

		$query = "
			SELECT user_id
			FROM " . $this->db->prefix . "_user_relation
			where
			user_id=" . $user_id . " and
			user_id_friend=" . $relation_id
		;
		
		$result = $this->db->Execute($query);

		if (isset($result->fields['user_id']) && $result->fields['user_id'] > 0) {

			return true;
		}
	}//EO checkRelation
	
	
	
	// getBlockedUsers --------------------------------------------------------------------
	// returns all blocked users to a user
	// tom calthrop - 24th April 2004
	//
	function getBlockedUsers() {
		$query = "
			SELECT b.user_id_blocked, b.block_datetime, b.block_description, 
			b.profile_id_blocked, p.profile_nic 
			FROM " . $this->db->prefix . "_user_blocked b 
			LEFT JOIN " . $this->db->prefix . "_user_profile p ON b.user_id_blocked=p.user_id
			WHERE 
			b.user_id_blocker=" . $this->user_id . " AND 
			p.profile_default=1 
			order by p.profile_nic"
		;
		
	    $result = $this->db->Execute($query);
	
		if (isset($result->fields)) {
	
			$temp = array();
	
			while (!$result->EOF) {
				$temp1 = $result->fields;
				$temp1['block_datetime'] = $this->date->formatDate($temp1['block_datetime']);
				
				array_push($temp, $temp1);
				$result->MoveNext();
			}
	
			$result->Close();
	
			return $temp;
		}
	}//EO getBlockedUsers
	
	
	
	// sendInvite --------------------------------------------------------------------
	// send an invite from sn_invite.php
	// tom calthrop - 24th April 2004
	//
	function sendInvite($data) {
		//prepare data
		if (empty($data['to'])) {
			$GLOBALS['am_error_log'][] = array(2, null, null);
		}
		
		if (empty($GLOBALS['am_error_log'])) {
			$data['to'] = trim($data['to']);
			$emails = preg_split("/[\s,]+/", $data['to']);
			$this->total_emails_sent = 0;
			
			//check each email
			foreach($emails as $key => $i):
	
				if(!preg_match('/^[-A-Za-z0-9_.]+[@][A-Za-z0-9_-]+([.][A-Za-z0-9_-]+)*[.][A-Za-z]{2,8}$/', $i)) {
					$GLOBALS['am_error_log'][] = array(3, null, $i); //email invalid
				}
				else {
					//check to see if we have already invited them
					$query = "
						SELECT DISTINCT user_id 
						FROM " . $this->db->prefix . "_user_invited 
						WHERE 
						invited_email=" . $this->db->qstr($i, get_magic_quotes_gpc()) ." AND 
						user_id=" . $this->me['user_id']
					;
					
					$result = $this->db->Execute($query);
					
					if(!isset($result->fields['user_id'])) {
						
						//check to see if user in User table
						$query = "
							SELECT user_id 
							FROM " . $this->db->prefix . "_user 
							WHERE 
							user_email=" . $this->db->qstr($i, get_magic_quotes_gpc())
						;
						
						$result = $this->db->Execute($query);
						
						if (isset($result->fields['user_id'])) {
							//check I am not daft enough to invite myself
							if($result->fields['user_id'] != $this->me['user_id']) {
								//get the degree and see if they are in my social network already
								$degree_path = $this->getDegree($result->fields['user_id']);
								
								if (!empty($degree_path) && $degree_path['degree'] == 1) {
								    $GLOBALS['am_error_log'][] = array(32, 1, $i); //already in social network
								}
								elseif($this->checkUserBlocked($result->fields['user_id'])) {//we check that the user has not blocked me
									//send internal instant message to user
									$body_file_im_txt = str_replace("NAME", $this->me['firstname'], $this->body_im_file);
									
									// add a br_relation record with a level of "approval_pending"
									if ($this->insertRelation($result->fields['user_id'], $this->relation_type_ids['approval_pending'])) {
								    	//send IM
										$this->im->sendMessage($result->fields['user_id'], $this->txt_subject_im_invite, $body_file_im_txt, 1);
										$this->total_emails_sent++;
									}
								}	
							}
						}
						else {
							//send email
							$body_file_mail_txt = str_replace("USERMESSAGE", $data['message'], $this->body_mail_file);
							$body_file_mail_txt = str_replace("NAME", $this->me['firstname'], $body_file_mail_txt);
							
							//create URL
							$url = "http://" . $_SERVER['HTTP_HOST'];
							$url .= dirname ($_SERVER['PHP_SELF']);
							//sometimes the server adds / as the last characture - we need to check.
							if (substr($url, -1, 1) != "/") {
							    $url .= "/";
							}
							
							$url .= "p_register.php?invitee=" . $this->me['user_id'] . "&email=" . htmlspecialchars($i) . "&language_id=" . $this->me['language_id'];
							
							$body_file_mail_txt = str_replace("URL", $url, $body_file_mail_txt);
							$body_file_mail_txt = stripslashes($body_file_mail_txt);
							
							$body_file_mail_txt = utf8_decode($body_file_mail_txt);
							
							//send email to email address
							$this->mail->Subject = $data['subject'];
							$this->mail->Body = $body_file_mail_txt;
							
							$this->mail->ClearAddresses();
							$this->mail->AddAddress($i, '');
							
							if(!$this->mail->Send()) {
								$GLOBALS['am_error_log'][] = array(18, null, $this->mail->ErrorInfo);
							}
							else {
								$this->total_emails_sent++;
							}
							
							//insert record into user invitee table
							$rec = array();
							$rec['invited_email'] = $i;
							$rec['user_id'] = $this->me['user_id'];
							$rec['invite_create_datetime'] = time();
							
							$table = $this->db->prefix . "_user_invited";
							
							$query = $this->db->GetInsertSQL($table, $rec, get_magic_quotes_gpc());
							$result = $this->db->Execute($query);
							
						}
					}
					else {
						$GLOBALS['am_error_log'][] = array(31, 1, $i); //email invalid
					}
				}
			endforeach;
		}
	}//EO sendInvite
	
	
	
	// getPendingRelations --------------------------------------------------------------------
	// get pending relations (and delete old ones)
	// tom calthrop - 24th April 2004
	//
	function getPendingRelations () {
		//delete anything older than 3 months ----------------------------
		$datetime = date(mktime()-(86400*21));
		$datetime = $this->db->DBDate($datetime);

		$query = "
			DELETE FROM " . $this->db->prefix . "_user_relation
			where
			user_id=" . $this->user_id . " and
			relation_type_id=" . $this->relation_type_ids['approval_pending'] . " and
			relation_create_datetime < " . $datetime
		;
	
		$result = $this->db->Execute($query);

		$query = "
			DELETE FROM " . $this->db->prefix . "_user_relation
			where
			user_id_friend=" . $this->user_id . " and
			relation_type_id=" . $this->relation_type_ids['approval_pending'] . " and
			relation_create_datetime < " . $datetime
		;
	
		$result = $this->db->Execute($query);

		$query = "
			DELETE FROM " . $this->db->prefix . "_user_invited
			where
			user_id=" . $this->user_id . " and
			invite_create_datetime < " . $datetime
		;
	
		$result = $this->db->Execute($query);
		
		
		//Get Pending relations -------------------------------------------
		$temp = array();
		
		//get relations pending from users already registered.
		$query = "
			SELECT r.relation_create_datetime as datetime, u.user_email as email
			FROM " . $this->db->prefix . "_user_relation r
			LEFT JOIN " . $this->db->prefix . "_user u ON r.user_id_friend=u.user_id
			where
			r.user_id=" . $this->user_id . " and
			r.relation_type_id=" . $this->relation_type_ids['approval_pending'] . "
			order by r.relation_create_datetime"
		;
		
		$result = $this->db->Execute($query);
	
		if (isset($result->fields)) {
			
			while (!$result->EOF) {
				$temp1 = $result->fields;
				$temp1['datetime'] = $this->date->formatDate($temp1['datetime']);
	
				array_push($temp, $temp1);
	
				$result->MoveNext();
			}
			$result->Close();
		}
	
		//get the pending requests for emails for used not in DB
		$query = "
			SELECT DISTINCT invited_email as email, invite_create_datetime as datetime
			FROM " . $this->db->prefix . "_user_invited ui
			where
			ui.user_id=" . $this->user_id . "
			order by ui.invite_create_datetime"
		;
	
		$result = $this->db->Execute($query);
	
		if (isset($result->fields)) {
		
			while (!$result->EOF) {
				$temp1 = $result->fields;
				$temp1['datetime'] = $this->date->formatDate($temp1['datetime']);
	
				array_push($temp, $temp1);
	
				$result->MoveNext();
			}
			$result->Close();
		}
	
		return $temp;
		
	}//EO getPendingRelations
	
	
	
	// getSocialNetworkSummary --------------------------------------------------------------------
	// tom calthrop - 4th January 2005
	//
	function getSocialNetworkSummary () {
		$query = "
			SELECT profile_id, degree_id, sn_total 
			FROM " . $this->db->prefix . "_sn 
			WHERE 
			user_id=" . $this->user_id
		;
		
		$result = $this->db->Execute($query);
		
		if (isset($result->fields)) {

			$temp = array();

			while (!$result->EOF) {
				$temp1 = $result->fields;
				array_push($temp, $temp1);
				$result->MoveNext();
			}

			$result->Close();
			return $temp;
		}
		else {
			$error_info = "function=getSocialNetworkSummary class=SocialNetwork.class.php -- " . $query . " -- " . $this->db->ErrorMsg();
			$GLOBALS['am_error_log'][] = array(1, 1, $error_info);
		}
	}//EO getSocialNetworkSummary


	
	// checkUserBlocked --------------------------------------------------------------------
	//check if the $to_user_id has blocked me
	//tom calthrop - 21st April 2004
	function checkUserBlocked($to_user_id) {
		if ($to_user_id == $this->user_id) {
			return true;
		}
		else {
			$query = "
				SELECT user_id_blocker
				FROM " . $this->db->prefix . "_user_blocked
				WHERE
				user_id_blocker = " . $to_user_id . " and
				user_id_blocked = " . $this->user_id
			;
			
			$result = $this->db->Execute($query);
	
			if (empty($result->fields['user_id_blocker'])) {
				return true;
			}
		}
	}//EO checkUserBlocked

	
	
	// getNewestFriends --------------------------------------------------------------------
	// get newest friend of a user
	// tom calthrop - 19th January 2004
	//
	function getNewestFriends($user_id){
		$query = "
			SELECT r.user_id_friend, u.user_create_datetime 
			FROM " . $this->db->prefix . "_user_relation r, " . $this->db->prefix . "_user u  
			WHERE 
			r.user_id=" . $user_id . " AND 
			r.user_id_friend=u.user_id AND 
			r.user_id_friend!=" . $this->user_id . " AND 
			r.relation_type_id=" . $this->relation_type_ids['approved'] . " AND 
			u.status_id=" . $this->status_ids['active'] . " 
			order by u.user_create_datetime desc"
		;
		
		if (isset($this->limit)) {
			$result = $this->db->SelectLimit($query, $this->limit);
		} 
		else {
			$result = $this->db->Execute($query);
		}

		if (isset($result->fields)) {
			$temp = array();

			while (!$result->EOF) {
				$temp1 = $result->fields;
				array_push($temp, $temp1);
				$result->MoveNext();
			}

			$result->Close();
			
			return $temp;
		}
		else {
			$error_info = "function=getNewestFriends class=getSocialNetwork.class.php -- " . $query . " -- " . $this->db->ErrorMsg();
			$GLOBALS['am_error_log'][] = array(1, 1, $error_info);
		}
	}//EO getNewestFriends
	
}

?>