Index: trunk/expressoMail1_2/inc/class.imap_functions.inc.php
===================================================================
--- trunk/expressoMail1_2/inc/class.imap_functions.inc.php	(revision 708)
+++ trunk/expressoMail1_2/inc/class.imap_functions.inc.php	(revision 828)
@@ -45,4 +45,6 @@
 	function open_mbox($folder = False)
 	{
+		if (is_resource($this->mbox))
+			return $this->mbox;
 		$folder = mb_convert_encoding($folder, "UTF7-IMAP","ISO_8859-1");
 	 	$this->mbox = @imap_open("{".$this->imap_server.":".$this->imap_port.$this->imap_options."}".$folder, $this->username, $this->password) or die(serialize(array('imap_error' => $this->parse_error(imap_last_error()))));
@@ -77,50 +79,47 @@
 		$sort_box_reverse = $params['sort_box_reverse'];
 		$search_box_type = $params['search_box_type'] != "ALL" && $params['search_box_type'] != "" ? $params['search_box_type'] : false;
-		$sort_array_msg = $this-> get_msgs($folder, $sort_box_type, $search_box_type, $sort_box_reverse);				
+		$sort_array_msg = $this-> get_msgs($folder, $sort_box_type, $search_box_type, $sort_box_reverse,$msg_range_begin,$msg_range_end);
 		
 		$return = array();
 		$i = 0;
-		$num_msgs = (is_array($sort_array_msg) ? count($sort_array_msg) : 0);
-		if($num_msgs) { 
-			for ($msg_range_begin; (($msg_range_begin <= $msg_range_end) && ($msg_range_begin <= $num_msgs)); $msg_range_begin++)
-			{
-				$msg_number = $sort_array_msg[$msg_range_begin-1];
+		$num_msgs = imap_num_msg($this->mbox);
+		if(is_array($sort_array_msg)){
+			foreach($sort_array_msg as $msg_number => $value) 
+			{
 				$temp = $this->get_info_head_msg($msg_number);
 				if(!$temp)
 					return false;
-	
+
 				$return[$i] = $temp;
 				$i++;
 			}
 		}
-		$return['num_msgs'] = $num_msgs;		
-		
+		$return['num_msgs'] = $num_msgs;
+
 		return $return;
 	}
-	
+
 	function get_info_head_msg($msg_number) {
 		$head_array = array();
 		include_once("class.imap_attachment.inc.php");
 		$imap_attachment = new imap_attachment();
-		
-		/*A função imap_headerinfo não traz o cabeçalho completo, e sim alguns
-		* atributos do cabeçalho. Como eu preciso do atributo Importance 
-		* para saber se o email é importante ou não, uso abaixo a função
-		* imap_fetchheader e busco o atributo importance nela para passar
-		* para as funções ajax. Isso faz com que eu acesse o cabeçalho
-		* duas vezes e de duas formas diferentes, mas em contrapartida, eu
-		* não preciso reimplementar o método utilizando o fetchheader.
-		* Como as mensagens são renderizadas de X em X, não parece ter
-		* perda considerável de performance.
-		*/
+
+		/*Como eu preciso do atributo Importance para saber se o email é 
+		 * importante ou não, uso abaixo a função imap_fetchheader e busco
+		 * o atributo importance nela. Isso faz com que eu acesse o cabeçalho
+		 * duas vezes e de duas formas diferentes, mas em contrapartida, eu
+		 * não preciso reimplementar o método utilizando o fetchheader.
+		 * Como as mensagens são renderizadas em um número pequeno por vez,
+		 * não parece ter perda considerável de performance.
+		 */
 		$flag = preg_match('/importance *: *(.*)\r/i',
-					imap_fetchheader($this->mbox, imap_msgno($this->mbox, $msg_number))
-					,$importance);		
+			imap_fetchheader($this->mbox, imap_msgno($this->mbox, $msg_number)),
+			$importance);
 		$head_array['Importance'] = $flag==0?"Normal":$importance[1];
 
-		
+
 		$header = $this->get_header($msg_number);
-			if (!is_object($header))
-				return false;
+		if (!is_object($header))
+			return false;
 		$head_array['Recent'] = $header->Recent;
 		$head_array['Unseen'] = $header->Unseen;
@@ -130,20 +129,20 @@
 		else {
 			$head_array['Answered']	= $header->Answered;
-			$head_array['Draft']	= $header->Draft;	
+			$head_array['Draft']	= $header->Draft;
 		}
 		$head_array['Deleted'] = $header->Deleted;
 		$head_array['Flagged'] = $header->Flagged;
-		
+
 		$head_array['msg_number'] = $msg_number;
-		//$return[$i]['msg_folder'] = $folder;
-		
+		//$head_array['msg_folder'] = $folder;
+
 		$date_msg = gmdate("d/m/Y",$header->udate);
-		if (date("d/m/Y") == $date_msg)
+		if (gmdate("d/m/Y") == $date_msg)
 			$head_array['udate'] = gmdate("H:i",$header->udate);
 		else
 			$head_array['udate'] = $date_msg;
-		
+
 		$head_array['aux_date'] = $date_msg; //Auxiliar apenas para mensagens locais.
-		
+
 		$from = $header->from;
 		$head_array['from'] = array();
@@ -161,13 +160,13 @@
 			$head_array['to']['name'] = $head_array['to']['email'];
 		$head_array['subject'] = $this->decode_string($header->fetchsubject);
-		
+
 		$head_array['Size'] = $header->Size;
-		
+
 		$head_array['attachment'] = array();
 		$head_array['attachment'] = $imap_attachment->get_attachment_headerinfo($this->mbox, $msg_number);
-		
+
 		return $head_array;
 	}
-	
+
 	function decode_string($string)
 	{	
@@ -337,10 +336,6 @@
 			imap_close($this->mbox);
 			$this->mbox=false;
-
-
 			array_push($return,serialize($msg_info));
-
-		}
-
+		}
 		return $return;
 	}
@@ -361,21 +356,23 @@
 		}
 		
-		$all_header = explode("\n", imap_fetchheader($this->mbox, $msg_number, FT_UID));
+		$header_ = imap_fetchheader($this->mbox, $msg_number, FT_UID);
+
 		$return_get_body = $this->get_body_msg($msg_number, $msg_folder);
 		
 		//Substituição de links em email para abrir no próprio expresso
 		$body = ereg_replace("<a[^>]*href=[\'\"]mailto:([^\"\']+)[\'\"]>([^<]+)</a>","<a href=\"javascript:new_message_to('\\1')\">\\2</a>",$return_get_body['body']);
-		
+
 		$return['body'] 		= $body;
 		$return['attachments'] 	= $return_get_body['attachments'];
 		$return['thumbs'] 		= $return_get_body['thumbs'];
 		$return['signature']	= $return_get_body['signature'];
-		
-		foreach($all_header as $line) {
-			if (eregi("^Disposition-Notification-To", $line)) {
-				eregi("^([^:]*): (.*)", $line, &$arg);
-				$return['DispositionNotificationTo'] = $arg[2];
-			}
-		}
+
+		$pattern = '/^[ \t]*Disposition-Notification-To(^:)*:(.+)*@(.+)*$/isUm';
+		if (preg_match($pattern, $header_, $fields))
+		{
+			preg_match('/[[:alnum:]\._\-]+@[[:alnum:]_\-\.]+/',$fields[0], $matches);
+			$return['DispositionNotificationTo'] = "<".$matches[0].">";
+		}
+
 		$return['Recent']	= $header->Recent;
 		$return['Unseen']	= $header->Unseen;
@@ -598,11 +595,11 @@
 		$return['subject'] = $this->decode_string($header->fetchsubject);
 		$return['Size'] = $header->Size;
-		$return['reply_toaddress'] = $header->reply_toaddress;	
-	
+		$return['reply_toaddress'] = $header->reply_toaddress;
+
 		//All this is to help in local messages
 		$return['timestamp'] = $header->udate;
 		$return['login'] = $_SESSION['phpgw_info']['expressomail']['user']['account_id'];//$GLOBALS['phpgw_info']['user']['account_id'];
 		$return['reply_toaddress'] = $header->reply_toaddress;
-		
+
 		return $return;
 	}
@@ -858,7 +855,8 @@
 		// HTML Filter
 		//$body = preg_replace("#(^|[\n ])([a-z0-9&\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)*[\w]+)#i", "\\1<a href=# onclick=\"javascript:new_message('new_by_message', '\\2@\\3')\">\\2@\\3</a>", $body);
-    	$body = str_replace("\r\n", "\n", $body);
+    	//$body = str_replace("\r\n", "\n", $body);
 		if ($encoding == 'quoted-printable')
-	    {
+		{
+			/*
 			
 			for($i=0;$i<256;$i++) {
@@ -869,4 +867,5 @@
 				$myqprintb[]=chr($i);
 			}	    	
+			 */
 			$body = str_replace($myqprinta,$myqprintb,($body));
 			$body = quoted_printable_decode($body);
@@ -880,8 +879,8 @@
         	$body = base64_decode($body);
     	}
-    	/*else if ($encoding == '7bit') 
+    	else if ($encoding == '7bit') 
     	{
         	$body = quoted_printable_decode($body);        	        	        	
-    	}*/
+    	}
 		// All other encodings are returned raw.
 		if (strtolower($charset) == "utf-8")
@@ -1082,28 +1081,12 @@
 		$msgs_in_the_server = array();
 		$search_box_type = $params['search_box_type'] != "ALL" && $params['search_box_type'] != "" ? $params['search_box_type'] : false;
-		$sort_array_msg = $this -> get_msgs($folder, $sort_box_type, $search_box_type, $sort_box_reverse);
-
-		if(!count($sort_array_msg))
+		$msgs_in_the_server = $this->get_msgs($folder, $sort_box_type, $search_box_type, $sort_box_reverse,$msg_range_begin,$msg_range_end);
+		$msgs_in_the_server = array_keys($msgs_in_the_server);
+		if(!count($msgs_in_the_server))
 			return array();
 			
-		$num_msgs = (count($sort_array_msg) - imap_num_recent($this->mbox));
-		$msgs_in_the_client = explode(",", $msgs_existent);
-
-		
-		for ($msg_range_begin; (($msg_range_begin <= $msg_range_end) && ($msg_range_begin <= count($sort_array_msg))); $msg_range_begin++)
-		{
-			$msgs_in_the_server[] = $sort_array_msg[$msg_range_begin-1];
-		}
-		if ((count($msgs_in_the_server) < 1) && ($msg_range_begin != 0))
-		{
-			$range = $msg_range_end - $msg_range_begin;
-			$msg_range_begin = $msg_range_begin - $range;
-			$msg_range_end = $msg_range_end - $range;
-			for ($msg_range_begin; (($msg_range_begin <= $msg_range_end) && ($msg_range_begin <= count($sort_array_msg))); $msg_range_begin++)
-			{
-				$msgs_in_the_server[] = $sort_array_msg[$msg_range_begin-1];
-			}
-		}
-		
+		$num_msgs = (count($msgs_in_the_server) - imap_num_recent($this->mbox));
+		$msgs_in_the_client = explode(",", $msgs_existent);	
+
 		$msg_to_insert  = array_diff($msgs_in_the_server, $msgs_in_the_client);
 		$msg_to_delete = array_diff($msgs_in_the_client, $msgs_in_the_server);
@@ -1150,5 +1133,5 @@
 			*/
 			$flag = preg_match('/importance *: *(.*)\r/i',
-					imap_fetchheader($this->mbox, imap_msgno($this->mbox, $msg_number))
+					@imap_fetchheader($this->mbox, imap_msgno($this->mbox, $msg_number))
 					,$importance);		
 			$return[$i]['Importance'] = $flag==0?"Normal":$importance[1];
@@ -1156,6 +1139,6 @@
 			$header = $this->get_header($msg_number);
 			if (!is_object($header))
-				return false;
-			
+				continue;
+
 			$return[$i]['msg_number']	= $msg_number;
 			$return[$i]['command']		= $command;
@@ -1208,4 +1191,5 @@
 		if($this->mbox && is_resource($this->mbox))
 			imap_close($this->mbox);
+
 		return $return;
 	}
@@ -1392,8 +1376,8 @@
 				return "The server denied your request to send a mail, you cannot use this mail address.";
 		}
-		
+
 		//new_message_to backs to mailto: pattern
 		$params['body'] = eregi_replace("<a href=\"javascript:new_message_to\('([^>]+)'\)\">[^>]+</a>","<a href='mailto:\\1'>\\1</a>",$params['body']);
-		
+
 		$toaddress = implode(',',$db->getAddrs(explode(',',$params['input_to'])));
 		$ccaddress = implode(',',$db->getAddrs(explode(',',$params['input_cc'])));
@@ -1502,7 +1486,7 @@
 			if( $total_uploaded_size > $upload_max_filesize)
 				return $this->parse_error("message file too big");			
-		}			
+		}
 		else if(($params['is_local_forward']=="1") && (count($local_attachments))) { //Caso seja forward de mensagens locais
-			
+
 			$total_uploaded_size = 0;
 			$upload_max_filesize = str_replace("M","",ini_get('upload_max_filesize')) * 1024 * 1024;			
@@ -1517,5 +1501,5 @@
 			}
 			if( $total_uploaded_size > $upload_max_filesize)
-				return 'false';	
+				return 'false';
 		}
 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1628,5 +1612,5 @@
 	function get_forwarding_attachment($msg_folder, $msg_number, $msg_part, $encoding)
 	{
-		$mbox_stream = $this->open_mbox($msg_folder);			
+		$mbox_stream = $this->open_mbox(utf8_decode(urldecode($msg_folder)));
 		$fileContent = imap_fetchbody($mbox_stream, $msg_number, $msg_part, FT_UID);		
 		if($encoding == 'base64')
@@ -1654,13 +1638,37 @@
 	}
 	
-	function messages_sort($sort_box_type,$sort_box_reverse, $search_box_type)
+	function messages_sort($sort_box_type,$sort_box_reverse, $search_box_type,$offsetBegin,$offsetEnd)
 	{
 		$sort = array();
-		$sort_uid = array();
-		
+		if ($offsetBegin > $offsetEnd) {$temp=$offsetEnd; $offsetEnd=$offsetBegin; $offsetBegin=$temp;}
 		$num_msgs = imap_num_msg($this->mbox);
-		for ($i=1; $i<=$num_msgs; $i++)
-		{
-			$header = $this->get_header(imap_uid($this->mbox,$i));
+		if ($offsetEnd >  $num_msgs) {$offsetEnd = $num_msgs;}
+		if ($search_box_type == "" && $sort_box_type == "SORTARRIVAL")
+		{
+			// If I'm looking for any type of email doesn't need to see all imap box
+			if ($sort_box_reverse)
+			{
+				$numBegin = $num_msgs - $offsetEnd;
+				if ($numBegin < 0) $numBegin=0;
+				$numEnd = $num_msgs - ($offsetBegin-1);
+			}
+			else
+			{
+				$numBegin = ($offsetBegin-1);
+				$numEnd = $offsetEnd;
+			}
+			$slice_array = false;
+		}
+		else
+		{
+			// If I'm looking for a specific type of email I have to see entire imap box
+			$numBegin = 0;
+			$numEnd = $num_msgs;
+			$slice_array = true;
+		}
+		for ($i=$numBegin+1; $i<=$numEnd; $i++)
+		{
+			$iuid = @imap_uid($this->mbox,$i);
+			$header = $this->get_header($iuid);
 			// List UNSEEN messages.
 			if($search_box_type == "UNSEEN" &&  (!trim($header->Recent) && !trim($header->Unseen))){
@@ -1689,91 +1697,30 @@
 				
 				if ($tmp[0]->text != "")
-					$sort[$i] = $tmp[0]->text;
+					$sort[$iuid] = $tmp[0]->text;
 				else
-					$sort[$i] = $from[0]->mailbox . "@" . $from[0]->host;
+					$sort[$iuid] = $from[0]->mailbox . "@" . $from[0]->host;
 			}
 			else if($sort_box_type=='SORTSUBJECT') {
-				$sort[$i] = $header->subject;
+				$sort[$iuid] = $header->subject;
 			}
 			else if($sort_box_type=='SORTSIZE') {
-				$sort[$i] = $header->Size;
+				$sort[$iuid] = $header->Size;
 			}
 			else {
-				$sort[$i] = $header->udate;
-			}
-			
-		}
-		
+				$sort[$iuid] = $header->udate;
+			}
+
+		}
 		natcasesort($sort);
-		
-		foreach($sort as $index => $header_msg)
-		{	
-			$sort_uid[] = imap_uid($this->mbox, $index);
-		}
-		
+
 		if ($sort_box_reverse)
-			$sort_uid = array_reverse($sort_uid);
-		
-		return $sort_uid;
-
-	}
-	
-	/**
-	 * Deprecated
-	 * 
-	 * Replaced for the method messages_sort
-	 */
-	function imap_sortfrom($sort_box_reverse, $search_box_type)
-	{
-		$sortfrom = array();
-		$sortfrom_uid = array();
-		
-		$num_msgs = imap_num_msg($this->mbox);
-		for ($i=1; $i<=$num_msgs; $i++)
-		{
-			$header = $this->get_header(imap_uid($this->mbox,$i));
-			// List UNSEEN messages.
-			if($search_box_type == "UNSEEN" &&  (!trim($header->Recent) && !trim($header->Unseen))){
-				continue;
-			}
-			// List SEEN messages.
-			elseif($search_box_type == "SEEN" && (trim($header->Recent) || trim($header->Unseen))){
-				continue;
-			}
-			// List ANSWERED messages.			
-			elseif($search_box_type == "ANSWERED" && !trim($header->Answered)){
-				continue;				
-			}
-			// List FLAGGED messages.			
-			elseif($search_box_type == "FLAGGED" && !trim($header->Flagged)){
-				continue;
-			}
-						
-			if (($header->from[0]->mailbox . "@" . $header->from[0]->host) == $_SESSION['phpgw_info']['expressomail']['user']['email'])				
-				$from = $header->to;
-			else
-				$from = $header->from;
-			
-			$tmp = imap_mime_header_decode($from[0]->personal);			
-			
-			if ($tmp[0]->text != "")
-				$sortfrom[$i] = $tmp[0]->text;
-			else
-				$sortfrom[$i] = $from[0]->mailbox . "@" . $from[0]->host;
-		}
-		
-		natcasesort($sortfrom);
-		
-		foreach($sortfrom as $index => $header_msg)
-		{	
-			$sortfrom_uid[] = imap_uid($this->mbox, $index);
-		}
-		
-		if ($sort_box_reverse)
-			$sortfrom_uid = array_reverse($sortfrom_uid);
-		
-		return $sortfrom_uid;
-	}
-
+			$sort = array_reverse($sort,true);
+
+		if ($slice_array)
+			$sort = array_slice($sort,$offsetBegin-1,$offsetEnd-($offsetBegin-1),true);
+		return $sort;
+
+	}
+	
 	function move_search_messages($params){		
 		$params['selected_messages'] = urldecode($params['selected_messages']);	
@@ -1850,5 +1797,5 @@
 					$return['new_folder_name'] = $cn;
         }
-				
+		
 		// Caso estejamos no box principal, nao eh necessario pegar a informacao da mensagem anterior. 		
 		if (($params['get_previous_msg']) && ($params['border_ID'] != 'null') && ($params['border_ID'] != ''))
@@ -2057,9 +2004,9 @@
             $mail->ContentType = "multipart/alternative";
 
-        $mail->error_count = 0; // reset errors
-        $mail->SetMessageType();
-        $header = $mail->CreateHeader();
-        $body = $mail->CreateBody();
-        
+		$mail->error_count = 0; // reset errors
+		$mail->SetMessageType();
+		$header = $mail->CreateHeader();
+		$body = $mail->CreateBody(); 
+
        	if ($_SESSION['phpgw_info']['expressomail']['email_server']['imapTLSEncryption'] == 'yes')
 		{
@@ -2083,10 +2030,10 @@
 		$return['msg_no'] = $status->uidnext - 1;
 		$return['folder_id'] = $folder;
-		
+
 		if($mbox_stream)
 			imap_close($mbox_stream);
 		if (is_array($return_files))		  
-		foreach ($return_files as $index => $_attachment) {
-			if (array_key_exists("name",$_attachment)){
+			foreach ($return_files as $index => $_attachment) {
+				if (array_key_exists("name",$_attachment)){
 				unset($return_files[$index]);
 				$return_files[$index] = $_attachment['name']."_SIZE_".$return_files[$index][1] = $_attachment['size'];
@@ -2250,23 +2197,11 @@
 	}
 	
-	function get_msgs($folder, $sort_box_type, $search_box_type, $sort_box_reverse){
-		
-		if(!$this->mbox || !is_resource($this->mbox)){
+	function get_msgs($folder, $sort_box_type, $search_box_type, $sort_box_reverse,$offsetBegin = 0,$offsetEnd = 0)
+	{
+		if(!$this->mbox || !is_resource($this->mbox))
 			$this->mbox = $this->open_mbox($folder);
-		
-		}
-
-		return $this->messages_sort($sort_box_type,$sort_box_reverse, $search_box_type);
-		/*switch($sort_box_type){
-			case 'SORTFROM':
-				return $this->imap_sortfrom($sort_box_reverse, $search_box_type);				
-			case 'SORTSUBJECT':
-				return imap_sort($this->mbox, SORTSUBJECT, $sort_box_reverse, SE_UID, $search_box_type);				
-			case 'SORTSIZE':
-				return imap_sort($this->mbox, SORTSIZE, $sort_box_reverse, SE_UID, $search_box_type);				
-			default:
-				return imap_sort($this->mbox, SORTARRIVAL, $sort_box_reverse, SE_UID, $search_box_type);						
-		}*/
-	}	
+
+		return $this->messages_sort($sort_box_type,$sort_box_reverse, $search_box_type,$offsetBegin,$offsetEnd);
+	}
 	
 	function get_info_next_msg($params)
@@ -2644,6 +2579,18 @@
 	function get_msg($uid_msg,$name_box, $mbox_stream )
 	{
-		$header = $this->get_header($uid_msg);         
-		$flag = $header->Unseen.$header->Recent.$header->Flagged.$header->Draft;
+		$header = $this->get_header($uid_msg);
+		include_once("class.imap_attachment.inc.php");
+		$imap_attachment = new imap_attachment();
+		$attachments =  $imap_attachment->get_attachment_headerinfo($mbox_stream, $uid_msg);
+		$attachments = $attachments['number_attachments'] > 0?"T".$attachments['number_attachments']:"";
+		$flag = $header->Unseen
+			.$header->Recent
+			.$header->Flagged
+			.$header->Draft
+			.$header->Answered
+			.$header->Deleted
+			.$attachments;
+
+
 		$subject = $this->decode_string($header->fetchsubject);
 		$from = $header->from[0]->mailbox;
@@ -2653,5 +2600,5 @@
 		return $ret_msg;                    
 	}	
-	
+
 	function size_msg($size){
 		$var = floor($size/1024);
