<?php

/*
   +----------------------------------------------------------------------+
   | Comment Class                                                        |
   | Author: Adam Goldberg                                                |
   +----------------------------------------------------------------------+
   | Copyright (c) 2008-2009 Adam J Goldberg                              |
   | This file is part of Lifebox.                                        |
   |                                                                      |
   | Lifebox 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 3 of the License, or    |
   | (at your option) any later version.                                  |
   |                                                                      |
   | Lifebox 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 Lifebox.  If not, see <http://www.gnu.org/licenses/>.     |
   +----------------------------------------------------------------------+
   | Handles comments for a photo					  |
   +----------------------------------------------------------------------+
	function Comment ($comment_id=false) {
        function setInfo ($data) {
        function commit(){
        function delete($photo_id=false){
	function updateCommentList($photo_id=false) {
	function notifyThread($title,$url) {
	function sendNotification($title,$url) {
	function getLatestComments($limit=3,$photo_id=false) {
        function _generateKey(){
   +----------------------------------------------------------------------+
*/

require_once 'Photo.inc.php';
require_once 'Mail.inc.php';
require_once 'Text.inc.php';

class Comment {

	var $info;
	var $comment_id;
	var $new_comment;

	/*****************************************************************
	 * Constructor
         *****************************************************************/
	function Comment ($comment_id=false) {

		if ($comment_id) {
			$this->comment_id = $comment_id;
			$this->new_comment = false;
		} else {
			$this->comment_id = $this->_generateKey();
			$this->new_comment = true;
		}
	}

	/*****************************************************************
         * setInfo
         *****************************************************************/
        function setInfo ($data) {
        global $CONFIG;
        global $ERROR;
	global $_USER;

		if ($_USER) {

			if (isset($data['name'])) {
				$name_array = Text::getNameArray($data['name']);
				$this->info['first'] = $name_array['first_name'];
				$this->info['last'] = $name_array['last_name'];
			}

			if (empty($this->info['first'])) {
				$this->info['first'] = $_USER['first'];
			}

			if (empty($this->info['last'])) {
				$this->info['last'] = $_USER['last'];
			}

			if (empty($this->info['email'])) {
				$this->info['email'] = $_USER['email'];
			}
		}

                foreach ($data as $key => $value){
			$value = strip_tags($value);

			if ($key !== 'name') {
	                        $this->info[$key] = strip_tags(trim($value));

	                        if ($this->info[$key] == 'on'){
	                                $this->info[$key] = 1;
	                        }
			}
                }
	
		#Insert the comment_id
		$this->info['comment_id'] = $this->comment_id;

		#ERROR Checking
                if (empty($this->info['text'])) {
                        $ERROR['title'] = 'Title is missing';
                }

                if (empty($this->info['email'])) {
                        $ERROR['email'] = 'E-Mail is missing';
                } else if (!Text::isValidEmail($this->info['email'])) {
			$ERROR['email'] = 'Invalid email address';
		}

		if (empty($this->info['first'])) {
                        $ERROR['first'] = 'First name is missing';
                }

		if (empty($this->info['last'])) {
                        $ERROR['last'] = 'Last name is missing';
                }

		if (empty($this->info['photo_id'])) {
                        $ERROR['photo_id'] = 'photo_id was not supplied';
                }

		if (empty($this->info['comment_id'])) {
                        $ERROR['comment_id'] = 'comment_id was not supplied';
                }

		if ($ERROR) {
			return false;
		} else {
			return true;
		}
        }

	/*****************************************************************
         * Adds a new comment.
         *****************************************************************/
        function commit(){
        global $CONFIG;
        global $ERROR;
        global $db;

                if (!empty($ERROR)){
                        return false;
                }

                if ($this->new_comment){

                        #Generate the current time, ip, and host
                        $timestamp = time();
			$ip = $_SERVER['REMOTE_ADDR'];
			$host = gethostbyaddr($_SERVER['REMOTE_ADDR']);

                        #Build the query.
			$insert_into = '';
			$values = '';
                        foreach ($this->info as $key=>$value){
                                
                        	$insert_into .= "$key,";
                                $values .= "'$value',";
                        }
                        
                        #strip the last comma
                        $insert_into = substr($insert_into,0,-1);
                        $values = substr($values,0,-1);


                        $query = "INSERT INTO ".$CONFIG['tbl_comments']."
                                  (timestamp_created,
				   ip,
				   host,
                                   $insert_into)
                                  VALUES ($timestamp,
					  '$ip',
					  '$host',
                                           $values)";
                }
                
                $result = $db->Execute($query);
                
		if ($result AND !$db->ErrorMsg()) { 
		
			$p = new Photo($this->info['photo_id']);
			$p->increaseComments();
                       
			$this->updateCommentList();
 
			return true;
                } else {
                        return false;
                }
        }

	/*****************************************************************
	 * Delete a comment
         *****************************************************************/
        function delete($photo_id=false){
	global $CONFIG;
	global $db;
	global $_USER;
	global $ERROR;
	
		if (!$photo_id) {
                        $photo_id = $this->info['photo_id'];
                }

		if ($_USER['level'] < $CONFIG['permission_delete_comments']) {
			$ERROR['permission'] = 'You do not have delete access';
			return false;	
		}

		$query = "DELETE FROM ".$CONFIG['tbl_comments']."
			  WHERE comment_id = '$this->comment_id'";
		$result = $db->Execute($query);

		if ($result) {

			$this->updateCommentList($photo_id);

			$p = new Photo($photo_id);
			$p->decreaseComments();

			return true;
		} else {
			return false;
		}

	}

	/*****************************************************************
	 * Update the comment list cache for the given photo
         *****************************************************************/
	function updateCommentList($photo_id=false) {
	global $CONFIG;
	global $db;

		if (!$photo_id) {
			$photo_id = $this->info['photo_id'];
		}

		#Check that a photo_id was supplied in the setInfo() function
		if (empty($photo_id)) {
			$ERROR['no_photo_id'] = 'No photo id has been specified';
			return false;
		}

		#Build a string of all the comments for a given photo
		$comments_list = Comment::getLatestComments(10000,$photo_id);
		$string = '';
		foreach ($comments_list as $comment) {
		
			$string .= addslashes($comment['text']).' ';

		}

		#Remove the last space at the end of the strong
		$string = substr($string,0,-1);

		#Update the string for the specified photo
		$query = "UPDATE ".$CONFIG['tbl_photos']."
			  SET comment_list = '$string'
			  WHERE photo_id = '".$photo_id."'";
		$result = $db->Execute($query);

		if ($result) {
			return true;
		} else {
			return false;
		}
	}

	/*****************************************************************
	 * Notify all people who have previously commented on a photo
         *****************************************************************/
	function notifyThread($title,$url) {
	global $CONFIG;
	global $db;
	global $_USER;

		if (substr($url,0,1) == '/') {
                        $url = substr($url,1);
                }

		$url = $CONFIG['full_site'].$url;

		#Build list of e-mail addresses
		$query = "SELECT DISTINCT email
			  FROM comments
			  WHERE photo_id = '".$this->info['photo_id']."'";
		$results = $db->getAll($query);

		#Push comment emails onto the contact array
		if ($results) {
			for($i=0;$i<count($results);$i++) {

				#No need to e-mail ourselves.
				if ($_USER['email'] !== $results[$i]['email']) {
					$contact_emails[$results[$i]['email']] = $results[$i]['email'];
				}
			}
		}

		#First, e-mail all of the people who have submitted a comment
		#for this picture.
                foreach ($contact_emails as $email) {

                        if (empty($ERROR) AND $email !== $_USER['email']){
                                $from = $CONFIG['email_from_comment'];
                                $subject = $this->info['first'].' '.$this->info['last'].' replied to your comment';
                                $message = $this->info['first'].' '.$this->info['last'].' has submitted a comment'."\r\n";
                                $message .= "in reply to yours on photo \"$title\"\r\n\r\n";
                                $message .= "$url\r\n\r\n";
                                $message .= "-------------------------\r\n";
                                $message .= $this->info['text']."\r\n";
                                $message .= "-------------------------";

                                $message = stripslashes($message);

                                $m = new Mail();
                                $m->setTo($email);
                                $m->setFrom($from);
                                $m->setSubject($subject);
                                $m->setTextMessage($message);

                                $m->send();
                        }
                }

		# Lookup all Tags on people, get their e-mail addresses
		# And add these e-mail addresses to the e-mail array	
		# Now notify all the people who are tagged in the photo
		# We make sure that people are e-mailed only if they have
		# not commented already, or their email is sent above.
                $p = new Photo($this->info['photo_id']);
                $tagged_email_array = $p->taggedPeopleEmails();

		if ($tagged_email_array) {
			$new_contact_emails = array_diff($tagged_email_array,$contact_emails);
                }


		#Now e-mail all the people who are tagged in this photo who
		#have not already submitted a comment
		foreach ($new_contact_emails as $email) {

	                if (empty($ERROR) AND $email !== $_USER['email']){
	                        $from = $CONFIG['email_from_comment'];
	                        $subject = $this->info['first'].' '.$this->info['last'].' added a comment';
	                        $message = $this->info['first'].' '.$this->info['last'].' has submitted a comment'."\r\n";
	                        $message .= "on one of your pictures, \"$title\"\r\n\r\n";
	                        $message .= "$url\r\n\r\n";
	                        $message .= "-------------------------\r\n";
	                        $message .= $this->info['text']."\r\n";
	                        $message .= "-------------------------";

	                        $message = stripslashes($message);

	                        $m = new Mail();
	                        $m->setTo($email);
	                        $m->setFrom($from);
	                        $m->setSubject($subject);
	                        $m->setTextMessage($message);

	                        $m->send();
	                }
		}

	}

	 /*****************************************************************
	 * Notify the site owner of a comment
         *****************************************************************/
	function sendNotification($title,$url) {
	global $CONFIG;

		#If no notification email is set in config
		#return false
		if (empty($CONFIG['email_notify'])) {
			return false;
		}

		if (substr($url,0,1) == '/') {
			$url = substr($url,1);
		}

		$url = $CONFIG['full_site'].$url;

		if (empty($ERROR)){
	                $email = $CONFIG['email_notify'];
	                $from = $CONFIG['email_from_comment'];
	                $subject = $this->info['first'].' '.$this->info['last'].' submitted a comment';
			$message = $this->info['first'].' '.$this->info['last'].' has submitted a comment'."\r\n";
			$message .= "on photo \"$title\"\r\n\r\n";
			$message .= "$url\r\n\r\n";
	                $message .= "-------------------------\r\n";
	                $message .= $this->info['text']."\r\n";
	                $message .= "-------------------------\r\n\r\n";
	                $message .= "Sender Host: ".gethostbyaddr($_SERVER['REMOTE_ADDR'])." (".$_SERVER['REMOTE_ADDR'].")";

	                $message = stripslashes($message);

	                $m = new Mail();
	                $m->setTo($email);
	                $m->setFrom($from);
	                $m->setSubject($subject);
	                $m->setTextMessage($message);
                
			$m->send();
		}
        }

	/*****************************************************************
	 * Gets latest comments
         *****************************************************************/
	function getLatestComments($limit=3,$photo_id=false) {
	global $CONFIG;
	global $db;
	global $_USER;

		#Don't display comments unless the user has
		#authenticated
		if ($_USER['level'] <= 1) {
			return false;
		}

		if ($photo_id) {
			$photo_restriction = "AND p.photo_id = '$photo_id'";
			$order = 'ORDER BY c.timestamp_created ASC';
		} else {
			$order = 'ORDER BY c.timestamp_created DESC';
		}

		if (!$photo_id) {
			$query = "SELECT *
				  FROM ".$CONFIG['tbl_comments']."
				  ORDER BY timestamp_created DESC";
			$results = $db->cacheSelectLimit($CONFIG['cache_latest_comments'],$query,$limit,0);
	
			if (!$results) {
				return false;
			}
		
			$results = $results->getAll();

			for ($i=0; $i<count($results); $i++) {
				$query = "SELECT a.title_url as album_title_url,
	                                         p.title_url as photo_title_url,
	                                         p.comments as comments,
	                                         p.title as title,
	                                         p.filename_extension
	                                  FROM ".$CONFIG['tbl_photos']." p,
	                                       ".$CONFIG['tbl_album_photo_map']." apm,
	                                       ".$CONFIG['tbl_albums']." a
					  WHERE p.photo_id = apm.photo_id AND
						apm.album_id = a.album_id AND
						p.photo_id = '".$results[$i]['photo_id']."'";
				$row = $db->getRow($query);
				$results[$i]['album_title_url'] = $row['album_title_url'];
                                $results[$i]['photo_title_url'] = $row['photo_title_url'];
				$results[$i]['comments'] = $row['comments'];
				$results[$i]['title'] = $row['title'];
				$results[$i]['filename_extension'] = $row['filename_extension'];
			}

		} else {
			$query = "SELECT c.*,
					 a.title_url as album_title_url,
					 p.title_url as photo_title_url,
					 p.comments as comments,
					 p.title as title,
					 p.filename_extension
				  FROM ".$CONFIG['tbl_comments']." c,
				       ".$CONFIG['tbl_photos']." p,
				       ".$CONFIG['tbl_album_photo_map']." apm,
				       ".$CONFIG['tbl_albums']." a
				  WHERE c.photo_id = p.photo_id AND
					a.album_id = apm.album_id AND
					apm.photo_id = p.photo_id AND
					p.level <= ".$_USER['level']."
					$photo_restriction
				  GROUP BY comment_id
				  $order";
			$results = $db->cacheSelectLimit($CONFIG['cache_latest_comments'],$query,$limit,0);

			if (!$results) {
				return false;
			}
	
			$results = $results->getAll();
		}

			for ($i=0; $i<count($results); $i++) {
				$results[$i]['recent_url'] = $CONFIG['full_site'].'photo/'.$results[$i]['photo_id'].'-main_recent.'.$results[$i]['filename_extension'];
				$results[$i]['preview_url'] = $CONFIG['full_site'].'photo/'.$results[$i]['photo_id'].'-main_preview.'.$results[$i]['filename_extension'];
				$results[$i]['full_url'] = $CONFIG['full_site'].'photo/'.$results[$i]['photo_id'].'-main_full.'.$results[$i]['filename_extension'];
                                $results[$i]['url'] = $CONFIG['full_site'].$results[$i]['album_title_url'].'/'.$results[$i]['photo_title_url'];
				$results[$i]['text'] = Text::highlightLinks($results[$i]['text']);
			}

	
			return $results;
	}

	/*****************************************************************
	 * Generates a 32-digit unique comment ID
         *****************************************************************/
        function _generateKey(){
        global $CONFIG;
	global $db;

                $key = md5(uniqid(rand(), true));

                #First, check that the unique member_id is actually unique
                $query = "SELECT COUNT(*) as num
                          FROM ".$CONFIG['tbl_comments']."
                          WHERE comment_id = '$key'";
                $row = $db->GetRow($query);

                if ($row['num'] > 0){
                        $key = $this->_generateKey();
                } else {
                        return $key;
                }
        }


}
