Changeset 4898 for contrib/z-push


Ignore:
Timestamp:
08/03/11 12:00:08 (13 years ago)
Author:
thiagoaos
Message:

Ticket #2180 - Adicionado código fonte completo do zpush

Location:
contrib/z-push
Files:
19 added
3 edited

Legend:

Unmodified
Added
Removed
  • contrib/z-push/backend/BackendCalendarExpresso.php

    r4219 r4898  
    77 * Created   :   06.12.2010 - emerson-faria.nobre@serpro.gov.br 
    88 * 
    9  * ï¿œ Zarafa Deutschland GmbH, www.zarafaserver.de 
     9 * ᅵ Zarafa Deutschland GmbH, www.zarafaserver.de 
    1010 * This file is distributed under GPL v2. 
    1111 * Consult LICENSE file for details 
     
    6565                        if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
    6666                        while ($row = pg_fetch_row($result)) { 
    67                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageList-> Lê item do BD (cal_id: '.$row[0].', title: '.$row[4].', last_update: '.date("d/m/Y G:i:s",substr($row[1], 0, strlen($row[1])-3)).', last_update_timestamp: '.$row[1].', datetime: '.date("d/m/Y G:i:s",$row[2]).', datetime_timestamp: '.$row[2].', cal_type: '.$row[3].')'); 
     67                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageList-> Lê item do BD (cal_id: '.$row[0].', title: '.$row[4].', last_update: '.date("d/m/Y G:i:s",substr($row[1], 0, strlen($row[1])-3)).', last_update_timestamp: '.$row[1].', datetime: '.date("d/m/Y G:i:s",$row[2]).', datetime_timestamp: '.$row[2].', cal_type: '.$row[3].')'); 
    6868                                $result_recur = pg_query($this->db,"select recur_enddate from phpgw_cal_repeats where cal_id = " . $row[0] . ";"); 
    6969                                if ($result_recur == FALSE) throw new Exception(pg_last_error($this->db)); 
    7070                                if ($row[3] == 'M') { 
    7171                                        if ($recur_enddate = pg_fetch_result($result_recur, 0, 0)) { 
    72                                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageList-> Evento '.$row[0].' é recorrente: recur_enddate : '.date("d/m/Y G:i:s",$recur_enddate).', recur_enddate_timestamp: '.$recur_enddate); 
     72                                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageList-> Evento '.$row[0].' é recorrente: recur_enddate : '.date("d/m/Y G:i:s",$recur_enddate).', recur_enddate_timestamp: '.$recur_enddate); 
    7373                                                if ($recur_enddate < $row[2]) { 
    74                                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageList-> ERRO: Esse evento não será adicionado na lista porque o campo phpgw_cal_repeats.recur_enddate é menor que o campo phpgw_cal.datetime. Corrija o valor de um dos campos'); 
     74                                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageList-> ERRO: Esse evento não será adicionado na lista porque o campo phpgw_cal_repeats.recur_enddate é menor que o campo phpgw_cal.datetime. Corrija o valor de um dos campos'); 
    7575                                                        continue; // Nao sincroniza este evento, porque a data final da recorrencia eh menor que a data inicial do evento. Eh o BD do Expresso que esta inconsistente. 
    7676                                                } 
     
    9191                        if ($result_invalid_ref == FALSE) throw new Exception(pg_last_error($this->db)); 
    9292                        while ($row_invalid_ref = pg_fetch_row($result_invalid_ref)) { 
    93                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageList-> ERRO: Evento com campo reference inválido (cal_id: '.$row_invalid_ref[0].', title: '.$row_invalid_ref[4].', reference: '.$row_invalid_ref[5].', last_update: '.date("d/m/Y G:i:s",substr($row_invalid_ref[1], 0, strlen($row[1])-3)).', last_update_timestamp: '.$row_invalid_ref[1].', datetime: '.date("d/m/Y G:i:s",$row_invalid_ref[2]).', datetime_timestamp: '.$row_invalid_ref[2].', cal_type: '.$row_invalid_ref[3].')'); 
     93                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageList-> ERRO: Evento com campo reference inválido (cal_id: '.$row_invalid_ref[0].', title: '.$row_invalid_ref[4].', reference: '.$row_invalid_ref[5].', last_update: '.date("d/m/Y G:i:s",substr($row_invalid_ref[1], 0, strlen($row[1])-3)).', last_update_timestamp: '.$row_invalid_ref[1].', datetime: '.date("d/m/Y G:i:s",$row_invalid_ref[2]).', datetime_timestamp: '.$row_invalid_ref[2].', cal_type: '.$row_invalid_ref[3].')'); 
    9494                        } 
    9595                        // Evento fora da faixa filtrada 
     
    107107                        debugLog("exception -> " . $e->getMessage() . " - ARQUIVO: " . $e->getFile() . " - LINHA: " . $e->getLine()); 
    108108                } 
    109                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageList-> Fim normal da função'); 
     109                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageList-> Fim normal da função'); 
    110110                return $messages; 
    111111        } 
     
    147147                if($folderid != "calendar") return false; 
    148148                try { 
    149                  $result = pg_query($this->db,"BEGIN;"); 
    150                  if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
    151                  $result_calendar = pg_query($this->db, "select last_update from phpgw_cal where cal_id = " . $id . ";"); 
    152                  if ($result_calendar == FALSE) throw new Exception(pg_last_error($this->db)); 
    153                  while ($row_calendar = pg_fetch_row($result_calendar)) { 
    154                         if(isset($row_calendar[0])) { 
    155                                 $message = array(); 
    156                                 $message["mod"] = substr($row_calendar[0], 0, strlen($row_calendar[0])-3); 
    157                                 $message["id"] = $id; 
    158                                 $message["flags"] = 1; 
    159                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::StatMessage-> mod: '.$message["mod"].', id: '.$message["id"]); 
    160                                 return $message; 
    161                         } 
    162                  } 
    163                  $result = pg_query($this->db,"COMMIT;"); 
    164                  if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
     149                        $result = pg_query($this->db,"BEGIN;"); 
     150                        if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
     151                        $result_calendar = pg_query($this->db, "select last_update from phpgw_cal where cal_id = " . $id . ";"); 
     152                        if ($result_calendar == FALSE) throw new Exception(pg_last_error($this->db)); 
     153                while ($row_calendar = pg_fetch_row($result_calendar)) { 
     154                        if(isset($row_calendar[0])) { 
     155                                $message = array(); 
     156                                $message["mod"] = substr($row_calendar[0], 0, strlen($row_calendar[0])-3); 
     157                                $message["id"] = $id; 
     158                                $message["flags"] = 1; 
     159                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::StatMessage-> mod: '.$message["mod"].', id: '.$message["id"]); 
     160                                return $message; 
     161                        } 
     162                } 
     163                $result = pg_query($this->db,"COMMIT;"); 
     164                if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
    165165                } catch (Exception $e) { 
    166166                        pg_query($this->db,"ROLLBACK;"); 
    167167                        debugLog("exception -> " . $e->getMessage() . " - ARQUIVO: " . $e->getFile() . " - LINHA: " . $e->getLine()); 
    168168                } 
    169                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::StatMessage: ERRO: Não encontrou valor para o campo last_update para esse evento.'); 
     169                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::StatMessage: ERRO: Não encontrou valor para o campo last_update para esse evento.'); 
    170170                return false; 
    171171        } 
     
    186186                        if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
    187187                        if ($row = pg_fetch_row($result)) { 
    188                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageDAO-> Lê evento do DB para enviar para o celular (cal_id: '.$row[0].', title:'.$row[1].', location: '.$row[2].', mdatetime: '.$row[3].', datetime: '.$row[4].', edatetime: '.$row[5].', reference: '.$row[7].', isPublic: '.$row[8].')'); 
     188                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageDAO-> Lê evento do DB para enviar para o celular (cal_id: '.$row[0].', title:'.$row[1].', location: '.$row[2].', mdatetime: '.$row[3].', datetime: '.$row[4].', edatetime: '.$row[5].', reference: '.$row[7].', isPublic: '.$row[8].')'); 
    189189                                if ($row[7] != 0) $has_parent_event = true; 
    190190                                else $has_parent_event = false; 
     
    236236                                        } 
    237237                                } 
    238                                 $message->alldayevent = 0; // (0 - Não(default), 1- Sim) 
     238                                $message->alldayevent = 0; // (0 - Não(default), 1- Sim) 
    239239                                $message->busystatus = 2; // 2 - Ocupado 
    240240                                //TODO: Tratar $message - timezone 
    241                                 //$tz = $this->_getGMTTZ(); 
     241                                // $tz = $this->_getGMTTZ(); 
    242242                                $tz = array("bias" => 180, "stdbias" => 0, "dstbias" => -60, "dstendyear" => 0, "dstendmonth" => 2, "dstendday" => 0, "dstendweek" => 2, "dstendhour" => 2, "dstendminute" => 0, "dstendsecond" => 0, "dstendmillis" => 0, 
    243                                                       "dststartyear" => 0, "dststartmonth" =>10, "dststartday" =>0, "dststartweek" => 3, "dststarthour" => 2, "dststartminute" => 0, "dststartsecond" => 0, "dststartmillis" => 0); 
     243                                                                                      "dststartyear" => 0, "dststartmonth" =>10, "dststartday" =>0, "dststartweek" => 3, "dststarthour" => 2, "dststartminute" => 0, "dststartsecond" => 0, "dststartmillis" => 0); 
    244244                                $message->timezone = base64_encode($this->_getSyncBlobFromTZ($tz)); 
    245245                                //TODO: Se necessario, tratar $message - meetingstatus 
     
    265265                                if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
    266266                                if ($row = pg_fetch_row($result)){ 
    267                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageDAO-> Lê recorrência do evento (recur_type: '.$row[0].', recur_use_end: '.$row[1].', recur_enddate: '.$row[2].', recur_interval: '.$row[3].', recur_data: '.$row[4].', recur_exception: '.$row[5].')'); 
     267                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageDAO-> Lê recorrência do evento (recur_type: '.$row[0].', recur_use_end: '.$row[1].', recur_enddate: '.$row[2].', recur_interval: '.$row[3].', recur_data: '.$row[4].', recur_exception: '.$row[5].')'); 
    268268                                        $recur = new SyncRecurrence(); 
    269269                                        // Converte os tipos do Expresso para os tipos do Protocolo ActiveSync 
     
    311311                                        } 
    312312                                        $message->recurrence = $recur; 
    313                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageDAO-> Fim do Bloco - Lê recorrência do evento.'); 
     313                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageDAO-> Fim do Bloco - Lê recorrência do evento.'); 
    314314                                } 
    315315 
     
    318318                                if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
    319319                                while ($row_recur_exception = pg_fetch_row($result)) { 
    320                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageDAO: Lê evento único da recorrência com id: '.$row_recur_exception[0]); 
     320                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageDAO: Lê evento único da recorrência com id: '.$row_recur_exception[0]); 
    321321                                        $recur_exception = $this->GetMessageDAO($row_recur_exception[0]); 
    322322                                        if ($recur_exception instanceof SyncAppointment) { 
     
    324324                                                array_push($message->exceptions, $recur_exception); 
    325325                                        } 
    326                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageDAO-> Fim do Bloco - Lê evento único da recorrência com id: '.$row_recur_exception[0]); 
     326                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageDAO-> Fim do Bloco - Lê evento único da recorrência com id: '.$row_recur_exception[0]); 
    327327                                } 
    328328 
     
    331331                                        $array_timestamps_recur_deleted = explode(",",$row[5]); 
    332332                                        foreach ($array_timestamps_recur_deleted as $timestamp_recur_deleted) { 
    333                                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageDAO: Timestamps dos eventos únicos da recorrência do tipo deletados: '.$timestamp_recur_deleted); 
     333                                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageDAO: Timestamps dos eventos únicos da recorrência do tipo deletados: '.$timestamp_recur_deleted); 
    334334                                                $recur_deleted = new SyncAppointment(); 
    335335                                                $recur_deleted->deleted = '1'; 
     
    340340                                } 
    341341                                //TODO: Tratar Participantes do Evento 
    342  
    343342                        } 
    344343                        $result = pg_query($this->db,"COMMIT;"); 
     
    349348                        return; 
    350349                } 
    351                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageDAO-> Fim do Bloco - Lê evento do DB para enviar para o celular: '.$id); 
     350                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::GetMessageDAO-> Fim do Bloco - Lê evento do DB para enviar para o celular: '.$id); 
    352351                return $message; 
    353352        } 
     
    389388                        return false; 
    390389                } 
    391                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog("CalendarExpresso::DeleteMessage-> Fim normal da Função."); 
     390                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog("CalendarExpresso::DeleteMessage-> Fim normal da Função."); 
    392391                return true; 
    393392        } 
     
    399398        function ChangeMessageDAO($id, $message) { 
    400399                debugLog('CalendarExpresso::ChangeMessageDAO('.$id.', ..)'); 
    401                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> O evento do celular será inserido/atualizado no BD com o ID: '.$id); 
     400                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> O evento do celular será inserido/atualizado no BD com o ID: '.$id); 
    402401                try { 
    403402                        $result = pg_query($this->db,"BEGIN;"); 
     
    543542                        //TODO: Implementar para os tipos 3 e 6. O Expresso ainda nao suporta esses tipos :-( 
    544543                        if (isset($message->recurrence) and ($message->recurrence->type == 0 or $message->recurrence->type == 1 or $message->recurrence->type == 2 or $message->recurrence->type == 5)) { 
    545                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> O Evento é Recorrente.'); 
     544                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> O Evento é Recorrente.'); 
    546545                                switch ($message->recurrence->type) { 
    547546                                        case 0: //repeticao diaria 
     
    562561                                                break; 
    563562                                } 
    564                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Recorrência-> recur_type: '.$arrayRecur["recur_type"]); 
     563                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Recorrência-> recur_type: '.$arrayRecur["recur_type"]); 
    565564                                if (isset($message->recurrence->interval)) { 
    566565                                        $arrayRecur["recur_interval"] = $message->recurrence->interval; 
    567                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Recorrência-> recur_interval: '.$arrayRecur["recur_interval"]); 
     566                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Recorrência-> recur_interval: '.$arrayRecur["recur_interval"]); 
    568567                                } 
    569568                                if ($message->recurrence->type == 1 or $message->recurrence->type == 3 or $message->recurrence->type == 6) { 
    570569                                        if (isset($message->recurrence->dayofweek)) { 
    571570                                                $arrayRecur["recur_data"] = $message->recurrence->dayofweek; 
    572                                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Recorrência-> recur_data: '.$arrayRecur["recur_data"]); 
     571                                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Recorrência-> recur_data: '.$arrayRecur["recur_data"]); 
    573572                                                /*$day = $message->recurrence->dayofweek; 
    574573                                                 $day_of_week_counter = 0; 
     
    615614                                        $arrayRecur["recur_enddate"] = 1893283200; // Se nao tem data de termino seta para 30/12/2029 
    616615                                } 
    617                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Recorrência-> recur_enddate: '.$arrayRecur["recur_enddate"]); 
     616                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Recorrência-> recur_enddate: '.$arrayRecur["recur_enddate"]); 
    618617 
    619618                                // Trata excecoes da recorrencia 
     
    621620                                        // Tem Excecoes de recorrencia do tipo Edicao 
    622621                                        // Verifica se ja existe o registro do evento de excecao de recorrencia na tabela phpgw_cal 
    623                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Evento tem exceção de recorrência'); 
     622                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Evento tem exceção de recorrência'); 
    624623                                        $recur_exception_changed_ids = ""; 
    625624                                        $recur_exception_deleted_starttimes = ""; 
     
    643642                                                                        $except_description_from_DB = $row[2]; 
    644643                                                                        $found_except_cal_id = true; 
    645                                                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Achou o evento na tabela phpgw_cal, vai ATUALIZAR a exceção da recorrência nessa tabela'); 
     644                                                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Achou o evento na tabela phpgw_cal, vai ATUALIZAR a exceção da recorrência nessa tabela'); 
    646645                                                                } 
    647646                                                        } 
     
    653652                                                                        if(isset($row[0])) { 
    654653                                                                                $found_except_cal_user = true; 
    655                                                                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Achou o evento na tabela phpgw_cal_user, vai ATUALIZAR a exceção da recorrência nessa tabela'); 
     654                                                                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Achou o evento na tabela phpgw_cal_user, vai ATUALIZAR a exceção da recorrência nessa tabela'); 
    656655                                                                        } 
    657656                                                                } 
     
    661660                                                        if(isset($message->uid)) { 
    662661                                                                $arrayExceptCal["uid"] = $this->truncateString(utf8_decode($message->uid),255); 
    663                                                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Exceção De Recorrência-> uid: '.$arrayExceptCal["uid"]); 
     662                                                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Exceção De Recorrência-> uid: '.$arrayExceptCal["uid"]); 
    664663                                                        } 
    665664                                                        if(isset($recur_exception->subject)) { 
     
    668667                                                                $arrayExceptCal["title"] = $this->truncateString(utf8_decode($message->subject),299); 
    669668                                                        } 
    670                                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Exceção De Recorrência-> title: '.$arrayExceptCal["title"]); 
     669                                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Exceção De Recorrência-> title: '.$arrayExceptCal["title"]); 
    671670                                                        if(isset($recur_exception->location)) { 
    672671                                                                $arrayExceptCal["location"] = $this->truncateString(utf8_decode($recur_exception->location),255); 
     
    674673                                                                $arrayExceptCal["location"] = $this->truncateString(utf8_decode($message->location),255); 
    675674                                                        } 
    676                                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Exceção De Recorrência-> location: '.$arrayExceptCal["location"]); 
     675                                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Exceção De Recorrência-> location: '.$arrayExceptCal["location"]); 
    677676                                                        if(isset($recur_exception->dtstamp)) { 
    678677                                                                $arrayExceptCal["mdatetime"] = $recur_exception->dtstamp; 
     
    680679                                                                $arrayExceptCal["mdatetime"] = $message->dtstamp; 
    681680                                                        } 
    682                                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Exceção De Recorrência-> mdatetime: '.$arrayExceptCal["mdatetime"]); 
     681                                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Exceção De Recorrência-> mdatetime: '.$arrayExceptCal["mdatetime"]); 
    683682                                                        if(isset($recur_exception->starttime)) { 
    684683                                                                $arrayExceptCal["datetime"] = $recur_exception->starttime; 
     
    686685                                                                $arrayExceptCal["datetime"] = $message->starttime; 
    687686                                                        } 
    688                                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Exceção De Recorrência-> datetime: '.$arrayExceptCal["datetime"]); 
     687                                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Exceção De Recorrência-> datetime: '.$arrayExceptCal["datetime"]); 
    689688                                                        if(isset($recur_exception->endtime)) { 
    690689                                                                $arrayExceptCal["edatetime"] = $recur_exception->endtime; 
     
    692691                                                                $arrayExceptCal["edatetime"] = $message->endtime; 
    693692                                                        } 
    694                                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Exceção De Recorrência-> edatetime: '.$arrayExceptCal["edatetime"]); 
     693                                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Exceção De Recorrência-> edatetime: '.$arrayExceptCal["edatetime"]); 
    695694                                                        if(isset($recur_exception->sensitivity) and $recur_exception->sensitivity == 0) { 
    696695                                                                $arrayExceptCal["is_public"] = 1; // 1 - Normal 
     
    700699                                                                $arrayExceptCal["is_public"] = 1; // 1 - Normal 
    701700                                                        }else $arrayExceptCal["is_public"] = 0; // 0 - Privado 
    702                                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Exceção De Recorrência-> is_public: '.$arrayExceptCal["is_public"]); 
     701                                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Exceção De Recorrência-> is_public: '.$arrayExceptCal["is_public"]); 
    703702                                                        if (isset($recur_exception->body)) { 
    704703                                                                $arrayExceptCal["description"] = utf8_decode($recur_exception->body); 
     
    738737                                                                } 
    739738                                                        } 
    740                                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Exceção De Recorrência-> category: '.$arrayExceptCal["category"]); 
     739                                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Exceção De Recorrência-> category: '.$arrayExceptCal["category"]); 
    741740                                                        //TODO: Converter eventos que sao alldayevent para iniciar as 0:00hs e terminar as 23:59hs. Isso porque o Expresso nao suporta alldayevents 
    742741                                                        //               if(isset($message->alldayevent)) { 
     
    752751                                                                $result = pg_insert($this->db, 'phpgw_cal', $arrayExceptCal); 
    753752                                                                if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
    754                                                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Evento de Exceção da Recorrência INSERIDO na tabela phpgw_cal com cal_id: '.$arrayExceptCal["cal_id"]); 
     753                                                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Evento de Exceção da Recorrência INSERIDO na tabela phpgw_cal com cal_id: '.$arrayExceptCal["cal_id"]); 
    755754                                                        } else { 
    756755                                                                $result = pg_update($this->db, 'phpgw_cal', $arrayExceptCal, array('cal_id' => $except_cal_id)); 
    757756                                                                if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
    758                                                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Evento de Exceção da Recorrência ATUALIZADO na tabela phpgw_cal'); 
     757                                                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Evento de Exceção da Recorrência ATUALIZADO na tabela phpgw_cal'); 
    759758                                                        } 
    760759 
     
    768767                                                                $result = pg_insert($this->db, 'phpgw_cal_user', $arrayExceptCalUser); 
    769768                                                                if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
    770                                                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Evento de Exceção da Recorrência INSERIDO na tabela phpgw_cal_user com cal_id: '.$arrayExceptCalUser["cal_id"]); 
     769                                                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Evento de Exceção da Recorrência INSERIDO na tabela phpgw_cal_user com cal_id: '.$arrayExceptCalUser["cal_id"]); 
    771770                                                        } else { 
    772771                                                                $result = pg_update($this->db, 'phpgw_cal_user', $arrayExceptCalUser, array('cal_id' => $except_cal_id, 'cal_login' => $this->_uidnumber)); 
    773772                                                                if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
    774                                                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Evento de Exceção da Recorrência ATUALIZADO na tabela phpgw_cal_user'); 
     773                                                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Evento de Exceção da Recorrência ATUALIZADO na tabela phpgw_cal_user'); 
    775774                                                        } 
    776775                                                        if ($recur_exception_changed_ids == "") { 
     
    790789                                                //Tem Excecoes de recorrencia do tipo Exclusao 
    791790                                                $arrayRecur["recur_exception"] = $recur_exception_deleted_starttimes; 
    792                                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Evento tem exceção de recorrência do tipo exclusão com os seguintes starttimes: '.$recur_exception_deleted_starttimes); 
     791                                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Evento tem exceção de recorrência do tipo exclusão com os seguintes starttimes: '.$recur_exception_deleted_starttimes); 
    793792                                        } else { 
    794793                                                $arrayRecur["recur_exception"] = ""; 
    795                                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Não tem exceção de recorrência do tipo exclusão para esse evento'); 
     794                                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Não tem exceção de recorrência do tipo exclusão para esse evento'); 
    796795                                        } 
    797796                                        if ($recur_exception_changed_ids == "") { 
     
    801800                                                $result = pg_query($this->db, "delete from phpgw_cal where reference = " . $cal_id . ";"); 
    802801                                                if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
    803                                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Não tem exceção de recorrência, então deleta possíveis eventos de exceção de recorrência criados anteriormente para esse evento.'); 
     802                                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Não tem exceção de recorrência, então deleta possíveis eventos de exceção de recorrência criados anteriormente para esse evento.'); 
    804803                                        } else { 
    805804                                                //Deleta as excecoes da recorrencia, exceto as inseridas/atualizadas acima 
     
    808807                                                $result = pg_query($this->db, "delete from phpgw_cal where reference = " . $cal_id . " and cal_id not in (" . $recur_exception_changed_ids . ");"); 
    809808                                                if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
    810                                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Deleta as exçeções da recorrência, exceto as inseridas/atualizadas pelo celular com os seguintes cal_id:'.$recur_exception_changed_ids); 
     809                                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Deleta as exçeções da recorrência, exceto as inseridas/atualizadas pelo celular com os seguintes cal_id:'.$recur_exception_changed_ids); 
    811810                                        } 
    812811                                } else { 
     
    817816                                        $result = pg_query($this->db, "delete from phpgw_cal where reference = " . $cal_id . ";"); 
    818817                                        if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
    819                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Não tem exceção de recorrência, então deleta possíveis eventos de exceção de recorrência criados anteriormente para esse evento..'); 
     818                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Não tem exceção de recorrência, então deleta possíveis eventos de exceção de recorrência criados anteriormente para esse evento..'); 
    820819                                } 
    821820                                if (!$found_cal_repeats){ 
     
    823822                                        $result = pg_insert($this->db, 'phpgw_cal_repeats', $arrayRecur); 
    824823                                        if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
    825                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Recorrência INSERIDA na tabela phpgw_cal_repeats com cal_id: '.$arrayRecur["cal_id"]); 
     824                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Recorrência INSERIDA na tabela phpgw_cal_repeats com cal_id: '.$arrayRecur["cal_id"]); 
    826825                                } else { 
    827826                                        $result = pg_update($this->db, 'phpgw_cal_repeats', $arrayRecur, array('cal_id' => $cal_id)); 
    828827                                        if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
    829                                         if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Recorrência ATUALIZADA na tabela phpgw_cal_repeats'); 
     828                                        if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Recorrência ATUALIZADA na tabela phpgw_cal_repeats'); 
    830829                                } 
    831830                        } elseif ($found_cal_id) { 
     
    837836                                $result = pg_query($this->db, "delete from phpgw_cal_repeats where cal_id = " . $cal_id . ";"); 
    838837                                if ($result == FALSE) throw new Exception(pg_last_error($this->db)); 
    839                                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Não tem recorrência, então deleta possíveis eventos de recorrência criados anteriormente para esse evento'); 
     838                                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Não tem recorrência, então deleta possíveis eventos de recorrência criados anteriormente para esse evento'); 
    840839                        } 
    841840                        $result = pg_query($this->db,"COMMIT;"); 
     
    847846                        return false; 
    848847                } 
    849                 if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Fim normal da Função'); 
     848                if (TRACE_UID !== false and (TRACE_TYPE == 'CALENDAR' or TRACE_TYPE == 'ALL')) traceLog('CalendarExpresso::ChangeMessageDAO-> Fim normal da Função'); 
    850849                return $id; 
    851850        } 
     
    917916 
    918917        function  removeAccents($data){ 
    919                 $data = strtr($data,"ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÜÚÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùüúþÿ","aaaaaaaceeeeiiii noooooxouuutbaaaaaaaceeeeiiii nooooo/ouuuty"); 
     918                $data = strtr($data,"ÀÁÂÃÄà
     919ÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÜÚÞßàáâãÀåÊçÚéêëìíîïðñòóÎõö÷ÞùÌúßÿ","aaaaaaaceeeeiiii noooooxouuutbaaaaaaaceeeeiiii nooooo/ouuuty"); 
    920920                return $data; 
    921921        } 
     
    944944        function _getGMTTZ() { 
    945945                //$tz = array("bias" => 0, "stdbias" => 0, "dstbias" => 0, "dstendyear" => 0, "dstendmonth" => 2, "dstendday" => 0, "dstendweek" => 2, "dstendhour" => 2, "dstendminute" => 0, "dstendsecond" => 0, "dstendmillis" => 0, 
    946                 //                              "dststartyear" => 0, "dststartmonth" =>10, "dststartday" =>0, "dststartweek" => 3, "dststarthour" => 2, "dststartminute" => 0, "dststartsecond" => 0, "dststartmillis" => 0); 
    947                 $tz = array("bias" => 120, "stdbias" => 0, "dstbias" => -60, "dstendyear" => 0, "dstendmonth" => 2, "dstendday" => 0, "dstendweek" => 2, "dstendhour" => 2, "dstendminute" => 0, "dstendsecond" => 0, "dstendmillis" => 0, 
    948                                                       "dststartyear" => 0, "dststartmonth" =>10, "dststartday" =>0, "dststartweek" => 3, "dststarthour" => 2, "dststartminute" => 0, "dststartsecond" => 0, "dststartmillis" => 0); 
     946                //"dststartyear" => 0, "dststartmonth" =>10, "dststartday" =>0, "dststartweek" => 3, "dststarthour" => 2, "dststartminute" => 0, "dststartsecond" => 0, "dststartmillis" => 0); 
     947                $tz = array("bias" => 120, "stdbias" => 0, "dstbias" => -60, "dstendyear" => 0, "dstendmonth" => 2, "dstendday" => 0, "dstendweek" => 2, "dstendhour" => 2, "dstendminute" => 0, "dstendsecond" => 0, "dstendmillis" => 0, "dststartyear" => 0, "dststartmonth" =>10, "dststartday" =>0, "dststartweek" => 3, "dststarthour" => 2, "dststartminute" => 0, "dststartsecond" => 0, "dststartmillis" => 0); 
     948                 
    949949                return $tz; 
    950950        } 
  • contrib/z-push/backend/imap.php

    r4619 r4898  
    99 * Created   :   10.10.2007 
    1010 * 
    11  * ï¿œ Zarafa Deutschland GmbH, www.zarafaserver.de 
     11 * Zarafa Deutschland GmbH, www.zarafaserver.de 
    1212 * This file is distributed under GPL v2. 
    1313 * Consult LICENSE file for details 
     
    9191         * the new message as any other new message in a folder. 
    9292         */ 
    93     function SendMail($rfc822, $forward = false, $reply = false, $parent = false) { 
    94         debugLog("IMAP-SendMail: for: $forward   reply: $reply   parent: $parent  RFC822:  \n". $rfc822 ); 
    95  
    96         $mobj = new Mail_mimeDecode($rfc822); 
    97         $message = $mobj->decode(array('decode_headers' => false, 'decode_bodies' => true, 'include_bodies' => true, 'charset' => 'utf-8')); 
    98          
    99         $Mail_RFC822 = new Mail_RFC822(); 
    100         $toaddr = $ccaddr = $bccaddr = ""; 
    101         if(isset($message->headers["to"])) 
    102             $toaddr = $this->parseAddr($Mail_RFC822->parseAddressList($message->headers["to"])); 
    103         if(isset($message->headers["cc"])) 
    104             $ccaddr = $this->parseAddr($Mail_RFC822->parseAddressList($message->headers["cc"])); 
    105         if(isset($message->headers["bcc"])) 
    106             $bccaddr = $this->parseAddr($Mail_RFC822->parseAddressList($message->headers["bcc"])); 
    107  
    108         // save some headers when forwarding mails (content type & transfer-encoding) 
    109         $headers = ""; 
    110         $forward_h_ct = ""; 
    111         $forward_h_cte = ""; 
    112         $envelopefrom = ""; 
    113  
    114         $use_orgbody = false; 
    115          
    116         // clean up the transmitted headers 
    117         // remove default headers because we are using imap_mail 
    118         $changedfrom = false; 
    119         $returnPathSet = false; 
    120         $body_base64 = false; 
    121         $org_charset = ""; 
    122         $org_boundary = false; 
    123         $multipartmixed = false; 
    124         foreach($message->headers as $k => $v) { 
    125             if ($k == "subject" || $k == "to" || $k == "cc" || $k == "bcc") 
    126                 continue; 
    127  
    128             if ($k == "content-type") { 
    129                 // if the message is a multipart message, then we should use the sent body 
    130                 if (preg_match("/multipart/i", $v)) { 
    131                     $use_orgbody = true; 
    132                     $org_boundary = $message->ctype_parameters["boundary"]; 
    133                 } 
    134  
    135                 // save the original content-type header for the body part when forwarding 
    136                 if ($forward && !$use_orgbody) { 
    137                     $forward_h_ct = $v; 
    138                     continue; 
    139                 } 
    140  
    141                 // set charset always to utf-8 
    142                 $org_charset = $v; 
    143                 $v = preg_replace("/charset=([A-Za-z0-9-\"']+)/", "charset=\"utf-8\"", $v); 
    144             } 
    145  
    146             if ($k == "content-transfer-encoding") { 
    147                 // if the content was base64 encoded, encode the body again when sending 
    148                 if (trim($v) == "base64") $body_base64 = true; 
    149  
    150                 // save the original encoding header for the body part when forwarding 
    151                 if ($forward) { 
    152                     $forward_h_cte = $v; 
    153                     continue; 
    154                 } 
    155             } 
    156  
    157             // check if "from"-header is set, do nothing if it's set 
    158             // else set it to IMAP_DEFAULTFROM 
    159             if ($k == "from") { 
    160                 if (trim($v)) { 
    161                     $changedfrom = true; 
    162                 } elseif (! trim($v) && IMAP_DEFAULTFROM) { 
    163                     $changedfrom = true; 
    164                     if      (IMAP_DEFAULTFROM == 'username') $v = $this->_username; 
    165                     else if (IMAP_DEFAULTFROM == 'domain')   $v = $this->_domain; 
    166                     else $v = $this->_username . IMAP_DEFAULTFROM; 
    167                     $envelopefrom = "-f$v"; 
    168                 } 
    169             } 
    170  
    171             // check if "Return-Path"-header is set 
    172             if ($k == "return-path") { 
    173                 $returnPathSet = true; 
    174                 if (! trim($v) && IMAP_DEFAULTFROM) { 
    175                     if      (IMAP_DEFAULTFROM == 'username') $v = $this->_username; 
    176                     else if (IMAP_DEFAULTFROM == 'domain')   $v = $this->_domain; 
    177                     else $v = $this->_username . IMAP_DEFAULTFROM; 
    178                 } 
    179             } 
    180  
    181             // all other headers stay 
    182             if ($headers) $headers .= "\n"; 
    183             $headers .= ucfirst($k) . ": ". $v; 
    184         } 
    185  
    186         // set "From" header if not set on the device 
    187         if(IMAP_DEFAULTFROM && !$changedfrom){ 
    188             if      (IMAP_DEFAULTFROM == 'username') $v = $this->_username; 
    189             else if (IMAP_DEFAULTFROM == 'domain')   $v = $this->_domain; 
    190             else $v = $this->_username . IMAP_DEFAULTFROM; 
    191             if ($headers) $headers .= "\n"; 
    192             $headers .= 'From: '.$v; 
    193             $envelopefrom = "-f$v"; 
    194         } 
    195  
    196         // set "Return-Path" header if not set on the device 
    197         if(IMAP_DEFAULTFROM && !$returnPathSet){ 
    198             if      (IMAP_DEFAULTFROM == 'username') $v = $this->_username; 
    199             else if (IMAP_DEFAULTFROM == 'domain')   $v = $this->_domain; 
    200             else $v = $this->_username . IMAP_DEFAULTFROM; 
    201             if ($headers) $headers .= "\n"; 
    202             $headers .= 'Return-Path: '.$v; 
    203         } 
    204  
    205         // if this is a multipart message with a boundary, we must use the original body 
    206         if ($use_orgbody) { 
    207             list(,$body) = $mobj->_splitBodyHeader($rfc822);  
    208             $repl_body = $this->getBody($message);  
    209             if ($message->parts[0]->headers["content-transfer-encoding"] == "base64") $multipart_text_cte_base64 = true; 
    210             else $multipart_text_cte_base64 = false; 
    211         } 
    212         else 
    213             $body = $this->getBody($message); 
    214  
    215         // reply 
    216         if ($reply && $parent) { 
    217             $this->imap_reopenFolder($parent); 
    218             // receive entire mail (header + body) to decode body correctly 
    219             $origmail = @imap_fetchheader($this->_mbox, $reply, FT_UID) . @imap_body($this->_mbox, $reply, FT_PEEK | FT_UID); 
    220  
    221             $mobj2 = new Mail_mimeDecode($origmail); 
    222             // receive only body 
    223             $body .= $this->getBody($mobj2->decode(array('decode_headers' => false, 'decode_bodies' => true, 'include_bodies' => true, 'charset' => 'utf-8'))); 
    224             // unset mimedecoder & origmail - free memory 
    225             unset($mobj2); 
    226             unset($origmail); 
    227         } 
    228  
    229         // encode the body to base64 if it was sent originally in base64 by the pda 
    230         // contrib - chunk base64 encoded body 
    231         if ($body_base64 && !$forward) $body = chunk_split(base64_encode($body)); 
    232  
    233  
    234         // forward 
    235         if ($forward && $parent) { 
    236             $this->imap_reopenFolder($parent); 
    237             // receive entire mail (header + body) 
    238             $origmail = @imap_fetchheader($this->_mbox, $forward, FT_UID) . @imap_body($this->_mbox, $forward, FT_PEEK | FT_UID); 
    239  
    240             //if (!defined('IMAP_INLINE_FORWARD') || IMAP_INLINE_FORWARD === false) { 
    241             if (defined('IMAP_INLINE_FORWARD') && IMAP_INLINE_FORWARD === false) { 
    242                 // contrib - chunk base64 encoded body 
    243                 if ($body_base64) $body = chunk_split(base64_encode($body)); 
    244                 //use original boundary if it's set 
    245                 $boundary = ($org_boundary) ? $org_boundary : false; 
    246                 // build a new mime message, forward entire old mail as file 
    247                 list($aheader, $body) = $this->mail_attach("forwarded_message.eml",strlen($origmail),$origmail, $body, $forward_h_ct, $forward_h_cte,$boundary); 
    248                 // add boundary headers 
    249                 $headers .= "\n" . $aheader; 
    250  
    251             } 
    252             else { 
    253                 $mobj2 = new Mail_mimeDecode($origmail); 
    254                 $mess2 = $mobj2->decode(array('decode_headers' => true, 'decode_bodies' => true, 'include_bodies' => true, 'charset' => 'utf-8')); 
    255  
    256                 if (!$use_orgbody) 
    257                     $nbody = $body; 
    258                 else 
    259                     $nbody = $repl_body; 
    260  
    261                 $nbody .= "\r\n\r\n"; 
    262                 $nbody .= "-----Original Message-----\r\n"; 
    263                 if(isset($mess2->headers['from'])) 
    264                     $nbody .= "From: " . $mess2->headers['from'] . "\r\n"; 
    265                 if(isset($mess2->headers['to']) && strlen($mess2->headers['to']) > 0) 
    266                     $nbody .= "To: " . $mess2->headers['to'] . "\r\n"; 
    267                 if(isset($mess2->headers['cc']) && strlen($mess2->headers['cc']) > 0) 
    268                     $nbody .= "Cc: " . $mess2->headers['cc'] . "\r\n"; 
    269                 if(isset($mess2->headers['date'])) 
    270                     $nbody .= "Sent: " . $mess2->headers['date'] . "\r\n"; 
    271                 if(isset($mess2->headers['subject'])) 
    272                     $nbody .= "Subject: " . $mess2->headers['subject'] . "\r\n"; 
    273                 $nbody .= "\r\n"; 
    274                 $nbody .= $this->getBody($mess2); 
    275  
    276                 if ($body_base64) { 
    277                     // contrib - chunk base64 encoded body 
    278                     $nbody = chunk_split(base64_encode($nbody)); 
    279                     if ($use_orgbody) 
    280                     // contrib - chunk base64 encoded body 
    281                         $repl_body = chunk_split(base64_encode($repl_body)); 
    282                 } 
    283  
    284                 if ($use_orgbody) { 
    285                     debugLog("-------------------"); 
    286                     debugLog("old:\n'$repl_body'\nnew:\n'$nbody'\nund der body:\n'$body'"); 
    287                     //$body is quoted-printable encoded while $repl_body and $nbody are plain text, 
    288                     //so we need to decode $body in order replace to take place 
    289                     if (!$multipart_text_cte_base64) { 
    290                        $body = str_replace($repl_body, $nbody, quoted_printable_decode($body)); 
    291                     } else { 
    292                        $body = str_replace(base64_encode($repl_body), base64_encode($nbody), $body);                    } 
    293                 } 
    294                 else 
    295                     $body = $nbody; 
    296  
    297  
    298                 if(isset($mess2->parts)) { 
    299                     $attached = false; 
    300  
    301                     if ($org_boundary) { 
    302                         $att_boundary = $org_boundary; 
    303                         // cut end boundary from body 
    304                         $body = substr($body, 0, strrpos($body, "--$att_boundary--")); 
    305                     } 
    306                     else { 
    307                         $att_boundary = strtoupper(md5(uniqid(time()))); 
    308                         // add boundary headers 
    309                         $headers .= "\n" . "Content-Type: multipart/mixed; boundary=$att_boundary"; 
    310                         $multipartmixed = true; 
    311                     } 
    312  
    313                     foreach($mess2->parts as $part) { 
    314                         if(isset($part->disposition) && ($part->disposition == "attachment" || $part->disposition == "inline")) { 
    315  
    316                             if(isset($part->d_parameters['filename'])) 
    317                                 $attname = $part->d_parameters['filename']; 
    318                             else if(isset($part->ctype_parameters['name'])) 
    319                                 $attname = $part->ctype_parameters['name']; 
    320                             else if(isset($part->headers['content-description'])) 
    321                                 $attname = $part->headers['content-description']; 
    322                             else $attname = "unknown attachment"; 
    323  
    324                             // ignore html content 
    325                             if ($part->ctype_primary == "text" && $part->ctype_secondary == "html") { 
    326                                 continue; 
    327                             } 
    328                             // 
    329                             if ($use_orgbody || $attached) { 
    330                                 $body .= $this->enc_attach_file($att_boundary, $attname, strlen($part->body),$part->body, $part->ctype_primary ."/". $part->ctype_secondary); 
    331                             } 
    332                             // first attachment 
    333                             else { 
    334                                 $encmail = $body; 
    335                                 $attached = true; 
    336                                 $body = $this->enc_multipart($att_boundary, $body, $forward_h_ct, $forward_h_cte); 
    337                                 $body .= $this->enc_attach_file($att_boundary, $attname, strlen($part->body),$part->body, $part->ctype_primary ."/". $part->ctype_secondary); 
    338                             } 
    339                         } 
    340                     } 
    341                     if ($multipartmixed) { 
    342                         //this happens if a multipart/alternative message is forwarded 
    343                         //then it's a multipart/mixed message which consists of: 
    344                         //1. text/plain part which was written on the mobile 
    345                         //2. multipart/alternative part which is the original message 
    346                         //$body = "This is a message with multiple parts in MIME format.\n--". 
    347                         //        $att_boundary. 
    348                         //        "\nContent-Type: $forward_h_ct\nContent-Transfer-Encoding: $forward_h_cte\n\n". 
    349                         //        (($body_base64) ? chunk_split(base64_encode($message->body)) : rtrim($message->body)). 
    350                         //        "\n--".$att_boundary. 
    351                         //        "\nContent-Type: {$mess2->headers['content-type']}\n\n". 
    352                         //        @imap_body($this->_mbox, $forward, FT_PEEK | FT_UID)."\n\n"; 
    353                         $body = "\n--". 
    354                                 $att_boundary. 
    355                                 "\nContent-Type: $forward_h_ct\nContent-Transfer-Encoding: $forward_h_cte\n\n". 
    356                                 $body; 
    357                     } 
    358  
    359                     $body .= "--$att_boundary--\n\n"; 
    360                 } 
    361  
    362                 unset($mobj2); 
    363             } 
    364  
    365             // unset origmail - free memory 
    366             unset($origmail); 
    367  
    368         } 
    369  
    370         // remove carriage-returns from body 
    371         $body = str_replace("\r\n", "\n", $body); 
    372  
    373         if (!$multipartmixed) { 
    374             if (!empty($forward_h_ct)) $headers .= "\nContent-Type: $forward_h_ct"; 
    375             if (!empty($forward_h_cte)) $headers .= "\nContent-Transfer-Encoding: $forward_h_cte"; 
    376         } 
    377         //advanced debugging 
    378         debugLog("IMAP-SendMail: parsed message: ". print_r($message,1)); 
    379         debugLog("IMAP-SendMail: headers: $headers"); 
    380         debugLog("IMAP-SendMail: subject: {$message->headers["subject"]}"); 
    381         debugLog("IMAP-SendMail: body: $body"); 
    382  
    383         if (!defined('IMAP_USE_IMAPMAIL') || IMAP_USE_IMAPMAIL == true) { 
    384             $send =  @imap_mail ( $toaddr, $message->headers["subject"], $body, $headers, $ccaddr, $bccaddr); 
    385         } 
    386         else { 
    387             if (!empty($ccaddr))  $headers .= "\nCc: $ccaddr"; 
    388             if (!empty($bccaddr)) $headers .= "\nBcc: $bccaddr"; 
    389             $send =  @mail ( $toaddr, $message->headers["subject"], $body, $headers, $envelopefrom ); 
    390         } 
    391  
    392         // email sent? 
    393         if (!$send) { 
    394             debugLog("The email could not be sent. Last-IMAP-error: ". imap_last_error()); 
    395         } 
    396  
    397         // add message to the sent folder 
    398         // build complete headers 
    399         $headers .= "\nTo: $toaddr"; 
    400         $headers .= "\nSubject: " . $message->headers["subject"]; 
    401  
    402         if (!defined('IMAP_USE_IMAPMAIL') || IMAP_USE_IMAPMAIL == true) { 
    403             if (!empty($ccaddr))  $headers .= "\nCc: $ccaddr"; 
    404             if (!empty($bccaddr)) $headers .= "\nBcc: $bccaddr"; 
    405         } 
    406         debugLog("IMAP-SendMail: complete headers: $headers"); 
    407  
    408         $asf = false; 
    409         if ($this->_sentID) { 
    410             $asf = $this->addSentMessage($this->_sentID, $headers, $body); 
    411         } 
    412         else if (IMAP_SENTFOLDER) { 
    413             $asf = $this->addSentMessage(IMAP_SENTFOLDER, $headers, $body); 
    414             debugLog("IMAP-SendMail: Outgoing mail saved in configured 'Sent' folder '".IMAP_SENTFOLDER."': ". (($asf)?"success":"failed")); 
    415         } 
    416         // No Sent folder set, try defaults 
    417         else { 
    418             debugLog("IMAP-SendMail: No Sent mailbox set"); 
    419             if($this->addSentMessage("INBOX.Sent", $headers, $body)) { 
    420                 debugLog("IMAP-SendMail: Outgoing mail saved in 'INBOX.Sent'"); 
    421                 $asf = true; 
    422             } 
    423             else if ($this->addSentMessage("Sent", $headers, $body)) { 
    424                 debugLog("IMAP-SendMail: Outgoing mail saved in 'Sent'"); 
    425                 $asf = true; 
    426             } 
    427             else if ($this->addSentMessage("Sent Items", $headers, $body)) { 
    428                 debugLog("IMAP-SendMail: Outgoing mail saved in 'Sent Items'"); 
    429                 $asf = true; 
    430             } 
    431         } 
    432  
    433         // unset mimedecoder - free memory 
    434         unset($mobj); 
    435         return ($send && $asf); 
    436     } 
    437          
     93        function SendMail($rfc822, $forward = false, $reply = false, $parent = false) { 
     94                debugLog("IMAP-SendMail: for: $forward   reply: $reply   parent: $parent  RFC822:  \n". $rfc822 ); 
     95 
     96                $mobj = new Mail_mimeDecode($rfc822); 
     97                $message = $mobj->decode(array('decode_headers' => false, 'decode_bodies' => true, 'include_bodies' => true, 'charset' => 'utf-8')); 
     98 
     99                $Mail_RFC822 = new Mail_RFC822(); 
     100                $toaddr = $ccaddr = $bccaddr = ""; 
     101                if(isset($message->headers["to"])) 
     102                        $toaddr = $this->parseAddr($Mail_RFC822->parseAddressList($message->headers["to"])); 
     103                if(isset($message->headers["cc"])) 
     104                        $ccaddr = $this->parseAddr($Mail_RFC822->parseAddressList($message->headers["cc"])); 
     105                if(isset($message->headers["bcc"])) 
     106                        $bccaddr = $this->parseAddr($Mail_RFC822->parseAddressList($message->headers["bcc"])); 
     107 
     108                // save some headers when forwarding mails (content type & transfer-encoding) 
     109                $headers = ""; 
     110                $forward_h_ct = ""; 
     111                $forward_h_cte = ""; 
     112                $envelopefrom = ""; 
     113 
     114                $use_orgbody = false; 
     115 
     116                // clean up the transmitted headers 
     117                // remove default headers because we are using imap_mail 
     118                $changedfrom = false; 
     119                $returnPathSet = false; 
     120                $body_base64 = false; 
     121                $org_charset = ""; 
     122                $org_boundary = false; 
     123                $multipartmixed = false; 
     124                 
     125                foreach($message->headers as $k => $v) { 
     126                        if ($k == "subject" || $k == "to" || $k == "cc" || $k == "bcc") 
     127                                continue; 
     128 
     129                        if ($k == "content-type") { 
     130                                // if the message is a multipart message, then we should use the sent body 
     131                                if (preg_match("/multipart/i", $v)) { 
     132                                        $use_orgbody = true; 
     133                                        $org_boundary = $message->ctype_parameters["boundary"]; 
     134                                } 
     135 
     136                                // save the original content-type header for the body part when forwarding 
     137                                if ($forward && !$use_orgbody) { 
     138                                        $forward_h_ct = $v; 
     139                                        continue; 
     140                                } 
     141 
     142                                // set charset always to utf-8 
     143                                $org_charset = $v; 
     144                                $v = preg_replace("/charset=([A-Za-z0-9-\"']+)/", "charset=\"utf-8\"", $v); 
     145                        } 
     146 
     147                        if ($k == "content-transfer-encoding") { 
     148                                // if the content was base64 encoded, encode the body again when sending 
     149                                if (trim($v) == "base64") $body_base64 = true; 
     150 
     151                                // save the original encoding header for the body part when forwarding 
     152                                if ($forward) { 
     153                                        $forward_h_cte = $v; 
     154                                        continue; 
     155                                } 
     156                        } 
     157 
     158                        // check if "from"-header is set, do nothing if it's set 
     159                        // else set it to IMAP_DEFAULTFROM 
     160                        if ($k == "from") { 
     161                                if (trim($v)) { 
     162                                        $changedfrom = true; 
     163                                } elseif (! trim($v) && IMAP_DEFAULTFROM) { 
     164                                        $changedfrom = true; 
     165                                        if      (IMAP_DEFAULTFROM == 'username') $v = $this->_username; 
     166                                        else if (IMAP_DEFAULTFROM == 'domain')   $v = $this->_domain; 
     167                                        else $v = $this->_username . IMAP_DEFAULTFROM; 
     168                                        $envelopefrom = "-f$v"; 
     169                                } 
     170                        } 
     171 
     172                        // check if "Return-Path"-header is set 
     173                        if ($k == "return-path") { 
     174                                $returnPathSet = true; 
     175                                if (! trim($v) && IMAP_DEFAULTFROM) { 
     176                                        if      (IMAP_DEFAULTFROM == 'username') $v = $this->_username; 
     177                                        else if (IMAP_DEFAULTFROM == 'domain')   $v = $this->_domain; 
     178                                        else $v = $this->_username . IMAP_DEFAULTFROM; 
     179                                } 
     180                        } 
     181 
     182                        // all other headers stay 
     183                        if ($headers) $headers .= "\n"; 
     184                        $headers .= ucfirst($k) . ": ". $v; 
     185                } 
     186 
     187                // set "From" header if not set on the device 
     188                if(IMAP_DEFAULTFROM && !$changedfrom){ 
     189                        if      (IMAP_DEFAULTFROM == 'username') $v = $this->_username; 
     190                        else if (IMAP_DEFAULTFROM == 'domain')   $v = $this->_domain; 
     191                        else $v = $this->_username . IMAP_DEFAULTFROM; 
     192                        if ($headers) $headers .= "\n"; 
     193                        $headers .= 'From: '.$v; 
     194                        $envelopefrom = "-f$v"; 
     195                } 
     196 
     197                // set "Return-Path" header if not set on the device 
     198                if(IMAP_DEFAULTFROM && !$returnPathSet){ 
     199                        if      (IMAP_DEFAULTFROM == 'username') $v = $this->_username; 
     200                        else if (IMAP_DEFAULTFROM == 'domain')   $v = $this->_domain; 
     201                        else $v = $this->_username . IMAP_DEFAULTFROM; 
     202                        if ($headers) $headers .= "\n"; 
     203                        $headers .= 'Return-Path: '.$v; 
     204                } 
     205 
     206                // if this is a multipart message with a boundary, we must use the original body 
     207                if ($use_orgbody) { 
     208                        list(,$body) = $mobj->_splitBodyHeader($rfc822); 
     209                        $repl_body = $this->getBody($message);  
     210                        if ($message->parts[0]->headers["content-transfer-encoding"] == "base64") $multipart_text_cte_base64 = true; 
     211                        else $multipart_text_cte_base64 = false; 
     212                } 
     213                else 
     214                        $body = $this->getBody($message); 
     215 
     216                // reply 
     217                if ($reply && $parent) { 
     218                        $this->imap_reopenFolder($parent); 
     219                        // receive entire mail (header + body) to decode body correctly 
     220                        $origmail = @imap_fetchheader($this->_mbox, $reply, FT_UID) . @imap_body($this->_mbox, $reply, FT_PEEK | FT_UID); 
     221 
     222                        $mobj2 = new Mail_mimeDecode($origmail); 
     223                        // receive only body 
     224                        $body .= $this->getBody($mobj2->decode(array('decode_headers' => false, 'decode_bodies' => true, 'include_bodies' => true, 'charset' => 'utf-8'))); 
     225                        // unset mimedecoder & origmail - free memory 
     226                        unset($mobj2); 
     227                        unset($origmail); 
     228                } 
     229 
     230                // encode the body to base64 if it was sent originally in base64 by the pda 
     231                // contrib - chunk base64 encoded body 
     232                if ($body_base64 && !$forward) $body = chunk_split(base64_encode($body)); 
     233 
     234 
     235                // forward 
     236                if ($forward && $parent) { 
     237                        $this->imap_reopenFolder($parent); 
     238                        // receive entire mail (header + body) 
     239                        $origmail = @imap_fetchheader($this->_mbox, $forward, FT_UID) . @imap_body($this->_mbox, $forward, FT_PEEK | FT_UID); 
     240 
     241                                if (defined('IMAP_INLINE_FORWARD') && IMAP_INLINE_FORWARD === false) { 
     242                                        // contrib - chunk base64 encoded body 
     243                                        if ($body_base64) $body = chunk_split(base64_encode($body)); 
     244                                        //use original boundary if it's set 
     245                                        $boundary = ($org_boundary) ? $org_boundary : false; 
     246                                        // build a new mime message, forward entire old mail as file 
     247                                        list($aheader, $body) = $this->mail_attach("forwarded_message.eml",strlen($origmail),$origmail, $body, $forward_h_ct, $forward_h_cte,$boundary); 
     248                                        // add boundary headers 
     249                                        $headers .= "\n" . $aheader; 
     250                                }  
     251                                else { 
     252                                        $mobj2 = new Mail_mimeDecode($origmail); 
     253                                        $mess2 = $mobj2->decode(array('decode_headers' => true, 'decode_bodies' => true, 'include_bodies' => true, 'charset' => 'utf-8')); 
     254 
     255                                        if (!$use_orgbody) 
     256                                                $nbody = $body; 
     257                                        else 
     258                                                $nbody = $repl_body; 
     259 
     260                                        $nbody .= "\r\n\r\n"; 
     261                                        $nbody .= "-----Original Message-----\r\n"; 
     262                                        if(isset($mess2->headers['from'])) 
     263                                                $nbody .= "From: " . $mess2->headers['from'] . "\r\n"; 
     264                                        if(isset($mess2->headers['to']) && strlen($mess2->headers['to']) > 0) 
     265                                                $nbody .= "To: " . $mess2->headers['to'] . "\r\n"; 
     266                                        if(isset($mess2->headers['cc']) && strlen($mess2->headers['cc']) > 0) 
     267                                                $nbody .= "Cc: " . $mess2->headers['cc'] . "\r\n"; 
     268                                        if(isset($mess2->headers['date'])) 
     269                                                $nbody .= "Sent: " . $mess2->headers['date'] . "\r\n"; 
     270                                        if(isset($mess2->headers['subject'])) 
     271                                                $nbody .= "Subject: " . $mess2->headers['subject'] . "\r\n"; 
     272                                         
     273                                        $nbody .= "\r\n"; 
     274                                        $nbody .= $this->getBody($mess2); 
     275 
     276                                        if ($body_base64) { 
     277                                                // contrib - chunk base64 encoded body 
     278                                                $nbody = chunk_split(base64_encode($nbody)); 
     279                                                if ($use_orgbody) 
     280                                                        // contrib - chunk base64 encoded body 
     281                                                        $repl_body = chunk_split(base64_encode($repl_body)); 
     282                                        } 
     283 
     284                                        if ($use_orgbody) { 
     285                                                debugLog("-------------------"); 
     286                                                debugLog("old:\n'$repl_body'\nnew:\n'$nbody'\nund der body:\n'$body'"); 
     287                                                //$body is quoted-printable encoded while $repl_body and $nbody are plain text, 
     288                                                //so we need to decode $body in order replace to take place 
     289                                                if (!$multipart_text_cte_base64) { 
     290                                                        $body = str_replace($repl_body, $nbody, quoted_printable_decode($body)); 
     291                                                } else { 
     292                                                        $body = str_replace(base64_encode($repl_body), base64_encode($nbody), $body);                     
     293                                                } 
     294                                        } 
     295                                        else 
     296                                                $body = $nbody; 
     297 
     298 
     299                                        if(isset($mess2->parts)) { 
     300                                                $attached = false; 
     301 
     302                                                if ($org_boundary) { 
     303                                                        $att_boundary = $org_boundary; 
     304                                                        // cut end boundary from body 
     305                                                        $body = substr($body, 0, strrpos($body, "--$att_boundary--")); 
     306                                                } 
     307                                                else { 
     308                                                        $att_boundary = strtoupper(md5(uniqid(time()))); 
     309                                                        // add boundary headers 
     310                                                        $headers .= "\n" . "Content-Type: multipart/mixed; boundary=$att_boundary"; 
     311                                                        $multipartmixed = true; 
     312                                                } 
     313 
     314                                                foreach($mess2->parts as $part) { 
     315                                                        if(isset($part->disposition) && ($part->disposition == "attachment" || $part->disposition == "inline")) { 
     316 
     317                                                        if(isset($part->d_parameters['filename'])) 
     318                                                                $attname = $part->d_parameters['filename']; 
     319                                                        else if(isset($part->ctype_parameters['name'])) 
     320                                                                $attname = $part->ctype_parameters['name']; 
     321                                                        else if(isset($part->headers['content-description'])) 
     322                                                                $attname = $part->headers['content-description']; 
     323                                                        else $attname = "unknown attachment"; 
     324 
     325                                                        // ignore html content 
     326                                                        if ($part->ctype_primary == "text" && $part->ctype_secondary == "html") { 
     327                                                                continue; 
     328                                                        } 
     329                                                        // 
     330                                                        if ($use_orgbody || $attached) { 
     331                                                                $body .= $this->enc_attach_file($att_boundary, $attname, strlen($part->body),$part->body, $part->ctype_primary ."/". $part->ctype_secondary); 
     332                                                        } 
     333                                                        // first attachment 
     334                                                        else { 
     335                                                                $encmail = $body; 
     336                                                                $attached = true; 
     337                                                                $body = $this->enc_multipart($att_boundary, $body, $forward_h_ct, $forward_h_cte); 
     338                                                                $body .= $this->enc_attach_file($att_boundary, $attname, strlen($part->body),$part->body, $part->ctype_primary ."/". $part->ctype_secondary); 
     339                                                        } 
     340                                                } 
     341                                        } 
     342                                        if ($multipartmixed) { 
     343                                                //this happens if a multipart/alternative message is forwarded 
     344                                                //then it's a multipart/mixed message which consists of: 
     345                                                //1. text/plain part which was written on the mobile 
     346                                                //2. multipart/alternative part which is the original message 
     347                                                //$body = "This is a message with multiple parts in MIME format.\n--". 
     348                                                //        $att_boundary. 
     349                                                //        "\nContent-Type: $forward_h_ct\nContent-Transfer-Encoding: $forward_h_cte\n\n". 
     350                                                //        (($body_base64) ? chunk_split(base64_encode($message->body)) : rtrim($message->body)). 
     351                                                //        "\n--".$att_boundary. 
     352                                                //        "\nContent-Type: {$mess2->headers['content-type']}\n\n". 
     353                                                //        @imap_body($this->_mbox, $forward, FT_PEEK | FT_UID)."\n\n"; 
     354                                                $body = "\n--". 
     355                                                        $att_boundary. 
     356                                                        "\nContent-Type: $forward_h_ct\nContent-Transfer-Encoding: $forward_h_cte\n\n". 
     357                                                        $body; 
     358                                        } 
     359 
     360                                        $body .= "--$att_boundary--\n\n"; 
     361                                } 
     362 
     363                                unset($mobj2); 
     364                        } 
     365 
     366                        // unset origmail - free memory 
     367                        unset($origmail); 
     368 
     369                } 
     370 
     371                // remove carriage-returns from body 
     372                $body = str_replace("\r\n", "\n", $body); 
     373 
     374                if (!$multipartmixed) { 
     375                        if (!empty($forward_h_ct)) $headers .= "\nContent-Type: $forward_h_ct"; 
     376                        if (!empty($forward_h_cte)) $headers .= "\nContent-Transfer-Encoding: $forward_h_cte"; 
     377                } 
     378                //advanced debugging 
     379                debugLog("IMAP-SendMail: parsed message: ". print_r($message,1)); 
     380                debugLog("IMAP-SendMail: headers: $headers"); 
     381                debugLog("IMAP-SendMail: subject: {$message->headers["subject"]}"); 
     382                debugLog("IMAP-SendMail: body: $body"); 
     383 
     384                if (!defined('IMAP_USE_IMAPMAIL') || IMAP_USE_IMAPMAIL == true) { 
     385                        $send =  @imap_mail ( $toaddr, $message->headers["subject"], $body, $headers, $ccaddr, $bccaddr); 
     386                } 
     387                else { 
     388                        if (!empty($ccaddr))  $headers .= "\nCc: $ccaddr"; 
     389                        if (!empty($bccaddr)) $headers .= "\nBcc: $bccaddr"; 
     390                        $send =  @mail ( $toaddr, $message->headers["subject"], $body, $headers, $envelopefrom ); 
     391                } 
     392 
     393                // email sent? 
     394                if (!$send) { 
     395                        debugLog("The email could not be sent. Last-IMAP-error: ". imap_last_error()); 
     396                } 
     397 
     398                // add message to the sent folder 
     399                // build complete headers 
     400                $headers .= "\nTo: $toaddr"; 
     401                $headers .= "\nSubject: " . $message->headers["subject"]; 
     402 
     403                if (!defined('IMAP_USE_IMAPMAIL') || IMAP_USE_IMAPMAIL == true) { 
     404                        if (!empty($ccaddr))  $headers .= "\nCc: $ccaddr"; 
     405                        if (!empty($bccaddr)) $headers .= "\nBcc: $bccaddr"; 
     406                } 
     407                debugLog("IMAP-SendMail: complete headers: $headers"); 
     408 
     409                $asf = false; 
     410                if ($this->_sentID) { 
     411                        $asf = $this->addSentMessage($this->_sentID, $headers, $body); 
     412                } 
     413                else if(defined("IMAP_SENTFOLDER")) { 
     414                        $asf = $this->addSentMessage(IMAP_SENTFOLDER, $headers, $body); 
     415                        debugLog("IMAP-SendMail: Outgoing mail saved in configured 'Sent' folder '".IMAP_SENTFOLDER."': ". (($asf)?"success":"failed")); 
     416                } 
     417                // No Sent folder set, try defaults 
     418                else { 
     419                        debugLog("IMAP-SendMail: No Sent mailbox set"); 
     420                        if($this->addSentMessage("INBOX.Sent", $headers, $body)) { 
     421                                debugLog("IMAP-SendMail: Outgoing mail saved in 'INBOX.Sent'"); 
     422                                $asf = true; 
     423                        } 
     424                        else if ($this->addSentMessage("Sent", $headers, $body)) { 
     425                                debugLog("IMAP-SendMail: Outgoing mail saved in 'Sent'"); 
     426                                $asf = true; 
     427                        } 
     428                        else if ($this->addSentMessage("Sent Items", $headers, $body)) { 
     429                                debugLog("IMAP-SendMail: Outgoing mail saved in 'Sent Items'"); 
     430                                $asf = true; 
     431                        } 
     432                } 
     433 
     434                // unset mimedecoder - free memory 
     435                unset($mobj); 
     436                return ($send && $asf); 
     437        } 
    438438 
    439439        /* Should return a wastebasket folder if there is one. This is used when deleting 
     
    468468                        if ($search !== false) 
    469469                        $sequence = implode(",", $search); 
    470                         if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog('IMAP::GetMessageList-> A função @imap_search leu as seguintes SEQUÊNCIAS do servidor IMAP com base no filtro de data: '.$sequence); 
     470                        if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog('IMAP::GetMessageList-> A função @imap_search leu as seguintes SEQUÊNCIAS do servidor IMAP com base no filtro de data: '.$sequence); 
    471471                } 
    472472 
     
    479479                                $date = ""; 
    480480                                $vars = get_object_vars($overview); 
    481                                 if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog('IMAP::GetMessageList-> A função @imap_fetch_overview leu mais detalhes da mensagem: '. print_r($overview,1)); 
     481                                if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog('IMAP::GetMessageList-> A função @imap_fetch_overview leu mais detalhes da mensagem: '. print_r($overview,1)); 
    482482                                if (array_key_exists( "date", $vars)) { 
    483483                                        // message is out of range for cutoffdate, ignore it 
    484484                                        if(strtotime(preg_replace("/\(.*\)/", "", $overview->date)) < $cutoffdate) { // emerson-faria.nobre@serpro.gov.br - 07/feb/2011 
    485                                                 if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog('IMAP::GetMessageList-> O overview->date: '.$overview->date.' (overview->date_timestamp: '.strtotime(preg_replace("/\(.*\)/", "", $overview->date)).') é menor que o $cutoffdate: '.date("d/m/Y G:i:s",$cutoffdate).' ($cutoffdate_timestamp: '.$cutoffdate.') ou a função "strtotime" gerou um ERRO porque não conseguiu retornar um valor para o overview->date_timestamp. A mensagem será descartada da sincronização.'); 
     485                                                if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog('IMAP::GetMessageList-> O overview->date: '.$overview->date.' (overview->date_timestamp: '.strtotime(preg_replace("/\(.*\)/", "", $overview->date)).') é menor que o $cutoffdate: '.date("d/m/Y G:i:s",$cutoffdate).' ($cutoffdate_timestamp: '.$cutoffdate.') ou a função "strtotime" gerou um ERRO porque não conseguiu retornar um valor para o overview->date_timestamp. A mensagem será descartada da sincronização.'); 
    486486                                                continue; 
    487487                                        } 
    488488                                        //if(strtotime($overview->date) < $cutoffdate) continue; 
    489489                                        $date = $overview->date; 
    490                                 } else if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog('IMAP::GetMessageList-> ERRO: O campo date não existe no overview da mensagem.'); 
     490                                } else if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog('IMAP::GetMessageList-> ERRO: O campo date não existe no overview da mensagem.'); 
    491491 
    492492                                // cut of deleted messages 
    493493                                if (array_key_exists( "deleted", $vars) && $overview->deleted) { 
    494                                         if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog('IMAP::GetMessageList-> A mensagem está com o flag deleted ativo e será descartada da sincronização'); 
    495                                         continue; 
     494                                        if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog('IMAP::GetMessageList-> A mensagem está com o flag deleted ativo e será descartada da sincronização'); 
     495                                continue; 
    496496                                } 
    497497 
     
    506506                                        $message["flags"] = 1; 
    507507                                        array_push($messages, $message); 
    508                                 } else if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog('IMAP::GetMessageList-> ERRO: O campo uid não existe no overview da mensagem.'); 
    509                         } 
    510                 } 
     508                                } else if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog('IMAP::GetMessageList-> ERRO: O campo uid não existe no overview da mensagem.'); 
     509                                } 
     510                        } 
    511511                return $messages; 
    512512        } 
     
    523523                        $list = array_reverse($list); 
    524524                        foreach ($list as $val) { 
    525                                 if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog('IMAP::GetFolderList-> Pasta lida usando a função @imap_getmailboxes: '.print_r($val,1)); 
     525                                if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog('IMAP::GetFolderList-> Pasta lida usando a função @imap_getmailboxes: '.print_r($val,1)); 
    526526                                $box = array(); 
    527527 
     
    542542                                        $box["parent"] = "0"; 
    543543                                } 
    544                                 if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog('IMAP::GetFolderList-> Parâmetros da pasta após decodificação: '.print_r($box,1)); 
     544                                if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog('IMAP::GetFolderList-> Parâmetros da pasta após decodificação: '.print_r($box,1)); 
    545545                                $folders[]=$box; 
    546546                        } 
     
    699699                if (isset($message->parts[$part]->body)) 
    700700                print $message->parts[$part]->body; 
    701                  
     701 
    702702                // unset mimedecoder & mail 
    703703                unset($mobj); 
     
    729729                        $vars = get_object_vars($overview[0]); 
    730730 
    731                         if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL') and (! array_key_exists( "uid", $vars))) debugLog('IMAP::StatMessage-> ERRO: A mensagem será desconsiderada porque não tem o campo "uid"'); 
     731                        if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL') and (! array_key_exists( "uid", $vars))) debugLog('IMAP::StatMessage-> ERRO: A mensagem será desconsiderada porque não tem o campo "uid"'); 
    732732                        // without uid it's not a valid message 
    733733                        if (! array_key_exists( "uid", $vars)) return false; 
     
    768768                        $mail = @imap_fetchheader($this->_mbox, $id, FT_PREFETCHTEXT | FT_UID) . @imap_body($this->_mbox, $id, FT_PEEK | FT_UID); 
    769769 
    770                         if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog("IMAP-GetMessage: Mensagem lida do servidor IMAP através da função @imap_fetchheader: ". print_r($mail,1)); 
     770                        if (TRACE_UID !== false and (TRACE_TYPE == 'IMAP' or TRACE_TYPE == 'ALL')) traceLog("IMAP-GetMessage: Mensagem lida do servidor IMAP através da função @imap_fetchheader: ". print_r($mail,1)); 
    771771 
    772772                        $mobj = new Mail_mimeDecode($mail); 
     
    999999                        // Remove the HTML tags using the 'html2text' - emerson-faria.nobre@serpro.gov.br 
    10001000                        // The 'html2text' (http://www.mbayer.de/html2text) must be installed in Z-Push server. 
    1001  
     1001                                 
    10021002                        // Advanced debug 
    10031003                        // debugLog("IMAP-getBody: subject: " . $message->headers["subject"]); 
    1004                         $body = utf8_encode($body); 
     1004                        $body = utf8_encode($body);      
    10051005                        libxml_use_internal_errors(true); 
    10061006                        try { 
     
    10541054 
    10551055                if(strcasecmp($message->ctype_primary,"multipart")==0 && isset($message->parts) && is_array($message->parts)) { 
    1056                 foreach($message->parts as $part) { 
     1056                        foreach($message->parts as $part) { 
    10571057                                if(!isset($part->disposition) || strcasecmp($part->disposition,"attachment"))  { 
    10581058                                        $this->getBodyRecursive($part, $subtype, $body); 
     
    10861086 
    10871087        // build a multipart email, embedding body and one file (for attachments) 
    1088    function mail_attach($filenm,$filesize,$file_cont,$body, $body_ct, $body_cte, $boundary = false) { 
    1089         if (!$boundary) $boundary = strtoupper(md5(uniqid(time()))); 
    1090  
    1091         //remove the ending boundary because we will add it at the end 
    1092         $body = str_replace("--$boundary--", "", $body); 
    1093  
    1094         $mail_header = "Content-Type: multipart/mixed; boundary=$boundary\n"; 
    1095  
    1096         // build main body with the sumitted type & encoding from the pda 
    1097         $mail_body  = $this->enc_multipart($boundary, $body, $body_ct, $body_cte); 
    1098         $mail_body .= $this->enc_attach_file($boundary, $filenm, $filesize, $file_cont); 
    1099  
    1100         $mail_body .= "--$boundary--\n\n"; 
    1101         return array($mail_header, $mail_body); 
    1102     } 
    1103  
    1104     function enc_multipart($boundary, $body, $body_ct, $body_cte) { 
     1088        function mail_attach($filenm,$filesize,$file_cont,$body, $body_ct, $body_cte, $boundary = false) { 
     1089                if (!$boundary) $boundary = strtoupper(md5(uniqid(time()))); 
     1090 
     1091                //remove the ending boundary because we will add it at the end 
     1092                $body = str_replace("--$boundary--", "", $body); 
     1093 
     1094                $mail_header = "Content-Type: multipart/mixed; boundary=$boundary\n"; 
     1095 
     1096                // build main body with the sumitted type & encoding from the pda 
     1097                $mail_body  = $this->enc_multipart($boundary, $body, $body_ct, $body_cte); 
     1098                $mail_body .= $this->enc_attach_file($boundary, $filenm, $filesize, $file_cont); 
     1099 
     1100                $mail_body .= "--$boundary--\n\n"; 
     1101                 
     1102                return array($mail_header, $mail_body); 
     1103        } 
     1104 
     1105        function enc_multipart($boundary, $body, $body_ct, $body_cte) { 
    11051106//        $mail_body = "This is a multi-part message in MIME format\n\n";    
    11061107//        $mail_body .= "--$boundary\n"; 
    11071108//        $mail_body .= "Content-Type: $body_ct\n"; 
    11081109//        $mail_body .= "Content-Transfer-Encoding: $body_cte\n\n"; 
    1109         $mail_body = "$body\n\n"; 
    1110  
    1111         return $mail_body; 
    1112     } 
     1110        $mail_body = "$body\n\n"; 
     1111 
     1112        return $mail_body; 
     1113        } 
    11131114     
    1114     function enc_attach_file($boundary, $filenm, $filesize, $file_cont, $content_type = "") { 
    1115         if (!$content_type) $content_type = "text/plain"; 
    1116         $mail_body = "--$boundary\n"; 
    1117         $mail_body .= "Content-Type: $content_type; name=\"$filenm\"\n"; 
    1118         $mail_body .= "Content-Transfer-Encoding: base64\n"; 
    1119         $mail_body .= "Content-Disposition: attachment; filename=\"$filenm\"\n"; 
    1120         $mail_body .= "Content-Description: $filenm\n\n"; 
    1121         //contrib - chunk base64 encoded attachments 
    1122         $mail_body .= chunk_split(base64_encode($file_cont)) . "\n\n"; 
    1123  
    1124         return $mail_body; 
    1125     } 
    1126          
     1115        function enc_attach_file($boundary, $filenm, $filesize, $file_cont, $content_type = "") { 
     1116                if (!$content_type) $content_type = "text/plain"; 
     1117                $mail_body = "--$boundary\n"; 
     1118                $mail_body .= "Content-Type: $content_type; name=\"$filenm\"\n"; 
     1119                $mail_body .= "Content-Transfer-Encoding: base64\n"; 
     1120                $mail_body .= "Content-Disposition: attachment; filename=\"$filenm\"\n"; 
     1121                $mail_body .= "Content-Description: $filenm\n\n"; 
     1122                //contrib - chunk base64 encoded attachments 
     1123                $mail_body .= chunk_split(base64_encode($file_cont)) . "\n\n"; 
     1124 
     1125                return $mail_body; 
     1126        } 
     1127 
    11271128        // adds a message as seen to a specified folder (used for saving sent mails) 
    11281129        function addSentMessage($folderid, $header, $body) { 
  • contrib/z-push/include/mimeDecode.php

    r4613 r4898  
    102102class Mail_mimeDecode 
    103103{ 
    104     /** 
    105      * The raw email to decode 
    106      * 
    107      * @var    string 
    108      * @access private 
    109      */ 
    110     var $_input; 
    111  
    112     /** 
    113      * The header part of the input 
    114      * 
    115      * @var    string 
    116      * @access private 
    117      */ 
    118     var $_header; 
    119  
    120     /** 
    121      * The body part of the input 
    122      * 
    123      * @var    string 
    124      * @access private 
    125      */ 
    126     var $_body; 
    127  
    128     /** 
    129      * If an error occurs, this is used to store the message 
    130      * 
    131      * @var    string 
    132      * @access private 
    133      */ 
    134     var $_error; 
    135  
    136     /** 
    137      * Flag to determine whether to include bodies in the 
    138      * returned object. 
    139      * 
    140      * @var    boolean 
    141      * @access private 
    142      */ 
    143     var $_include_bodies; 
    144  
    145     /** 
    146      * Flag to determine whether to decode bodies 
    147      * 
    148      * @var    boolean 
    149      * @access private 
    150      */ 
    151     var $_decode_bodies; 
    152  
    153     /** 
    154      * Flag to determine whether to decode headers 
    155      * 
    156      * @var    boolean 
    157      * @access private 
    158      */ 
    159     var $_decode_headers; 
    160  
    161     /** 
    162      * Flag to determine whether to include attached messages 
    163      * as body in the returned object. Depends on $_include_bodies 
    164      * 
    165      * @var    boolean 
    166      * @access private 
    167      */ 
    168     var $_rfc822_bodies; 
    169  
    170     /** 
    171      * Constructor. 
    172      * 
    173      * Sets up the object, initialise the variables, and splits and 
    174      * stores the header and body of the input. 
    175      * 
    176      * @param string The input to decode 
    177      * @access public 
    178      */ 
    179     function Mail_mimeDecode($input, $deprecated_linefeed = '') 
    180     { 
    181         list($header, $body)   = $this->_splitBodyHeader($input); 
    182  
    183         $this->_input          = $input; 
    184         $this->_header         = $header; 
    185         $this->_body           = $body; 
    186         $this->_decode_bodies  = false; 
    187         $this->_include_bodies = true; 
    188         $this->_rfc822_bodies  = false; 
    189     } 
    190  
    191     /** 
    192      * Begins the decoding process. If called statically 
    193      * it will create an object and call the decode() method 
    194      * of it. 
    195      * 
    196      * @param array An array of various parameters that determine 
    197      *              various things: 
    198      *              include_bodies - Whether to include the body in the returned 
    199      *                               object. 
    200      *              decode_bodies  - Whether to decode the bodies 
    201      *                               of the parts. (Transfer encoding) 
    202      *              decode_headers - Whether to decode headers 
    203      *              input          - If called statically, this will be treated 
    204      *                               as the input 
    205      *              charset        - convert all data to this charset 
    206      * @return object Decoded results 
    207      * @access public 
    208      */ 
    209     function decode($params = null) 
    210     { 
    211         // determine if this method has been called statically 
    212         $isStatic = !(isset($this) && get_class($this) == __CLASS__); 
    213  
    214         // Have we been called statically? 
    215         // If so, create an object and pass details to that. 
    216         if ($isStatic AND isset($params['input'])) { 
    217  
    218             $obj = new Mail_mimeDecode($params['input']); 
    219             $structure = $obj->decode($params); 
    220  
    221         // Called statically but no input 
    222         } elseif ($isStatic) { 
    223             return $this->raiseError('Called statically and no input given'); 
    224  
    225         // Called via an object 
    226         } else { 
    227             $this->_include_bodies = isset($params['include_bodies']) ? 
    228                                  $params['include_bodies'] : false; 
    229             $this->_decode_bodies  = isset($params['decode_bodies']) ? 
    230                                  $params['decode_bodies']  : false; 
    231             $this->_decode_headers = isset($params['decode_headers']) ? 
    232                                  $params['decode_headers'] : false; 
    233             $this->_rfc822_bodies  = isset($params['rfc_822bodies']) ? 
    234                                  $params['rfc_822bodies']  : false; 
    235             $this->_charset = isset($params['charset']) ? 
    236                                  strtolower($params['charset']) : 'utf-8'; 
    237  
    238             $structure = $this->_decode($this->_header, $this->_body); 
    239             if ($structure === false) { 
    240                 $structure = $this->raiseError($this->_error); 
    241             } 
    242         } 
    243  
    244         return $structure; 
    245     } 
    246  
    247     /** 
    248      * Performs the decoding. Decodes the body string passed to it 
    249      * If it finds certain content-types it will call itself in a 
    250      * recursive fashion 
    251      * 
    252      * @param string Header section 
    253      * @param string Body section 
    254      * @return object Results of decoding process 
    255      * @access private 
    256      */ 
    257     function _decode($headers, $body, $default_ctype = 'text/plain') 
    258     { 
    259         $return = new stdClass; 
    260         $return->headers = array(); 
    261         $headers = $this->_parseHeaders($headers); 
    262  
    263         foreach ($headers as $value) { 
    264             if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) { 
    265                 $return->headers[strtolower($value['name'])]   = array($return->headers[strtolower($value['name'])]); 
    266                 $return->headers[strtolower($value['name'])][] = $value['value']; 
    267  
    268             } elseif (isset($return->headers[strtolower($value['name'])])) { 
    269                 $return->headers[strtolower($value['name'])][] = $value['value']; 
    270  
    271             } else { 
    272                 $return->headers[strtolower($value['name'])] = $value['value']; 
    273             } 
    274         } 
    275  
    276         reset($headers); 
    277         while (list($key, $value) = each($headers)) { 
    278             $headers[$key]['name'] = strtolower($headers[$key]['name']); 
    279             switch ($headers[$key]['name']) { 
    280  
    281                 case 'content-type': 
    282                     $content_type = $this->_parseHeaderValue($headers[$key]['value']); 
    283  
    284                     if (preg_match('/([0-9a-z+.-]+)\/([0-9a-z+.-]+)/i', $content_type['value'], $regs)) { 
    285                         $return->ctype_primary   = $regs[1]; 
    286                         $return->ctype_secondary = $regs[2]; 
    287                     } 
    288  
    289                     if (isset($content_type['other'])) { 
    290                         while (list($p_name, $p_value) = each($content_type['other'])) { 
    291                             $return->ctype_parameters[$p_name] = $p_value; 
    292                         } 
    293                     } 
    294                     break; 
    295  
    296                 case 'content-disposition': 
    297                     $content_disposition = $this->_parseHeaderValue($headers[$key]['value']); 
    298                     $return->disposition   = $content_disposition['value']; 
    299                     if (isset($content_disposition['other'])) { 
    300                         while (list($p_name, $p_value) = each($content_disposition['other'])) { 
    301                             $return->d_parameters[$p_name] = $p_value; 
    302                         } 
    303                     } 
    304                     break; 
    305  
    306                 case 'content-transfer-encoding': 
    307                     $content_transfer_encoding = $this->_parseHeaderValue($headers[$key]['value']); 
    308                     break; 
    309             } 
    310         } 
    311  
    312         if (isset($content_type)) { 
    313             switch (strtolower($content_type['value'])) { 
    314                 case 'text/plain': 
    315                     $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; 
    316                     $charset = isset($return->ctype_parameters['charset']) ? $return->ctype_parameters['charset'] : $this->_charset; 
    317                     $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding, $charset) : $body) : null; 
    318                     break; 
    319  
    320                 case 'text/html': 
    321                     $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; 
    322                     $charset = isset($return->ctype_parameters['charset']) ? $return->ctype_parameters['charset'] : $this->_charset; 
    323                     $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding, $charset) : $body) : null; 
    324                     break; 
    325  
    326                 case 'multipart/parallel': 
    327                 case 'multipart/appledouble': // Appledouble mail 
    328                 case 'multipart/report': // RFC1892 
    329                 case 'multipart/signed': // PGP 
    330                 case 'multipart/digest': 
    331                 case 'multipart/alternative': 
    332                 case 'multipart/related': 
    333                 case 'multipart/mixed': 
    334                     if(!isset($content_type['other']['boundary'])){ 
    335                         $this->_error = 'No boundary found for ' . $content_type['value'] . ' part'; 
    336                         return false; 
    337                     } 
    338  
    339                     $default_ctype = (strtolower($content_type['value']) === 'multipart/digest') ? 'message/rfc822' : 'text/plain'; 
    340  
    341                     $parts = $this->_boundarySplit($body, $content_type['other']['boundary']); 
    342                     for ($i = 0; $i < count($parts); $i++) { 
    343                         list($part_header, $part_body) = $this->_splitBodyHeader($parts[$i]); 
    344                         $part = $this->_decode($part_header, $part_body, $default_ctype); 
    345                         if($part === false) 
    346                             $part = $this->raiseError($this->_error); 
    347                         $return->parts[] = $part; 
    348                     } 
    349                     break; 
    350  
    351                 case 'message/rfc822': 
    352                     if ($this->_rfc822_bodies) { 
    353                         $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; 
    354                         $charset = isset($return->ctype_parameters['charset']) ? $return->ctype_parameters['charset'] : $this->_charset; 
    355                         $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding, $charset) : $body); 
    356                     } 
    357  
    358                     $obj = new Mail_mimeDecode($body); 
    359                     $return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies, 
    360                                                           'decode_bodies'  => $this->_decode_bodies, 
    361                                                           'decode_headers' => $this->_decode_headers)); 
    362                     unset($obj); 
    363                     break; 
    364  
    365                 default: 
    366                     if(!isset($content_transfer_encoding['value'])) 
    367                         $content_transfer_encoding['value'] = '7bit'; 
    368                     // if there is no explicit charset, then don't try to convert to default charset, and make sure that only text mimetypes are converted 
    369                     $charset = (isset($return->ctype_parameters['charset']) && ((isset($return->ctype_primary) && $return->ctype_primary == 'text') || !isset($return->ctype_primary)) )? $return->ctype_parameters['charset']: ''; 
    370                     $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $content_transfer_encoding['value'], $charset) : $body) : null; 
    371                     break; 
    372             } 
    373  
    374         } else { 
    375             $ctype = explode('/', $default_ctype); 
    376             $return->ctype_primary   = $ctype[0]; 
    377             $return->ctype_secondary = $ctype[1]; 
    378             $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body) : $body) : null; 
    379         } 
    380  
    381         return $return; 
    382     } 
    383  
    384     /** 
    385      * Given the output of the above function, this will return an 
    386      * array of references to the parts, indexed by mime number. 
    387      * 
    388      * @param  object $structure   The structure to go through 
    389      * @param  string $mime_number Internal use only. 
    390      * @return array               Mime numbers 
    391      */ 
    392     function &getMimeNumbers(&$structure, $no_refs = false, $mime_number = '', $prepend = '') 
    393     { 
    394         $return = array(); 
    395         if (!empty($structure->parts)) { 
    396             if ($mime_number != '') { 
    397                 $structure->mime_id = $prepend . $mime_number; 
    398                 $return[$prepend . $mime_number] = &$structure; 
    399             } 
    400             for ($i = 0; $i < count($structure->parts); $i++) { 
    401  
    402  
    403                 if (!empty($structure->headers['content-type']) AND substr(strtolower($structure->headers['content-type']), 0, 8) == 'message/') { 
    404                     $prepend      = $prepend . $mime_number . '.'; 
    405                     $_mime_number = ''; 
    406                 } else { 
    407                     $_mime_number = ($mime_number == '' ? $i + 1 : sprintf('%s.%s', $mime_number, $i + 1)); 
    408                 } 
    409  
    410                 $arr = &Mail_mimeDecode::getMimeNumbers($structure->parts[$i], $no_refs, $_mime_number, $prepend); 
    411                 foreach ($arr as $key => $val) { 
    412                     $no_refs ? $return[$key] = '' : $return[$key] = &$arr[$key]; 
    413                 } 
    414             } 
    415         } else { 
    416             if ($mime_number == '') { 
    417                 $mime_number = '1'; 
    418             } 
    419             $structure->mime_id = $prepend . $mime_number; 
    420             $no_refs ? $return[$prepend . $mime_number] = '' : $return[$prepend . $mime_number] = &$structure; 
    421         } 
    422  
    423         return $return; 
    424     } 
    425  
    426     /** 
    427      * Given a string containing a header and body 
    428      * section, this function will split them (at the first 
    429      * blank line) and return them. 
    430      * 
    431      * @param string Input to split apart 
    432      * @return array Contains header and body section 
    433      * @access private 
    434      */ 
    435     function _splitBodyHeader($input) 
    436     { 
    437         if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) { 
    438             return array($match[1], $match[2]); 
    439         } 
    440         $this->_error = 'Could not split header and body'; 
    441         return false; 
    442     } 
    443  
    444     /** 
    445      * Parse headers given in $input and return 
    446      * as assoc array. 
    447      * 
    448      * @param string Headers to parse 
    449      * @return array Contains parsed headers 
    450      * @access private 
    451      */ 
    452     function _parseHeaders($input) 
    453     { 
    454  
    455         if ($input !== '') { 
    456             // Unfold the input 
    457             $input   = preg_replace("/\r?\n/", "\r\n", $input); 
    458             $input   = preg_replace("/\r\n(\t| )+/", ' ', $input); 
    459             $headers = explode("\r\n", trim($input)); 
    460  
    461             foreach ($headers as $value) { 
    462                 $hdr_name = substr($value, 0, $pos = strpos($value, ':')); 
    463                 $hdr_value = substr($value, $pos+1); 
    464                 if($hdr_value[0] == ' ') 
    465                     $hdr_value = substr($hdr_value, 1); 
    466  
    467                 $return[] = array( 
    468                                   'name'  => $hdr_name, 
    469                                   'value' => $this->_decode_headers ? $this->_decodeHeader($hdr_value) : $hdr_value 
    470                                  ); 
    471             } 
    472         } else { 
    473             $return = array(); 
    474         } 
    475  
    476         return $return; 
    477     } 
    478  
    479     /** 
    480      * Function to parse a header value, 
    481      * extract first part, and any secondary 
    482      * parts (after ;) This function is not as 
    483      * robust as it could be. Eg. header comments 
    484      * in the wrong place will probably break it. 
    485      * 
    486      * @param string Header value to parse 
    487      * @return array Contains parsed result 
    488      * @access private 
    489      */ 
    490     function _parseHeaderValue($input) 
    491     { 
    492  
    493         if (($pos = strpos($input, ';')) !== false) { 
    494  
    495             $return['value'] = trim(substr($input, 0, $pos)); 
    496             $input = trim(substr($input, $pos+1)); 
    497  
    498             if (strlen($input) > 0) { 
    499  
    500                 // This splits on a semi-colon, if there's no preceeding backslash 
    501                 // Now works with quoted values; had to glue the \; breaks in PHP 
    502                 // the regex is already bordering on incomprehensible 
    503                 //$splitRegex = '/([^;\'"]*[\'"]([^\'"]*([^\'"]*)*)[\'"][^;\'"]*|([^;]+))(;|$)/'; 
    504                 // simplyfied RegEx - Nokia Mail2 sends boundaries containing ' which break the above regex 
    505                 $splitRegex = '/([^;\'"]*[\'"]([^\'"]*)[\'"][^;\'"]*|([^;]+))(;|$)/'; 
    506                 preg_match_all($splitRegex, $input, $matches); 
    507  
    508                 $parameters = array(); 
    509                 for ($i=0; $i<count($matches[0]); $i++) { 
    510                     $param = $matches[0][$i]; 
    511                     while (substr($param, -2) == '\;') { 
    512                         $param .= $matches[0][++$i]; 
    513                     } 
    514                     $parameters[] = $param; 
    515                 } 
    516  
    517                 for ($i = 0; $i < count($parameters); $i++) { 
    518                     $param_name  = trim(substr($parameters[$i], 0, $pos = strpos($parameters[$i], '=')), "'\";\t\\ "); 
    519                     $param_value = trim(str_replace('\;', ';', substr($parameters[$i], $pos + 1)), "'\";\t\\ "); 
    520                     if (!empty($param_value[0]) && $param_value[0] == '"') { 
    521                         $param_value = substr($param_value, 1, -1); 
    522                     } 
    523                     $return['other'][$param_name] = $param_value; 
    524                     $return['other'][strtolower($param_name)] = $param_value; 
    525                 } 
    526             } 
    527         } else { 
    528             $return['value'] = trim($input); 
    529         } 
    530  
    531         return $return; 
    532     } 
    533  
    534     /** 
    535      * This function splits the input based 
    536      * on the given boundary 
    537      * 
    538      * @param string Input to parse 
    539      * @return array Contains array of resulting mime parts 
    540      * @access private 
    541      */ 
    542     function _boundarySplit($input, $boundary) 
    543     { 
    544         $parts = array(); 
    545  
    546         $bs_possible = substr($boundary, 2, -2); 
    547         $bs_check = '\"' . $bs_possible . '\"'; 
    548  
    549         if ($boundary == $bs_check) { 
    550             $boundary = $bs_possible; 
    551         } 
    552  
    553         $tmp = explode('--' . $boundary, $input); 
    554  
    555         for ($i = 1; $i < count($tmp) - 1; $i++) { 
    556             $parts[] = $tmp[$i]; 
    557         } 
    558  
    559         return $parts; 
    560     } 
    561  
    562     /** 
    563      * Given a header, this function will decode it 
    564      * according to RFC2047. Probably not *exactly* 
    565      * conformant, but it does pass all the given 
    566      * examples (in RFC2047). 
    567      * 
    568      * @param string Input header value to decode 
    569      * @return string Decoded header value 
    570      * @access private 
    571      */ 
    572     function _decodeHeader($input) 
    573     { 
    574         // Remove white space between encoded-words 
    575         $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input); 
    576  
    577         // For each encoded-word... 
    578         while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) { 
    579  
    580             $encoded  = $matches[1]; 
    581             $charset  = $matches[2]; 
    582             $encoding = $matches[3]; 
    583             $text     = $matches[4]; 
    584  
    585             switch (strtolower($encoding)) { 
    586                 case 'b': 
    587                     $text = base64_decode($text); 
    588                     break; 
    589  
    590                 case 'q': 
    591                     $text = str_replace('_', ' ', $text); 
    592                     preg_match_all('/=([a-f0-9]{2})/i', $text, $matches); 
    593                     foreach($matches[1] as $value) 
    594                         $text = str_replace('='.$value, chr(hexdec($value)), $text); 
    595                     break; 
    596             } 
    597  
    598             $input = str_replace($encoded, $this->_fromCharset($charset, $text), $input); 
    599         } 
    600  
    601         return $input; 
    602     } 
    603  
    604     /** 
    605      * Given a body string and an encoding type, 
    606      * this function will decode and return it. 
    607      * 
    608      * @param  string Input body to decode 
    609      * @param  string Encoding type to use. 
    610      * @return string Decoded body 
    611      * @access private 
    612      */ 
    613     function _decodeBody($input, $encoding = '7bit', $charset = '') 
    614     { 
    615         switch (strtolower($encoding)) { 
    616             case '7bit': 
    617                 return $this->_fromCharset($charset, $input);; 
    618                 break; 
    619  
    620             case '8bit': 
    621                 return $this->_fromCharset($charset, $input); 
    622                 break; 
    623  
    624             case 'quoted-printable': 
    625                 return $this->_fromCharset($charset, $this->_quotedPrintableDecode($input)); 
    626                 break; 
    627  
    628             case 'base64': 
    629                 return $this->_fromCharset($charset, base64_decode($input)); 
    630                 break; 
    631  
    632             default: 
    633                 return $input; 
    634         } 
    635     } 
    636  
    637     /** 
    638      * Given a quoted-printable string, this 
    639      * function will decode and return it. 
    640      * 
    641      * @param  string Input body to decode 
    642      * @return string Decoded body 
    643      * @access private 
    644      */ 
    645     function _quotedPrintableDecode($input) 
    646     { 
    647         // Remove soft line breaks 
    648         $input = preg_replace("/=\r?\n/", '', $input); 
    649  
    650         // Replace encoded characters 
    651         $input = preg_replace('/=([a-f0-9]{2})/ie', "chr(hexdec('\\1'))", $input); 
    652  
    653         return $input; 
    654     } 
    655  
    656     /** 
    657      * Checks the input for uuencoded files and returns 
    658      * an array of them. Can be called statically, eg: 
    659      * 
    660      * $files =& Mail_mimeDecode::uudecode($some_text); 
    661      * 
    662      * It will check for the begin 666 ... end syntax 
    663      * however and won't just blindly decode whatever you 
    664      * pass it. 
    665      * 
    666      * @param  string Input body to look for attahcments in 
    667      * @return array  Decoded bodies, filenames and permissions 
    668      * @access public 
    669      * @author Unknown 
    670      */ 
    671     function &uudecode($input) 
    672     { 
    673         // Find all uuencoded sections 
    674         preg_match_all("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $input, $matches); 
    675  
    676         for ($j = 0; $j < count($matches[3]); $j++) { 
    677  
    678             $str      = $matches[3][$j]; 
    679             $filename = $matches[2][$j]; 
    680             $fileperm = $matches[1][$j]; 
    681  
    682             $file = ''; 
    683             $str = preg_split("/\r?\n/", trim($str)); 
    684             $strlen = count($str); 
    685  
    686             for ($i = 0; $i < $strlen; $i++) { 
    687                 $pos = 1; 
    688                 $d = 0; 
    689                 $len=(int)(((ord(substr($str[$i],0,1)) -32) - ' ') & 077); 
    690  
    691                 while (($d + 3 <= $len) AND ($pos + 4 <= strlen($str[$i]))) { 
    692                     $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); 
    693                     $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); 
    694                     $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20); 
    695                     $c3 = (ord(substr($str[$i],$pos+3,1)) ^ 0x20); 
    696                     $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); 
    697  
    698                     $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2)); 
    699  
    700                     $file .= chr(((($c2 - ' ') & 077) << 6) |  (($c3 - ' ') & 077)); 
    701  
    702                     $pos += 4; 
    703                     $d += 3; 
    704                 } 
    705  
    706                 if (($d + 2 <= $len) && ($pos + 3 <= strlen($str[$i]))) { 
    707                     $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); 
    708                     $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); 
    709                     $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20); 
    710                     $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); 
    711  
    712                     $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2)); 
    713  
    714                     $pos += 3; 
    715                     $d += 2; 
    716                 } 
    717  
    718                 if (($d + 1 <= $len) && ($pos + 2 <= strlen($str[$i]))) { 
    719                     $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); 
    720                     $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); 
    721                     $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); 
    722  
    723                 } 
    724             } 
    725             $files[] = array('filename' => $filename, 'fileperm' => $fileperm, 'filedata' => $file); 
    726         } 
    727  
    728         return $files; 
    729     } 
    730  
    731     /** 
    732      * getSendArray() returns the arguments required for Mail::send() 
    733      * used to build the arguments for a mail::send() call 
    734      * 
    735      * Usage: 
    736      * $mailtext = Full email (for example generated by a template) 
    737      * $decoder = new Mail_mimeDecode($mailtext); 
    738      * $parts =  $decoder->getSendArray(); 
    739      * if (!PEAR::isError($parts) { 
    740      *     list($recipents,$headers,$body) = $parts; 
    741      *     $mail = Mail::factory('smtp'); 
    742      *     $mail->send($recipents,$headers,$body); 
    743      * } else { 
    744      *     echo $parts->message; 
    745      * } 
    746      * @return mixed   array of recipeint, headers,body or Pear_Error 
    747      * @access public 
    748      * @author Alan Knowles <alan@akbkhome.com> 
    749      */ 
    750     function getSendArray() 
    751     { 
    752         // prevent warning if this is not set 
    753         $this->_decode_headers = FALSE; 
    754         $headerlist =$this->_parseHeaders($this->_header); 
    755         $to = ""; 
    756         if (!$headerlist) { 
    757             return $this->raiseError("Message did not contain headers"); 
    758         } 
    759         foreach($headerlist as $item) { 
    760             $header[$item['name']] = $item['value']; 
    761             switch (strtolower($item['name'])) { 
    762                 case "to": 
    763                 case "cc": 
    764                 case "bcc": 
    765                     $to .= ",".$item['value']; 
    766                 default: 
    767                    break; 
    768             } 
    769         } 
    770         if ($to == "") { 
    771             return $this->raiseError("Message did not contain any recipents"); 
    772         } 
    773         $to = substr($to,1); 
    774         return array($to,$header,$this->_body); 
    775     } 
    776  
    777     /** 
    778      * Returns a xml copy of the output of 
    779      * Mail_mimeDecode::decode. Pass the output in as the 
    780      * argument. This function can be called statically. Eg: 
    781      * 
    782      * $output = $obj->decode(); 
    783      * $xml    = Mail_mimeDecode::getXML($output); 
    784      * 
    785      * The DTD used for this should have been in the package. Or 
    786      * alternatively you can get it from cvs, or here: 
    787      * http://www.phpguru.org/xmail/xmail.dtd. 
    788      * 
    789      * @param  object Input to convert to xml. This should be the 
    790      *                output of the Mail_mimeDecode::decode function 
    791      * @return string XML version of input 
    792      * @access public 
    793      */ 
    794     function getXML($input) 
    795     { 
    796         $crlf    =  "\r\n"; 
    797         $output  = '<?xml version=\'1.0\'?>' . $crlf . 
     104        /** 
     105         * The raw email to decode 
     106         * 
     107         * @var    string 
     108         * @access private 
     109         */ 
     110        var $_input; 
     111 
     112        /** 
     113         * The header part of the input 
     114         * 
     115         * @var    string 
     116         * @access private 
     117         */ 
     118        var $_header; 
     119 
     120        /** 
     121         * The body part of the input 
     122         * 
     123         * @var    string 
     124         * @access private 
     125         */ 
     126        var $_body; 
     127 
     128        /** 
     129         * If an error occurs, this is used to store the message 
     130         * 
     131         * @var    string 
     132         * @access private 
     133         */ 
     134        var $_error; 
     135 
     136        /** 
     137         * Flag to determine whether to include bodies in the 
     138         * returned object. 
     139         * 
     140         * @var    boolean 
     141         * @access private 
     142         */ 
     143        var $_include_bodies; 
     144 
     145        /** 
     146         * Flag to determine whether to decode bodies 
     147         * 
     148         * @var    boolean 
     149         * @access private 
     150         */ 
     151        var $_decode_bodies; 
     152 
     153        /** 
     154         * Flag to determine whether to decode headers 
     155         * 
     156         * @var    boolean 
     157         * @access private 
     158         */ 
     159        var $_decode_headers; 
     160 
     161        /** 
     162         * Flag to determine whether to include attached messages 
     163         * as body in the returned object. Depends on $_include_bodies 
     164         * 
     165         * @var    boolean 
     166         * @access private 
     167         */ 
     168        var $_rfc822_bodies; 
     169 
     170        /** 
     171         * Constructor. 
     172         * 
     173         * Sets up the object, initialise the variables, and splits and 
     174         * stores the header and body of the input. 
     175         * 
     176         * @param string The input to decode 
     177         * @access public 
     178         */ 
     179        function Mail_mimeDecode($input, $deprecated_linefeed = '') 
     180        { 
     181                list($header, $body)   = $this->_splitBodyHeader($input); 
     182 
     183                $this->_input          = $input; 
     184                $this->_header         = $header; 
     185                $this->_body           = $body; 
     186                $this->_decode_bodies  = false; 
     187                $this->_include_bodies = true; 
     188                $this->_rfc822_bodies  = false; 
     189        } 
     190 
     191        /** 
     192         * Begins the decoding process. If called statically 
     193         * it will create an object and call the decode() method 
     194         * of it. 
     195         * 
     196         * @param array An array of various parameters that determine 
     197         *              various things: 
     198         *              include_bodies - Whether to include the body in the returned 
     199         *                               object. 
     200         *              decode_bodies  - Whether to decode the bodies 
     201         *                               of the parts. (Transfer encoding) 
     202         *              decode_headers - Whether to decode headers 
     203         *              input          - If called statically, this will be treated 
     204         *                               as the input 
     205         *              charset        - convert all data to this charset 
     206         * @return object Decoded results 
     207         * @access public 
     208         */ 
     209        function decode($params = null) 
     210        { 
     211                // determine if this method has been called statically 
     212                $isStatic = !(isset($this) && get_class($this) == __CLASS__); 
     213 
     214                // Have we been called statically? 
     215                // If so, create an object and pass details to that. 
     216                if ($isStatic AND isset($params['input'])) { 
     217 
     218                        $obj = new Mail_mimeDecode($params['input']); 
     219                        $structure = $obj->decode($params); 
     220 
     221                        // Called statically but no input 
     222                } elseif ($isStatic) { 
     223                        return $this->raiseError('Called statically and no input given'); 
     224 
     225                        // Called via an object 
     226                } else { 
     227                        $this->_include_bodies = isset($params['include_bodies']) ? 
     228                                $params['include_bodies'] : false; 
     229                        $this->_decode_bodies  = isset($params['decode_bodies']) ? 
     230                                $params['decode_bodies']  : false; 
     231                        $this->_decode_headers = isset($params['decode_headers']) ? 
     232                                $params['decode_headers'] : false; 
     233                        $this->_rfc822_bodies  = isset($params['rfc_822bodies']) ? 
     234                                $params['rfc_822bodies']  : false; 
     235                        $this->_charset = isset($params['charset']) ? 
     236                                strtolower($params['charset']) : 'utf-8'; 
     237                          
     238                        $structure = $this->_decode($this->_header, $this->_body); 
     239                        if ($structure === false) { 
     240                                $structure = $this->raiseError($this->_error); 
     241                        } 
     242                } 
     243 
     244                return $structure; 
     245        } 
     246 
     247        /** 
     248         * Performs the decoding. Decodes the body string passed to it 
     249         * If it finds certain content-types it will call itself in a 
     250         * recursive fashion 
     251         * 
     252         * @param string Header section 
     253         * @param string Body section 
     254         * @return object Results of decoding process 
     255         * @access private 
     256         */ 
     257        function _decode($headers, $body, $default_ctype = 'text/plain') 
     258        { 
     259                $return = new stdClass; 
     260                $return->headers = array(); 
     261                $headers = $this->_parseHeaders($headers); 
     262 
     263                foreach ($headers as $value) { 
     264                        if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) { 
     265                                $return->headers[strtolower($value['name'])]   = array($return->headers[strtolower($value['name'])]); 
     266                                $return->headers[strtolower($value['name'])][] = $value['value']; 
     267 
     268                        } elseif (isset($return->headers[strtolower($value['name'])])) { 
     269                                $return->headers[strtolower($value['name'])][] = $value['value']; 
     270 
     271                        } else { 
     272                                $return->headers[strtolower($value['name'])] = $value['value']; 
     273                        } 
     274                } 
     275 
     276                reset($headers); 
     277                while (list($key, $value) = each($headers)) { 
     278                        $headers[$key]['name'] = strtolower($headers[$key]['name']); 
     279                        switch ($headers[$key]['name']) { 
     280 
     281                                case 'content-type': 
     282                                        $content_type = $this->_parseHeaderValue($headers[$key]['value']); 
     283 
     284                                        if (preg_match('/([0-9a-z+.-]+)\/([0-9a-z+.-]+)/i', $content_type['value'], $regs)) { 
     285                                                $return->ctype_primary   = $regs[1]; 
     286                                                $return->ctype_secondary = $regs[2]; 
     287                                        } 
     288 
     289                                        if (isset($content_type['other'])) { 
     290                                                while (list($p_name, $p_value) = each($content_type['other'])) { 
     291                                                        $return->ctype_parameters[$p_name] = $p_value; 
     292                                                } 
     293                                        } 
     294                                        break; 
     295 
     296                                case 'content-disposition': 
     297                                        $content_disposition = $this->_parseHeaderValue($headers[$key]['value']); 
     298                                        $return->disposition   = $content_disposition['value']; 
     299                                        if (isset($content_disposition['other'])) { 
     300                                                while (list($p_name, $p_value) = each($content_disposition['other'])) { 
     301                                                        $return->d_parameters[$p_name] = $p_value; 
     302                                                } 
     303                                        } 
     304                                        break; 
     305 
     306                                case 'content-transfer-encoding': 
     307                                        $content_transfer_encoding = $this->_parseHeaderValue($headers[$key]['value']); 
     308                                        break; 
     309                        } 
     310                } 
     311 
     312                if (isset($content_type)) { 
     313                        switch (strtolower($content_type['value'])) { 
     314                                case 'text/plain': 
     315                                        $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; 
     316                                        $charset = isset($return->ctype_parameters['charset']) ? $return->ctype_parameters['charset'] : $this->_charset; 
     317                                        $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding, $charset) : $body) : null; 
     318                                        break; 
     319 
     320                                case 'text/html': 
     321                                        $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; 
     322                                        $charset = isset($return->ctype_parameters['charset']) ? $return->ctype_parameters['charset'] : $this->_charset; 
     323                                        $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding, $charset) : $body) : null; 
     324                                        break; 
     325 
     326                                case 'multipart/parallel': 
     327                                case 'multipart/appledouble': // Appledouble mail 
     328                                case 'multipart/report': // RFC1892 
     329                                case 'multipart/signed': // PGP 
     330                                case 'multipart/digest': 
     331                                case 'multipart/alternative': 
     332                                case 'multipart/related': 
     333                                case 'multipart/mixed': 
     334                                        if(!isset($content_type['other']['boundary'])){ 
     335                                                $this->_error = 'No boundary found for ' . $content_type['value'] . ' part'; 
     336                                                return false; 
     337                                        } 
     338 
     339                                        $default_ctype = (strtolower($content_type['value']) === 'multipart/digest') ? 'message/rfc822' : 'text/plain'; 
     340 
     341                                        $parts = $this->_boundarySplit($body, $content_type['other']['boundary']); 
     342                                        for ($i = 0; $i < count($parts); $i++) { 
     343                                                list($part_header, $part_body) = $this->_splitBodyHeader($parts[$i]); 
     344                                                $part = $this->_decode($part_header, $part_body, $default_ctype); 
     345                                                if($part === false) 
     346                                                $part = $this->raiseError($this->_error); 
     347                                                $return->parts[] = $part; 
     348                                        } 
     349                                        break; 
     350 
     351                                case 'message/rfc822': 
     352                                        if ($this->_rfc822_bodies) { 
     353                                                $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; 
     354                                                $charset = isset($return->ctype_parameters['charset']) ? $return->ctype_parameters['charset'] : $this->_charset; 
     355                                                $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding, $charset) : $body); 
     356                                        } 
     357 
     358                                        $obj = new Mail_mimeDecode($body); 
     359                                        $return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies, 
     360                                                'decode_bodies'  => $this->_decode_bodies, 
     361                                                'decode_headers' => $this->_decode_headers)); 
     362                                        unset($obj); 
     363                                        break; 
     364 
     365                                default: 
     366                                        if(!isset($content_transfer_encoding['value'])) 
     367                                                $content_transfer_encoding['value'] = '7bit'; 
     368                                         
     369                                        // if there is no explicit charset, then don't try to convert to default charset, and make sure that only text mimetypes are converted 
     370                                        $charset = (isset($return->ctype_parameters['charset']) && ((isset($return->ctype_primary) && $return->ctype_primary == 'text') || !isset($return->ctype_primary)) ) ? $return->ctype_parameters['charset']: ''; 
     371                                        $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $content_transfer_encoding['value'], $charset) : $body) : null; 
     372                                        break; 
     373                        } 
     374 
     375                } else { 
     376                        $ctype = explode('/', $default_ctype); 
     377                        $return->ctype_primary   = $ctype[0]; 
     378                        $return->ctype_secondary = $ctype[1]; 
     379                        $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body) : $body) : null; 
     380                } 
     381 
     382                return $return; 
     383        } 
     384 
     385        /** 
     386         * Given the output of the above function, this will return an 
     387         * array of references to the parts, indexed by mime number. 
     388         * 
     389         * @param  object $structure   The structure to go through 
     390         * @param  string $mime_number Internal use only. 
     391         * @return array               Mime numbers 
     392         */ 
     393        function &getMimeNumbers(&$structure, $no_refs = false, $mime_number = '', $prepend = '') 
     394        { 
     395                $return = array(); 
     396                if (!empty($structure->parts)) { 
     397                        if ($mime_number != '') { 
     398                                $structure->mime_id = $prepend . $mime_number; 
     399                                $return[$prepend . $mime_number] = &$structure; 
     400                        } 
     401                        for ($i = 0; $i < count($structure->parts); $i++) { 
     402                                if (!empty($structure->headers['content-type']) AND substr(strtolower($structure->headers['content-type']), 0, 8) == 'message/') { 
     403                                        $prepend      = $prepend . $mime_number . '.'; 
     404                                        $_mime_number = ''; 
     405                                } else { 
     406                                        $_mime_number = ($mime_number == '' ? $i + 1 : sprintf('%s.%s', $mime_number, $i + 1)); 
     407                                } 
     408 
     409                                $arr = &Mail_mimeDecode::getMimeNumbers($structure->parts[$i], $no_refs, $_mime_number, $prepend); 
     410                                foreach ($arr as $key => $val) { 
     411                                        $no_refs ? $return[$key] = '' : $return[$key] = &$arr[$key]; 
     412                                } 
     413                        } 
     414                } else { 
     415                        if ($mime_number == '') { 
     416                                $mime_number = '1'; 
     417                        } 
     418                        $structure->mime_id = $prepend . $mime_number; 
     419                        $no_refs ? $return[$prepend . $mime_number] = '' : $return[$prepend . $mime_number] = &$structure; 
     420                } 
     421 
     422                return $return; 
     423        } 
     424 
     425        /** 
     426         * Given a string containing a header and body 
     427         * section, this function will split them (at the first 
     428         * blank line) and return them. 
     429         * 
     430         * @param string Input to split apart 
     431         * @return array Contains header and body section 
     432         * @access private 
     433         */ 
     434        function _splitBodyHeader($input) 
     435        { 
     436                if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) { 
     437                        return array($match[1], $match[2]); 
     438                } 
     439                $this->_error = 'Could not split header and body'; 
     440                return false; 
     441        } 
     442 
     443        /** 
     444         * Parse headers given in $input and return 
     445         * as assoc array. 
     446         * 
     447         * @param string Headers to parse 
     448         * @return array Contains parsed headers 
     449         * @access private 
     450         */ 
     451        function _parseHeaders($input) 
     452        { 
     453 
     454                if ($input !== '') { 
     455                        // Unfold the input 
     456                        $input   = preg_replace("/\r?\n/", "\r\n", $input); 
     457                        $input   = preg_replace("/\r\n(\t| )+/", ' ', $input); 
     458                        $headers = explode("\r\n", trim($input)); 
     459 
     460                        foreach ($headers as $value) { 
     461                                $hdr_name = substr($value, 0, $pos = strpos($value, ':')); 
     462                                $hdr_value = substr($value, $pos+1); 
     463                                if($hdr_value[0] == ' ') 
     464                                        $hdr_value = substr($hdr_value, 1); 
     465 
     466                                $return[] = array( 
     467                                        'name'  => $hdr_name, 
     468                                        'value' => $this->_decode_headers ? $this->_decodeHeader($hdr_value) : $hdr_value 
     469                                ); 
     470                        } 
     471                } else { 
     472                        $return = array(); 
     473                } 
     474 
     475                return $return; 
     476        } 
     477 
     478        /** 
     479         * Function to parse a header value, 
     480         * extract first part, and any secondary 
     481         * parts (after ;) This function is not as 
     482         * robust as it could be. Eg. header comments 
     483         * in the wrong place will probably break it. 
     484         * 
     485         * @param string Header value to parse 
     486         * @return array Contains parsed result 
     487         * @access private 
     488         */ 
     489        function _parseHeaderValue($input) 
     490        { 
     491                if (($pos = strpos($input, ';')) !== false) { 
     492                        $return['value'] = trim(substr($input, 0, $pos)); 
     493                        $input = trim(substr($input, $pos+1)); 
     494 
     495                        if (strlen($input) > 0) { 
     496                                // This splits on a semi-colon, if there's no preceeding backslash 
     497                                // Now works with quoted values; had to glue the \; breaks in PHP 
     498                                // the regex is already bordering on incomprehensible 
     499                                //$splitRegex = '/([^;\'"]*[\'"]([^\'"]*([^\'"]*)*)[\'"][^;\'"]*|([^;]+))(;|$)/'; 
     500                                // simplyfied RegEx - Nokia Mail2 sends boundaries containing ' which break the above regex 
     501                                $splitRegex = '/([^;\'"]*[\'"]([^\'"]*)[\'"][^;\'"]*|([^;]+))(;|$)/'; 
     502                                preg_match_all($splitRegex, $input, $matches); 
     503 
     504                                $parameters = array(); 
     505                                for ($i=0; $i<count($matches[0]); $i++) { 
     506                                        $param = $matches[0][$i]; 
     507                                        while (substr($param, -2) == '\;') { 
     508                                                $param .= $matches[0][++$i]; 
     509                                        } 
     510                                        $parameters[] = $param; 
     511                                } 
     512 
     513                                for ($i = 0; $i < count($parameters); $i++) { 
     514                                        $param_name  = trim(substr($parameters[$i], 0, $pos = strpos($parameters[$i], '=')), "'\";\t\\ "); 
     515                                        $param_value = trim(str_replace('\;', ';', substr($parameters[$i], $pos + 1)), "'\";\t\\ "); 
     516                                        if (!empty($param_value[0]) && $param_value[0] == '"') { 
     517                                                $param_value = substr($param_value, 1, -1); 
     518                                        } 
     519                                        $return['other'][$param_name] = $param_value; 
     520                                        $return['other'][strtolower($param_name)] = $param_value; 
     521                                } 
     522                        } 
     523                } else { 
     524                        $return['value'] = trim($input); 
     525                } 
     526 
     527                return $return; 
     528        } 
     529 
     530        /** 
     531         * This function splits the input based 
     532         * on the given boundary 
     533         * 
     534         * @param string Input to parse 
     535         * @return array Contains array of resulting mime parts 
     536         * @access private 
     537         */ 
     538        function _boundarySplit($input, $boundary) 
     539        { 
     540                $parts = array(); 
     541 
     542                $bs_possible = substr($boundary, 2, -2); 
     543                $bs_check = '\"' . $bs_possible . '\"'; 
     544 
     545                if ($boundary == $bs_check) { 
     546                        $boundary = $bs_possible; 
     547                } 
     548 
     549                $tmp = explode('--' . $boundary, $input); 
     550 
     551                for ($i = 1; $i < count($tmp) - 1; $i++) { 
     552                        $parts[] = $tmp[$i]; 
     553                } 
     554 
     555                return $parts; 
     556        } 
     557 
     558        /** 
     559         * Given a header, this function will decode it 
     560         * according to RFC2047. Probably not *exactly* 
     561         * conformant, but it does pass all the given 
     562         * examples (in RFC2047). 
     563         * 
     564         * @param string Input header value to decode 
     565         * @return string Decoded header value 
     566         * @access private 
     567         */ 
     568        function _decodeHeader($input) 
     569        { 
     570                // Remove white space between encoded-words 
     571                $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input); 
     572 
     573                // For each encoded-word... 
     574                while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) { 
     575                        $encoded  = $matches[1]; 
     576                        $charset  = $matches[2]; 
     577                        $encoding = $matches[3]; 
     578                        $text     = $matches[4]; 
     579 
     580                        switch (strtolower($encoding)) { 
     581                                case 'b': 
     582                                        $text = base64_decode($text); 
     583                                        break; 
     584 
     585                                case 'q': 
     586                                        $text = str_replace('_', ' ', $text); 
     587                                        preg_match_all('/=([a-f0-9]{2})/i', $text, $matches); 
     588                                        foreach($matches[1] as $value) 
     589                                        $text = str_replace('='.$value, chr(hexdec($value)), $text); 
     590                                        break; 
     591                        } 
     592 
     593                        $input = str_replace($encoded, $this->_fromCharset($charset, $text), $input); 
     594                } 
     595 
     596                return $input; 
     597        } 
     598 
     599        /** 
     600         * Given a body string and an encoding type, 
     601         * this function will decode and return it. 
     602         * 
     603         * @param  string Input body to decode 
     604         * @param  string Encoding type to use. 
     605         * @return string Decoded body 
     606         * @access private 
     607         */ 
     608        function _decodeBody($input, $encoding = '7bit', $charset = '') 
     609        { 
     610                switch (strtolower($encoding)) { 
     611                        case '7bit': 
     612                                return $this->_fromCharset($charset, $input);; 
     613                                break; 
     614 
     615                        case '8bit': 
     616                                return $this->_fromCharset($charset, $input); 
     617                                break; 
     618 
     619                        case 'quoted-printable': 
     620                                return $this->_fromCharset($charset, $this->_quotedPrintableDecode($input)); 
     621                                break; 
     622 
     623                        case 'base64': 
     624                                return $this->_fromCharset($charset, base64_decode($input)); 
     625                                break; 
     626 
     627                        default: 
     628                                return $input; 
     629                } 
     630        } 
     631 
     632        /** 
     633         * Given a quoted-printable string, this 
     634         * function will decode and return it. 
     635         * 
     636         * @param  string Input body to decode 
     637         * @return string Decoded body 
     638         * @access private 
     639         */ 
     640        function _quotedPrintableDecode($input) 
     641        { 
     642                // Remove soft line breaks 
     643                $input = preg_replace("/=\r?\n/", '', $input); 
     644 
     645                // Replace encoded characters 
     646                $input = preg_replace('/=([a-f0-9]{2})/ie', "chr(hexdec('\\1'))", $input); 
     647 
     648                return $input; 
     649        } 
     650 
     651        /** 
     652         * Checks the input for uuencoded files and returns 
     653         * an array of them. Can be called statically, eg: 
     654         * 
     655         * $files =& Mail_mimeDecode::uudecode($some_text); 
     656         * 
     657         * It will check for the begin 666 ... end syntax 
     658         * however and won't just blindly decode whatever you 
     659         * pass it. 
     660         * 
     661         * @param  string Input body to look for attahcments in 
     662         * @return array  Decoded bodies, filenames and permissions 
     663         * @access public 
     664         * @author Unknown 
     665         */ 
     666        function &uudecode($input) 
     667        { 
     668                // Find all uuencoded sections 
     669                preg_match_all("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $input, $matches); 
     670 
     671                for ($j = 0; $j < count($matches[3]); $j++) { 
     672                        $str      = $matches[3][$j]; 
     673                        $filename = $matches[2][$j]; 
     674                        $fileperm = $matches[1][$j]; 
     675 
     676                        $file = ''; 
     677                        $str = preg_split("/\r?\n/", trim($str)); 
     678                        $strlen = count($str); 
     679 
     680                        for ($i = 0; $i < $strlen; $i++) { 
     681                                $pos = 1; 
     682                                $d = 0; 
     683                                $len=(int)(((ord(substr($str[$i],0,1)) -32) - ' ') & 077); 
     684 
     685                                while (($d + 3 <= $len) AND ($pos + 4 <= strlen($str[$i]))) { 
     686                                        $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); 
     687                                        $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); 
     688                                        $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20); 
     689                                        $c3 = (ord(substr($str[$i],$pos+3,1)) ^ 0x20); 
     690                                        $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); 
     691 
     692                                        $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2)); 
     693 
     694                                        $file .= chr(((($c2 - ' ') & 077) << 6) |  (($c3 - ' ') & 077)); 
     695 
     696                                        $pos += 4; 
     697                                        $d += 3; 
     698                                } 
     699 
     700                                if (($d + 2 <= $len) && ($pos + 3 <= strlen($str[$i]))) { 
     701                                        $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); 
     702                                        $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); 
     703                                        $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20); 
     704                                        $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); 
     705 
     706                                        $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2)); 
     707 
     708                                        $pos += 3; 
     709                                        $d += 2; 
     710                                } 
     711 
     712                                if (($d + 1 <= $len) && ($pos + 2 <= strlen($str[$i]))) { 
     713                                        $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); 
     714                                        $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); 
     715                                        $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); 
     716                                } 
     717                        } 
     718                        $files[] = array('filename' => $filename, 'fileperm' => $fileperm, 'filedata' => $file); 
     719                } 
     720 
     721                return $files; 
     722        } 
     723 
     724        /** 
     725         * getSendArray() returns the arguments required for Mail::send() 
     726         * used to build the arguments for a mail::send() call 
     727         * 
     728         * Usage: 
     729         * $mailtext = Full email (for example generated by a template) 
     730         * $decoder = new Mail_mimeDecode($mailtext); 
     731         * $parts =  $decoder->getSendArray(); 
     732         * if (!PEAR::isError($parts) { 
     733         *     list($recipents,$headers,$body) = $parts; 
     734         *     $mail = Mail::factory('smtp'); 
     735         *     $mail->send($recipents,$headers,$body); 
     736         * } else { 
     737         *     echo $parts->message; 
     738         * } 
     739         * @return mixed   array of recipeint, headers,body or Pear_Error 
     740         * @access public 
     741         * @author Alan Knowles <alan@akbkhome.com> 
     742         */ 
     743        function getSendArray() 
     744        { 
     745                // prevent warning if this is not set 
     746                $this->_decode_headers = FALSE; 
     747                $headerlist =$this->_parseHeaders($this->_header); 
     748                $to = ""; 
     749                if (!$headerlist) { 
     750                        return $this->raiseError("Message did not contain headers"); 
     751                } 
     752                foreach($headerlist as $item) { 
     753                        $header[$item['name']] = $item['value']; 
     754                        switch (strtolower($item['name'])) { 
     755                                case "to": 
     756                                case "cc": 
     757                                case "bcc": 
     758                                        $to .= ",".$item['value']; 
     759                                default: 
     760                                        break; 
     761                        } 
     762                } 
     763                if ($to == "") { 
     764                        return $this->raiseError("Message did not contain any recipents"); 
     765                } 
     766                $to = substr($to,1); 
     767                return array($to,$header,$this->_body); 
     768        } 
     769 
     770        /** 
     771         * Returns a xml copy of the output of 
     772         * Mail_mimeDecode::decode. Pass the output in as the 
     773         * argument. This function can be called statically. Eg: 
     774         * 
     775         * $output = $obj->decode(); 
     776         * $xml    = Mail_mimeDecode::getXML($output); 
     777         * 
     778         * The DTD used for this should have been in the package. Or 
     779         * alternatively you can get it from cvs, or here: 
     780         * http://www.phpguru.org/xmail/xmail.dtd. 
     781         * 
     782         * @param  object Input to convert to xml. This should be the 
     783         *                output of the Mail_mimeDecode::decode function 
     784         * @return string XML version of input 
     785         * @access public 
     786         */ 
     787        function getXML($input) 
     788        { 
     789                $crlf    =  "\r\n"; 
     790                $output  = '<?xml version=\'1.0\'?>' . $crlf . 
    798791                   '<!DOCTYPE email SYSTEM "http://www.phpguru.org/xmail/xmail.dtd">' . $crlf . 
    799792                   '<email>' . $crlf . 
    800                    Mail_mimeDecode::_getXML($input) . 
     793                Mail_mimeDecode::_getXML($input) . 
    801794                   '</email>'; 
    802795 
    803         return $output; 
    804     } 
    805  
    806     /** 
    807      * Function that does the actual conversion to xml. Does a single 
    808      * mimepart at a time. 
    809      * 
    810      * @param  object  Input to convert to xml. This is a mimepart object. 
    811      *                 It may or may not contain subparts. 
    812      * @param  integer Number of tabs to indent 
    813      * @return string  XML version of input 
    814      * @access private 
    815      */ 
    816     function _getXML($input, $indent = 1) 
    817     { 
    818         $htab    =  "\t"; 
    819         $crlf    =  "\r\n"; 
    820         $output  =  ''; 
    821         $headers = @(array)$input->headers; 
    822  
    823         foreach ($headers as $hdr_name => $hdr_value) { 
    824  
    825             // Multiple headers with this name 
    826             if (is_array($headers[$hdr_name])) { 
    827                 for ($i = 0; $i < count($hdr_value); $i++) { 
    828                     $output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value[$i], $indent); 
    829                 } 
    830  
    831             // Only one header of this sort 
    832             } else { 
    833                 $output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value, $indent); 
    834             } 
    835         } 
    836  
    837         if (!empty($input->parts)) { 
    838             for ($i = 0; $i < count($input->parts); $i++) { 
    839                 $output .= $crlf . str_repeat($htab, $indent) . '<mimepart>' . $crlf . 
    840                            Mail_mimeDecode::_getXML($input->parts[$i], $indent+1) . 
    841                            str_repeat($htab, $indent) . '</mimepart>' . $crlf; 
    842             } 
    843         } elseif (isset($input->body)) { 
    844             $output .= $crlf . str_repeat($htab, $indent) . '<body><![CDATA[' . 
    845                        $input->body . ']]></body>' . $crlf; 
    846         } 
    847  
    848         return $output; 
    849     } 
    850  
    851     /** 
    852      * Helper function to _getXML(). Returns xml of a header. 
    853      * 
    854      * @param  string  Name of header 
    855      * @param  string  Value of header 
    856      * @param  integer Number of tabs to indent 
    857      * @return string  XML version of input 
    858      * @access private 
    859      */ 
    860     function _getXML_helper($hdr_name, $hdr_value, $indent) 
    861     { 
    862         $htab   = "\t"; 
    863         $crlf   = "\r\n"; 
    864         $return = ''; 
    865  
    866         $new_hdr_value = ($hdr_name != 'received') ? Mail_mimeDecode::_parseHeaderValue($hdr_value) : array('value' => $hdr_value); 
    867         $new_hdr_name  = str_replace(' ', '-', ucwords(str_replace('-', ' ', $hdr_name))); 
    868  
    869         // Sort out any parameters 
    870         if (!empty($new_hdr_value['other'])) { 
    871             foreach ($new_hdr_value['other'] as $paramname => $paramvalue) { 
    872                 $params[] = str_repeat($htab, $indent) . $htab . '<parameter>' . $crlf . 
    873                             str_repeat($htab, $indent) . $htab . $htab . '<paramname>' . htmlspecialchars($paramname) . '</paramname>' . $crlf . 
    874                             str_repeat($htab, $indent) . $htab . $htab . '<paramvalue>' . htmlspecialchars($paramvalue) . '</paramvalue>' . $crlf . 
    875                             str_repeat($htab, $indent) . $htab . '</parameter>' . $crlf; 
    876             } 
    877  
    878             $params = implode('', $params); 
    879         } else { 
    880             $params = ''; 
    881         } 
    882  
    883         $return = str_repeat($htab, $indent) . '<header>' . $crlf . 
    884                   str_repeat($htab, $indent) . $htab . '<headername>' . htmlspecialchars($new_hdr_name) . '</headername>' . $crlf . 
    885                   str_repeat($htab, $indent) . $htab . '<headervalue>' . htmlspecialchars($new_hdr_value['value']) . '</headervalue>' . $crlf . 
    886                   $params . 
    887                   str_repeat($htab, $indent) . '</header>' . $crlf; 
    888  
    889         return $return; 
    890     } 
    891  
    892     /** 
    893      * Z-Push helper to decode text 
    894      * 
    895      * @param  string  current charset of input 
    896      * @param  string  input 
    897      * @return string  XML version of input 
    898      * @access private 
    899      */ 
    900     function _fromCharset($charset, $input) { 
    901         if($charset == '' || (strtolower($charset) == $this->_charset)) 
    902             return $input; 
    903  
    904         return @iconv($charset, $this->_charset. "//TRANSLIT", $input); 
    905     } 
    906  
    907     /** 
    908      * Z-Push helper for error logging 
    909      * removing PEAR dependency 
    910      * 
    911      * @param  string  debug message 
    912      * @return boolean always false as there was an error 
    913      * @access private 
    914      */ 
    915     function raiseError($message) { 
    916         debugLog("mimeDecode error: ". $message); 
    917         return false; 
    918     } 
     796                return $output; 
     797        } 
     798 
     799        /** 
     800         * Function that does the actual conversion to xml. Does a single 
     801         * mimepart at a time. 
     802         * 
     803         * @param  object  Input to convert to xml. This is a mimepart object. 
     804         *                 It may or may not contain subparts. 
     805         * @param  integer Number of tabs to indent 
     806         * @return string  XML version of input 
     807         * @access private 
     808         */ 
     809        function _getXML($input, $indent = 1) 
     810        { 
     811                $htab    =  "\t"; 
     812                $crlf    =  "\r\n"; 
     813                $output  =  ''; 
     814                $headers = @(array)$input->headers; 
     815 
     816                foreach ($headers as $hdr_name => $hdr_value) { 
     817                        // Multiple headers with this name 
     818                        if (is_array($headers[$hdr_name])) { 
     819                                for ($i = 0; $i < count($hdr_value); $i++) { 
     820                                        $output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value[$i], $indent); 
     821                                } 
     822 
     823                                // Only one header of this sort 
     824                        } else { 
     825                                $output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value, $indent); 
     826                        } 
     827                } 
     828 
     829                if (!empty($input->parts)) { 
     830                        for ($i = 0; $i < count($input->parts); $i++) { 
     831                                $output .= $crlf . str_repeat($htab, $indent) . '<mimepart>' . $crlf . 
     832                                Mail_mimeDecode::_getXML($input->parts[$i], $indent+1) . 
     833                                str_repeat($htab, $indent) . '</mimepart>' . $crlf; 
     834                        } 
     835                } elseif (isset($input->body)) { 
     836                        $output .= $crlf . str_repeat($htab, $indent) . '<body><![CDATA[' . 
     837                        $input->body . ']]></body>' . $crlf; 
     838                } 
     839 
     840                return $output; 
     841        } 
     842 
     843        /** 
     844         * Helper function to _getXML(). Returns xml of a header. 
     845         * 
     846         * @param  string  Name of header 
     847         * @param  string  Value of header 
     848         * @param  integer Number of tabs to indent 
     849         * @return string  XML version of input 
     850         * @access private 
     851         */ 
     852        function _getXML_helper($hdr_name, $hdr_value, $indent) 
     853        { 
     854                $htab   = "\t"; 
     855                $crlf   = "\r\n"; 
     856                $return = ''; 
     857 
     858                $new_hdr_value = ($hdr_name != 'received') ? Mail_mimeDecode::_parseHeaderValue($hdr_value) : array('value' => $hdr_value); 
     859                $new_hdr_name  = str_replace(' ', '-', ucwords(str_replace('-', ' ', $hdr_name))); 
     860 
     861                // Sort out any parameters 
     862                if (!empty($new_hdr_value['other'])) { 
     863                        foreach ($new_hdr_value['other'] as $paramname => $paramvalue) { 
     864                                $params[] = str_repeat($htab, $indent) . $htab . '<parameter>' . $crlf . 
     865                                str_repeat($htab, $indent) . $htab . $htab . '<paramname>' . htmlspecialchars($paramname) . '</paramname>' . $crlf . 
     866                                str_repeat($htab, $indent) . $htab . $htab . '<paramvalue>' . htmlspecialchars($paramvalue) . '</paramvalue>' . $crlf . 
     867                                str_repeat($htab, $indent) . $htab . '</parameter>' . $crlf; 
     868                        } 
     869 
     870                        $params = implode('', $params); 
     871                } else { 
     872                        $params = ''; 
     873                } 
     874 
     875                $return = str_repeat($htab, $indent) . '<header>' . $crlf . 
     876                str_repeat($htab, $indent) . $htab . '<headername>' . htmlspecialchars($new_hdr_name) . '</headername>' . $crlf . 
     877                str_repeat($htab, $indent) . $htab . '<headervalue>' . htmlspecialchars($new_hdr_value['value']) . '</headervalue>' . $crlf . 
     878                $params . 
     879                str_repeat($htab, $indent) . '</header>' . $crlf; 
     880 
     881                return $return; 
     882        } 
     883 
     884        /** 
     885         * Z-Push helper to decode text 
     886         * 
     887         * @param  string  current charset of input 
     888         * @param  string  input 
     889         * @return string  XML version of input 
     890         * @access private 
     891         */ 
     892        function _fromCharset($charset, $input) { 
     893                if($charset == '' || (strtolower($charset) == $this->_charset)) 
     894                        return $input; 
     895 
     896                return @iconv($charset, $this->_charset. "//TRANSLIT", $input); 
     897        } 
     898 
     899        /** 
     900         * Z-Push helper for error logging 
     901         * removing PEAR dependency 
     902         * 
     903         * @param  string  debug message 
     904         * @return boolean always false as there was an error 
     905         * @access private 
     906         */ 
     907        function raiseError($message) { 
     908                debugLog("mimeDecode error: ". $message); 
     909                return false; 
     910        } 
    919911} // End of class 
Note: See TracChangeset for help on using the changeset viewer.