<?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
	
	

	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;
		}
				
		if($degree<$this->max_degree) {
			$tmp = $this->getFriends($user_id);
			
			if(!empty($tmp)){
				foreach($tmp as $key => $user_id_friend){
					$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(){
		if (!empty($this->sn_degree_count)) {
			$datetime = date("Y-m-d H:i:s");
			$datetime = $this->db->DBDate($datetime);
		
			foreach($this->sn_degree_count as $key => $i):
			   $query = "
					UPDATE " . $this->db->prefix . "_sn SET 
					sn_total=" . $i . ", 
					sn_update_datetime=" . $datetime . " 
					WHERE 
					user_id=" . $this->user_id . " AND 
					degree_id=" . $key
				;
				//echo $query;
				$this->db->Execute($query);
			endforeach;
		}
	}//EO updateSnStatistics
	
	
	
	// 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) {

		$datetime = date("Y-m-d H:i:s");
		$datetime = $this->db->DBDate($datetime);

		$query = "
			INSERT INTO " . $this->db->prefix . "_user_blocked
			(user_id_blocker, user_id_blocked, block_description, block_datetime) values (
			" . $this->user_id . ",
			" . $user_id_friend . ",
			'" . $block_description . "',
			" . $datetime . "
			)"
		;
		
	    $result = $this->db->Execute($query);

		if (empty($result)) {
			$error_info = "function=blockUser class=getSocialNetwork.class.php -- " . $query . " -- " . $this->db->ErrorMsg();
			$GLOBALS['am_error_log'][] = array(1, 1, $error_info);
		}
	} //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) {

		$datetime = date("Y-m-d H:i:s");
		$datetime = $this->db->DBDate($datetime);
		
		if (!$this->checkRelation($this->user_id, $relation_id)) {
			$query =
				"INSERT INTO " . $this->db->prefix . "_user_relation
				(user_id, user_id_friend, node_id, relation_create_datetime, relation_type_id)
				VALUES (
				'" . $this->user_id . "',
				'" . $relation_id . "',
				'" . $this->node_id . "',
				" . $datetime . ",
				'" . $relation_type_id . "'
				)"
			;
			
			$result = $this->db->Execute($query);

			if ($result) {

				if (!$this->checkRelation($relation_id, $this->user_id)) {
					$query =
						"INSERT INTO " . $this->db->prefix . "_user_relation
						(user_id, user_id_friend, node_id, relation_create_datetime, relation_type_id)
						VALUES (
						'" . $relation_id . "',
						'" . $this->user_id . "',
						'" . $this->node_id . "',
						" . $datetime . ",
						'" . $relation_type_id . "'
						)"
					;
					
					$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 =
				"UPDATE " . $this->db->prefix . "_user_relation SET
				relation_type_id=" . $this->relation_type_ids['approved'] . "
				WHERE
				user_id=" . $this->user_id .  " and
				user_id_friend=" . $relation_id . "
				limit 1"
			;
			//echo $query;
			$result = $this->db->Execute($query);

			if (isset($result)) {

				if ($this->checkRelation($relation_id, $this->user_id)) {
					$query =
						"UPDATE " . $this->db->prefix . "_user_relation SET
						relation_type_id=" . $this->relation_type_ids['approved'] . "
						WHERE
						user_id=" . $relation_id .  " and
						user_id_friend=" . $this->user_id . "
						limit 1"
					;
					//echo $query;
					$result = $this->db->Execute($query);

					if (isset($result)) {
						$_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='" . $i ."' 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='" . $i . "'"
						;
						
						$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)) {
								    $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);
							
							$url = "http://" . $_SERVER['HTTP_HOST'];
				
							if (dirname ($_SERVER['PHP_SELF']) != "/") {
							    $url .= dirname ($_SERVER['PHP_SELF']);
								
								//trim off last directory as we use the www directory for register.php
								$last_dir_pos = strrpos($url, "/");
								$url = substr($url, 0, $last_dir_pos);
								$url .= "/";
							}
							
							$url .= "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);
		
							//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.
							$datetime = date("Y-m-d H:i:s");
							$datetime = $this->db->DBDate($datetime);
		
							$query = "
								INSERT INTO " . $this->db->prefix . "_user_invited (
								invited_email, 
								user_id, 
								invite_create_datetime
								) VALUES (
								'" . $i ."',
								" . $this->me['user_id'] . ",
								" . $datetime . ")"
							;
		
							$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=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
	
}

?>