source: sandbox/2.5.1-expresso1/prototype/services/ImapServiceAdapter.php @ 7912

Revision 7912, 28.5 KB checked in by gustavo, 11 years ago (diff)

Ticket #3349 - Finalizada implementacao da melhoria com a busca no anexo de mensagens

RevLine 
[6243]1<?php
[6536]2/**
3 *
4 * Copyright (C) 2012 Consórcio Expresso Livre - 4Linux (www.4linux.com.br) e Prognus Software Livre (www.prognus.com.br)
5 *
6 * This program is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Affero General Public License version 3 as published by
8 * the Free Software Foundation with the addition of the following permission
9 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
10 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
11 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program; if not, see www.gnu.org/licenses or write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 * MA 02110-1301 USA.
22 *
23 * This code is based on the OpenXchange Connector and on the Prognus pSync
24 * Connector both developed by the community and licensed under the GPL
25 * version 2 or above as published by the Free Software Foundation.
26 *
[6243]27 * You can contact Prognus Software Livre headquarters at Av. Tancredo Neves,
28 * 6731, PTI, Edifício do Saber, 3º floor, room 306, Foz do Iguaçu - PR - Brasil or at
[6536]29 * e-mail address prognus@prognus.com.br.
30 *
[6243]31 * Classe de abstração que faz uma adaptação para manipulação de informações
[6536]32 * no IMAP a partir de vários métodos.
33 *
34 * @package    Prototype
35 * @license    http://www.gnu.org/copyleft/gpl.html GPL
36 * @author     Consórcio Expresso Livre - 4Linux (www.4linux.com.br) e Prognus Software Livre (www.prognus.com.br)
37 * @version    2.4
38 * @sponsor    Caixa Econômica Federal
39 * @since      Arquivo disponibilizado na versão 2.4
[6243]40 */
41
42include_once ROOTPATH."/../expressoMail1_2/inc/class.imap_functions.inc.php";
43
[6536]44use prototype\api\Config as Config;
45
46/**
47 *
48 * @package    Prototype (Mail)
49 * @license    http://www.gnu.org/copyleft/gpl.html GPL
50 * @author     Consórcio Expresso Livre - 4Linux (www.4linux.com.br) e Prognus Software Livre (www.prognus.com.br)
51 * @version    2.4
52 * @sponsor    Caixa Econômica Federal
53 * @since      Classe disponibilizada na versão 2.4
[6243]54 */
55class ImapServiceAdapter extends imap_functions/* implements Service*/
56{
57    public function open( $config )
58    {
59                $this->init();
60    }
61
62//     public function connect( $config )
63//     {
64//                      $this->init();
65//     }
66       
67    public function find( $URI, $justthese = false, $criteria = false )
68        {
69
70                $context = isset($justthese['context']) ? $justthese['context'] : '' ;
71
72                switch( $URI['concept'] )
73                {
74                        case 'folder':
75                        {
76                                $result = $this->getFolders();
77
78                                foreach ($result as $res) {
79
[6930]80                                        //monta o array padrao
81                                        $array = array(
[6243]82                                                        'id' => mb_convert_encoding( $res['folder_id'], 'UTF-8', 'UTF7-IMAP' ),
83                                                        'commonName' => mb_convert_encoding( $res['folder_name'], 'UTF-8' , 'UTF7-IMAP' ),
84                                                        'parentFolder' => mb_convert_encoding( $res['folder_parent'], 'UTF-8' , 'UTF7-IMAP' ),
85                                                        'messageCount' => array('unseen' => isset($res['folder_unseen']) ? $res['folder_unseen'] : null, 'total' => null)
[6930]86                                        );
87
88                                        //se existir compartilhamento para pasta compartilhada
89                                        //adicionar array de permissoes
90                                        if(isset($res['acl_share'])){
91                                                $array['acl_share'] = $res['acl_share'];
92                                        }
93                                        $response[] = $array;
[6243]94                                }
95                                return $response;
96                        }
97                        case 'message':
98                        {
99                                //begin: for grid       
100                                $page  = isset($criteria['page']) ? $criteria['page'] : 1 ; //{1}    get the requested page
101                                $limit = isset($criteria['rows']) ? $criteria['rows'] : 10 ; //{10}   get how many rows we want to have into the grid
102                                $sidx  = isset($criteria['sidx']) ? $criteria['sidx'] : 0; //{id}   get index row - i.e. user click to sort
103                                $sord  = isset($criteria['sord']) ? $criteria['sord'] : ''; //{desc} get the direction
104
105                                $filter =  isset($criteria['filter']) ? $criteria['filter'] : '';
106
107                                if( !$sidx ) $sidx = 1;
108
109                                $folder_name =  isset($URI['folder']) ?  $URI['folder'] : str_replace( '.', $this->imap_delimiter, isset($context['folder']) ?  $context['folder'] : 'INBOX');
110                       
111                                $count = imap_num_msg( $this->open_mbox( $folder_name ) );
112
113                                $total_pages = $count > 0 ? ceil( $count/$limit ) : 0;
114
115                                if( $page > $total_pages )
116                                        $page = $total_pages;
117
118                                $start = $limit * $page - $limit;
119                                // do not put $limit*($page - 1)
120                                //end: for grid
121                               
122                               
123                                /**
124                                 * Trata o caso específico de retorno do atributo messageId
125                                 *
126                                 * TODO - refazer todo a operação find do conceito message, uma vez que esta
127                                 * foi desenvolvida quando a nova API ainda era muito imatura e se encontra
128                                 * muito acoplada à estrutura de retorno esperada pelo plugin jqGrid
129                                 */
130                                if ( $justthese )
131                                {
132                                        if (isset($justthese[0]) && $justthese[0] == 'messageId') {
133                                                $map = array(
134                                                        'folderName' => array(),
135                                                        'messageNumber' => array()
136                                                );
137                                               
138                                                self::parseFilter($criteria["filter"], &$map);
139                                               
140                                                if (count($map['folderName']) == 0) {
141                                                        $folders = $this->get_folders_list();
142                                                        foreach ($folders as $folder)
143                                                                if (isset($folder['folder_id']))
144                                                                        $map['folderName'][] = $folder['folder_id'];
145                                                }
146                                               
147                                                $result = array();
148                                                foreach ($map['folderName'] as $folder) {
149                                                        $this->mbox = $this->open_mbox($folder);
150
151                                                        /**
152                                                         * Se não foi passado messageNumber no filtro,
153                                                         * busca todas as mensagens de cada pasta
154                                                         */
155                                                        $messages = empty($map['messageNumber']) ? '1:*' : implode(',', $map['messageNumber']);
156                                                        $sequenceType = empty($map['messageNumber']) ? 0 : FT_UID;
157
158                                                        $headers = imap_fetch_overview($this->mbox, $messages, $sequenceType);
159                                                        foreach ($headers as $h) {
160                                                                if(isset($h->message_id ))
161                                                                        $result[] = array ( 'messageId' => $h->message_id );
162                                                        }
163       
164                                                }
165                                                return $result;
166                                        }
167                                }
168                               
169                                if( $filter )
170                                {
171                                        if( $filter[0] !== 'msgNumber' )
172                                        {
[7712]173                        for( $i = 0; $i < count($filter); ++$i )
[7673]174                        {
175                            if( count( $filter[$i] ) === 4 )
176                            $criteria['isExact'] = ( array_shift( $filter[$i] ) === 'AND' );
[6243]177
[7673]178                            $criteria[ $filter[$i][0] ] = array( 'criteria' => $filter[$i][2], 'filter' => $filter[$i][1] );
179                        }
180                        return $this->searchSieveRule($criteria);
[6243]181                                        }
182
183                                        $msgNumber = array();
184
[7655]185                                        for( $i = $start; $i < $start + $limit && isset( $filter[2][$i] ); ++$i )
[6243]186                                          $msgNumber[] = $filter[2][$i];
187
188                                        if( empty( $msgNumber ) )
[7673]189                                            return( false );
[6243]190
191                                        $result = $this->get_info_msgs( array( 'folder' => $folder_name,
192                                                                           'msgs_number' => implode( ',', $msgNumber ) ) );
193
194                                        foreach( $result as $i => $val )
195                                        $result[$i] = unserialize( $val );
196
197                                }
198                                else
199                                {
200                                        $result = $this->get_range_msgs2(
201                                                array(
202                                                        'folder' => $folder_name, //INBOX
203                                                        'msg_range_begin' => $start + 1, //??
204                                                        'msg_range_end' => $start + $limit, //$limit = $_GET['rows']; // get how many rows we want to have into the grid
205                                                        'sort_box_type' => 'SORTARRIVAL',
206                                                        'search_box_type' => 'ALL',
207                                                        'sort_box_reverse' => 1
208                                                )
209                                        );
210                                }
211                                //return var_export($result);
212
[7719]213                                if($filter){
214                                        $total_pages = count($filter[2]) > 0 ? ceil( count($filter[2])/$limit ) : 0;
215                                        $response = array( "page" => $page, "total" => $total_pages, "records" =>  count($filter[2]) );
216                                }else{
217                                        $response = array( "page" => $page, "total" =>  $total_pages, "records" =>  $count );   
218                                }
[7712]219
220                                for ($i=0; $i<count($result); ++$i)
[6243]221                                {
222                                        $flags_enum = array('Unseen'=> 1,  'Answered'=> 1, 'Forwarded'=> 1, 'Flagged'=> 1, 'Recent'=> 1, 'Draft'=> 1 );
223
224                                        foreach ($flags_enum as $key => $flag)
225                                        {
226                                                if ( !isset($result[$i][$key]) || !trim($result[$i][$key]) || trim($result[$i][$key]) == '') 
227                                                        $flags_enum[$key] = 0;
228
229                                                unset($result[$i][$flag]);
230                                        }
231
232                                        if (array_key_exists($i, $result))
233                                        {
234                                                $response["rows"][$i] = $result[$i];
[6343]235                                                $response["rows"][$i]['timestamp'] = $result[$i]['udate'] * 1000;
[6243]236                                                $response["rows"][$i]['flags'] = implode(',', $flags_enum);
237                                                $response["rows"][$i]['size'] = $response["rows"][$i]['Size'];
238                                                $response["rows"][$i]['folder'] = $folder_name;
239                                                //$response["rows"][$i]['udate'] = ( $result[$i]['udate'] + $this->functions->CalculateDateOffset()  * 1000 );
240                                                unset($response["rows"][$i]['Size']);
241                                        }
242                                 }
243
244                                return $this->to_utf8($response);
245                        }
246                       
247                        /**
248                         * Filtros suportados:
249                         * - ['=', 'folderName', $X]
250                         * - [
251                         *              'AND',
252                         *              [
253                         *                      'AND',
254                         *                      ['=', 'folderName', $X],
255                         *                      ['IN', 'messageNumber', $Ys]
256                         *              ],
257                         *              ['IN', 'labelId', $Zs]
258                         * ]
259                         * - ['=', 'labelId', $X]
260                         * - [
261                         *              'AND',
262                         *              ['=', 'folderName', $X],
263                         *              ['=', 'labelId', $Y]
264                         * ]
265                         * - ['IN', 'labelId', $Ys]
266                         * - [
267                         *              'AND',
268                         *              ['=', 'folderName', $X],
269                         *              ['IN', 'labelId', $Ys]
270                         * ]                   
271                         */
272                        case 'labeled':
273                        {
274                                $result = array ( );
275                                if (isset($criteria["filter"]) && is_array($criteria['filter'])) {
276                                        //TODO - melhorar o tratamento do filter com a lista de todos os labelIds dado pelo interceptor
277                                        $map = array(
278                                                'id' => array(),
279                                                'folderName' => array(),
280                                                'messageNumber' => array(),
281                                                'labelId' => array()
282                                        );
283                                       
284                                        self::parseFilter($criteria["filter"], &$map);
285                                       
286                                        if (count($map['folderName']) == 0) {
287                                                $folders = $this->get_folders_list();
288                                                foreach ($folders as $folder)
289                                                        if (isset($folder['folder_id']))
290                                                                $map['folderName'][] = $folder['folder_id'];
291                                        }
292
293                                        foreach ($map['folderName'] as $folder) {
294                                                $this->mbox = $this->open_mbox($folder);
295                                               
296                                                foreach ($map['labelId'] as $label) {
[6389]297                                                        $messagesLabeleds = imap_search($this->mbox, 'UNDELETED KEYWORD "$Label'.$label.'"', SE_UID);
[6243]298                                                       
299                                                        if(is_array($messagesLabeleds))
300                                                        foreach ($messagesLabeleds as $messageLabeled) {
301                                                                if (count($map['messageNumber']) > 0 && !in_array($messageLabeled, $map['messageNumber']))
302                                                                        continue;
303                                                                       
304                                                                $result[] = array (
305                                                                        'id' => $folder . '/' . $messageLabeled . '#' . $label,
306                                                                        'folderName' => $folder,
307                                                                        'messageNumber' => $messageLabeled,
308                                                                        'labelId' => $label
309                                                                );
310                                                        }
311                                                }
312
313                                        }
314                                }
315                               
316                                return $result;
317                        }
318                       
319                        case 'followupflagged':
320                        {                                       
321                                $result = array ( );
322
323                                $map = array(
324                                        //'id' => array(),
325                                        'folderName' => array(),
326                                        'messageNumber' => array(),
327                                        'messageId' => array()
328                                );
329                               
330                                self::parseFilter($criteria["filter"], &$map);
331       
332                                if (empty($map['folderName'])) {
333                                        $folders = $this->get_folders_list();
334                                        foreach ($folders as $folder)
335                                                if (isset($folder['folder_id']))
336                                                        $map['folderName'][] = $folder['folder_id'];
337                                }
338                               
339                                $messagesIds = $map['messageId'];
340
341                                foreach ($map['folderName'] as $folder) {
342                                        $messages = array();
343                                       
344                                        $this->mbox = $this->open_mbox($folder);
345
346                                        /**
347                                         * Se é uma busca por messageId
348                                         */
349                                        if (!empty($map['messageId'])) {
350                                                       
351                                                foreach ($messagesIds as $k => $v) {
352
353                                                        $r = imap_search($this->mbox, 'ALL KEYWORD "$Followupflagged" TEXT "Message-Id: '.$v.'"', SE_UID);
354
355                                                        if ($r) {
356
357                                                                $messages = array_merge($messages, $r);
358                                                                unset($messagesIds[$k]);
359                                                               
360                                                        }
361                                                }
362
363                                        /**
364                                         * Se é uma busca por messageNumber.
365                                         * Lembrando que, neste caso, só deve ser suportada uma única pasta no filtro.
366                                         */
367                                        } else {
368                                                $messages = imap_search($this->mbox, 'ALL KEYWORD "$Followupflagged"', SE_UID);
369                                        }
370
371                                        /**
372                                         * Se é uma busca por messageId, deve ser comparado com os messageNumbers
373                                         * passados no filtro, se houverem.
374                                         */
375                                        if (!empty($map['messageNumber']) && is_array($messages)) {
376                                                                                               
377                                                foreach ($messages as $k => $m)
378                                                        if (!in_array($m, $map['messageNumber']))
379                                                                unset($messages[$k]);
380                                        }
381
382                                        /**
383                                         * Adicionar demais atributos às mensagens para retorno
384                                         */
385                                        if(is_array($messages))
386                                        foreach ($messages as $k => $m) {
387                                                $headers = imap_fetch_overview($this->mbox, $m, FT_UID);
388
389                                                $result[] = array (
390                                                        'messageId' => $headers[0]->message_id,
391                                                        'messageNumber' => $m,
392                                                        'folderName' => $folder
393                                                );
394                                        }
395
396                                       
397                                        /**
398                                         * Se é uma busca por messageId e todos os messageIds foram econstrados:
399                                         * Stop searching in all folders
400                                         */
401                                        if (!empty($map['messageId']) && empty($messagesIds))
402                                                break;
403                                }
404                               
405
406                                return $result;
407                               
408                        } //CASE 'followupflag'
409                }
410    }
411
412    public function read( $URI, $justthese = false )
413    {
414
415                switch( $URI['concept'] )
416                {
417                        case 'message':
[6303]418                        {       
[6243]419                                return $this->to_utf8(
420                                        $this->get_info_msg( array('msg_number'=>$URI['id'],
[6303]421                                        'msg_folder'=>str_replace( '.', $this->imap_delimiter, $justthese['context']['folder'] ) ,
422                                        'decoded' => true ) )
[6243]423                                );
424                        }
425                        case 'labeled':
426                        {
427                                /**
428                                 * id looks like 'folder/subfolder/subsubfolder/65#13', meaning messageId#labelId
429                                 */
430                                list($messageId, $labelId) = explode('#', $URI['id']);
431                                $folderName = basename($messageId);
432                                $messageNumber = dirname($messageId);
433                               
434                                $result = array();
435
436                                if ($folderName && $messageNumber && $labelId) {
437                                        $this->mbox = $this->open_mbox($folderName);
[6389]438                                        $messagesLabeleds = imap_search($this->mbox, 'UNDELETED KEYWORD "$Label'.$labelId.'"', SE_UID);
[6243]439                                       
440                                        if (in_array($messageNumber, $messagesLabeleds)) {
441                                                $result = array (
442                                                        'id' => $URI['id'],
443                                                        'folderName' => $folderName,
444                                                        'messageNumber' => $messageNumber,
445                                                        'labelId' => $labelId
446                                                );
447                                        }
448
449                                }
450                               
451                                return $result;
452                        }
453                       
454                        case 'followupflagged':
455                        {
456                       
457                                /**
458                                 * identifica se o formato de ID é "folder/subfolder/subsubfolder/<messageNumber>" ou "<message-id>"
459                                 */
460                                $folderName = $messageNumber = false;
461                                if(!($messageHasId = preg_match('/<.*>/', $URI['id']))) {
462                                        $folderName = dirname($URI['id']);
463                                        $messageNumber = basename($URI['id']);
464                                }
465
466                                $result = array();
467                                if ($folderName && $messageNumber) {
468
469                                        $this->mbox = $this->open_mbox($folderName);
470                                        $r = imap_search($this->mbox, 'ALL KEYWORD "$Followupflagged"', SE_UID);
471
472                                        if (in_array($messageNumber, $r)) {
473                                                $headers = imap_fetch_overview($this->mbox, $messageNumber, FT_UID);
474                                                       
475                                                $result = array (
476                                                        'messageId' => $headers[0]->message_id,
477                                                        'messageNumber' => $messageNumber,
478                                                        'folderName' => $folderName
479                                                );
480                                        }
481                               
482                                } else {
483                                        /**
484                                         * Busca pela mensagem com o messageId dado. Se uma pasta foi passada, busca nela,
485                                         * senão busca em todas.
486                                         */
487                                       
488                                        $folders = array ();
489                                        if ($folderName) {
490                                                $folders = array ($folderName);
491                                        } else {
492                                                $folder_list = $this->get_folders_list();
493                                                foreach ($folder_list as $folder)
494                                                        if (isset($folder['folder_id']))
495                                                                $folders[] = $folder['folder_id'];
496                                        }
497                                       
498                                        foreach ($folders as $folder) {
499                                               
500                                                $this->mbox = $this->open_mbox($folder);
501                                               
502                                                if ($messages = imap_search($this->mbox, 'ALL KEYWORD "$Followupflagged" TEXT "Message-Id: '.$URI['id'].'"', SE_UID)) {
503                               
504                                                        $result = array (
505                                                                'messageId' => $URI['id'],
506                                                                'messageNumber' => $messages[0],
507                                                                'folderName' => $folder
508                                                        );
509                                                       
510                                                        /**
511                                                         * Stop searching in all folders
512                                                         */
513                                                        break;
514                                                }
515       
516                                        }
517                                }
518                               
519                               
520                                return $result;
521                        }
522                }
523    }
524
525    public function create($URI, &$data)
526    {               
527                switch( $URI['concept'] )
528                {
529                        case 'labeled':
530                        {
531                                if (isset($data['folderName']) && isset($data['messageNumber']) && isset($data['labelId'])) {
532                                        $this->mbox = $this->open_mbox($data['folderName']);
[6389]533                                        imap_setflag_full($this->mbox, $data['messageNumber'], '$Label' . $data['labelId'], ST_UID);
[6243]534
535                                        return array ('id' => $data['folderName'].'/'.$data['messageNumber'].'#'.$data['labelId']);
536                                }
537                                return array ();
538                        }
539                        case 'followupflagged':
540                        {
541                                //deve ser gravado primeiro no imap, obtido o message-id e, depois gravado no banco
542                               
543                                if (isset($data['folderName']) && isset($data['messageNumber'])) {
544                                       
545                                        $this->mbox = $this->open_mbox($data['folderName']);
546                                        $s = imap_setflag_full($this->mbox, $data['messageNumber'], '$Followupflagged', ST_UID);
547                                       
548                                        $headers = imap_fetch_overview($this->mbox, $data['messageNumber'], FT_UID);
549                                       
550                                        $data['messageId'] = $headers[0]->message_id;
[6641]551                                       
552                                        /*
553                                         * TODO
554                                         * Verificar erro ao tentar setar uma flag com o limite de flags atingido
555                                         * onde o status retornado pelo imap_setflag_full é true mesmo não sendo possível
556                                         * a inserção da flag.
557                                         */
[6243]558
[6641]559                                        return (($s) && (imap_last_error() != 'Too many user flags in mailbox')) ? $data : array();
[6243]560
561                                } else if (isset($data['messageId'])) {
562                                        /**
563                                         * Busca pela mensagem com o messageId dado. Se uma pasta foi passada, busca nela,
564                                         * senão busca em todas.
565                                         */
566                                        $folders = array ();
567                                        if (isset($data['folderName'])) {
568                                                $folders = array ($data['folderName']);
569                                        } else {
570                                                $folder_list = $this->get_folders_list();
571                                                foreach ($folder_list as $folder)
572                                                        if (isset($folder['folder_id']))
573                                                                $folders[] = $folder['folder_id'];
574                                        }
575                                       
576                                        foreach ($folders as $folder) {
577                                               
578                                                $this->mbox = $this->open_mbox($folder);
579                                                if ($messages = imap_search($this->mbox, 'ALL TEXT "Message-Id: '.$data['messageId'].'"', SE_UID)) {
580                                                       
581                                                        $s = imap_setflag_full($this->mbox, $messages[0], '$Followupflagged', ST_UID);
582                                               
583                                                        /**
584                                                         * Stop searching in all folders
585                                                         */
586                                                        return $data;
587                                                }
588                                               
589                                        }
590                                }
591                                return array ();
592                        }
593                       
594                        case 'message':
595                        {
596                                require_once ROOTPATH.'/library/uuid/class.uuid.php';
597                               
598                                $GLOBALS['phpgw_info']['flags'] = array( 'noheader' => true, 'nonavbar' => true,'currentapp' => 'expressoMail1_2','enable_nextmatchs_class' => True );
599                                $return = array();
600
601                                require_once dirname(__FILE__) . '/../../services/class.servicelocator.php';
602                                $mailService = ServiceLocator::getService('mail');
603
604                                $msg_uid = $data['msg_id'];
605                                $body = $data['body'];
[7274]606                                $body = str_replace("&lt;","&yzwkx;",$body); //Alterar as Entities padrão das tags < > para compatibilizar com o Expresso
607                                $body = str_replace("&gt;","&xzwky;",$body);
[6243]608                                $body = str_replace("%nbsp;","&nbsp;",$body);
[7274]609                                $body = html_entity_decode ( $body, ENT_QUOTES , 'ISO-8859-1' );               
610                                $body = str_replace("&yzwkx;","&lt;",$body);
611                                $body = str_replace("&xzwky;","&gt;",$body);                           
[6243]612
613                                $folder = mb_convert_encoding($data['folder'], "UTF7-IMAP","ISO-8859-1, UTF-8");
614                                $folder = @preg_replace('/INBOX[\/.]/i', "INBOX".$this->imap_delimiter, $folder);
615
616                                /**
617                                * Gera e preenche o field Message-Id do header
618                                */
619                                $mailService->addHeaderField('Message-Id', UUID::generate( UUID::UUID_RANDOM, UUID::FMT_STRING ) . '@Draft');
[6882]620                $mailService->addHeaderField('Reply-To', mb_convert_encoding(($data['input_reply_to']), 'ISO-8859-1', 'UTF-8,ISO-8859-1'));
[7414]621                $mailService->addHeaderField('Date', date("d-M-Y H:i:s"));
[6243]622                                $mailService->addTo(mb_convert_encoding(($data['input_to']), 'ISO-8859-1', 'UTF-8,ISO-8859-1'));
623                                $mailService->addCc( mb_convert_encoding(($data['input_cc']), 'ISO-8859-1', 'UTF-8,ISO-8859-1'));
624                                $mailService->addBcc(mb_convert_encoding(($data['input_cco']), 'ISO-8859-1', 'UTF-8,ISO-8859-1'));
625                                $mailService->setSubject(mb_convert_encoding(($data['input_subject']), 'ISO-8859-1', 'UTF-8,ISO-8859-1'));
626                               
627                                if(isset($data['input_important_message']))
628                                        $mailService->addHeaderField('Importance','High');
629
630                                if(isset($data['input_return_receipt']))
631                                        $mailService->addHeaderField('Disposition-Notification-To', Config::me('mail'));
632
[6457]633                                $this->rfc2397ToEmbeddedAttachment($mailService , $body);
634
[6243]635                                $isHTML = ( isset($data['type']) && $data['type'] == 'html' )?  true : false;
636
637                                if (!$body) $body = ' ';
638
639
640                                $mbox_stream = $this->open_mbox($folder);
641
642                                $attachment = json_decode($data['attachments'],TRUE);
643
[7044]644                if(!empty($attachment))
[6243]645                                foreach ($attachment as &$value)
646                                {
647                                        if((int)$value > 0) //BD attachment
648                                        {
649                                                $att = Controller::read(array('id'=> $value , 'concept' => 'mailAttachment'));
650
[6700]651                                                if($att['disposition'] == 'embedded' && $isHTML) //Caso mensagem em texto simples converter os embedded para attachments
[6243]652                                                {
[6576]653                                                        $body = str_replace('"../prototype/getArchive.php?mailAttachment='.$att['id'].'"', '"'.mb_convert_encoding($att['name'], 'ISO-8859-1' , 'UTF-8,ISO-8859-1').'"', $body);
[6536]654                                                        $mailService->addStringImage(base64_decode($att['source']), $att['type'], mb_convert_encoding($att['name'], 'ISO-8859-1' , 'UTF-8,ISO-8859-1'));
[6243]655                                                }
656                                                else
[6536]657                                                        $mailService->addStringAttachment(base64_decode($att['source']), mb_convert_encoding($att['name'], 'ISO-8859-1' , 'UTF-8,ISO-8859-1'), $att['type'], 'base64', isset($att['disposition']) ? $att['disposition'] :'attachment' );
[6243]658
659                                                unset($att);
660                                        }
661                                        else
662                                        {
663                                                $value = json_decode($value, true);
[6265]664                                               
[6243]665                                                switch ($value['type']) {
666                                                        case 'imapPart':
667                                                                $att = $this->getForwardingAttachment($value['folder'],$value['uid'], $value['part']);
[6999]668                                                                if(strstr($body,'src="./inc/get_archive.php?msgFolder='.$value['folder'].'&msgNumber='.$value['uid'].'&indexPart='.$value['part'].'"') !== false)//Embeded IMG
[6243]669                                                                {   
[6999]670                                                                        $body = str_ireplace('src="./inc/get_archive.php?msgFolder='.$value['folder'].'&msgNumber='.$value['uid'].'&indexPart='.$value['part'].'"' , 'src="'.$att['name'].'"', $body);
[6536]671                                                                        $mailService->addStringImage($att['source'], $att['type'], mb_convert_encoding($att['name'], 'ISO-8859-1' , 'UTF-8,ISO-8859-1'));
[6243]672                                                                }
673                                                                else
[6536]674                                                                        $mailService->addStringAttachment($att['source'], mb_convert_encoding($att['name'], 'ISO-8859-1' , 'UTF-8,ISO-8859-1'), $att['type'], 'base64', isset($att['disposition']) ? $att['disposition'] :'attachment' );
[6243]675                                                                unset($att);
676                                                                break;
677                                                        case 'imapMSG':
678                                                                $mbox_stream = $this->open_mbox($value['folder']);
679                                                                $rawmsg = $this->getRawHeader($value['uid']) . "\r\n\r\n" . $this->getRawBody($value['uid']);
[6536]680                                                                $mailService->addStringAttachment($rawmsg, mb_convert_encoding(base64_decode($value['name']), 'ISO-8859-1' , 'UTF-8,ISO-8859-1'), 'message/rfc822', '7bit', 'attachment' );
[6243]681                                                                unset($rawmsg);
682                                                                break;
683
684                                                        default:
685                                                        break;
686                                                }
687                                        }
688
689                                }
690
[7622]691                                if($isHTML) $mailService->setBodyHtml($body); else $mailService->setBodyText(mb_convert_encoding($body, 'ISO-8859-1' , 'UTF-8,ISO-8859-1' ));
[6243]692
693                                if(imap_append($mbox_stream, "{".$this->imap_server.":".$this->imap_port."}".$folder, $mailService->getMessage(), "\\Seen \\Draft"))
694                                {
695                                        $status = imap_status($mbox_stream, "{".$this->imap_server.":".$this->imap_port."}".$folder, SA_UIDNEXT);
696                                        $return['id'] = $status->uidnext - 1;
697
698                                        if($data['uidsSave'] )
699                                                $this->delete_msgs(array('folder'=> $folder , 'msgs_number' => $data['uidsSave']));
700                                }
701
702                                return $return;
703                        }
704                }
705        }
706
707    public function delete( $URI, $justthese = false, $criteria = false )
708    {
709                switch( $URI['concept'] )
710                {
711                        case 'labeled':
712                        {
713                                list($messageId, $labelId) = explode('#', $URI['id']);
714                                $folderName = dirname($messageId);
715                                $messageNumber = basename($messageId);
716
717                                if ($folderName && $messageNumber && $labelId) {
718                                        $this->mbox = $this->open_mbox($folderName);
[6389]719                                        imap_clearflag_full($this->mbox, $messageNumber, '$Label' . $labelId, ST_UID);
[6243]720
721                                }
722                        }
723                        case 'followupflagged':
724                        {
725                                $map = array(
726                                        'folderName' => array(),
727                                        'messageNumber' => array(),
728                                        'messageId' => array()
729                                );
730                               
731                                self::parseFilter($criteria["filter"], &$map);
732                               
733                                if (!$map['folderName']) {
734                                        $folders = array ();
735                                       
736                                        $folder_list = $this->get_folders_list();
737                                        foreach ($folder_list as $folder)
738                                                if (isset($folder['folder_id']))
739                                                        $folders[] = $folder['folder_id'];
740                                        $map['folderName'] = $folders;
741                                }
742
743                                $messagesIds = $map['messageId'];
744
745                                foreach ($map['folderName'] as $folder) {
746                                        $messages = array();
747                                       
748                                        $this->mbox = $this->open_mbox($folder);
749                               
750                                        /**
751                                         * Se é uma busca por messageId
752                                         */
753                                        if (!empty($map['messageId'])) {
754                                                       
755                                                foreach ($messagesIds as $k => $v) {
756                                                        $r = imap_search($this->mbox, 'ALL KEYWORD "$Followupflagged" TEXT "Message-Id: '.$v.'"', SE_UID);
757
758                                                        if ($r) {
759                                                                $messages = $messages + $r;
760                                                                unset($messagesIds[$k]);       
761                                                        }
762                                                }
763
764                                        /**
765                                         * Se é uma busca por messageNumber.
766                                         * Lembrando que, neste caso, só deve ser suportada uma única pasta no filtro.
767                                         */
768                                        } else {
769                                                $messages = imap_search($this->mbox, 'ALL KEYWORD "$Followupflagged"', SE_UID);
770                                        }
771
772                                        /**
773                                         * Se é uma busca por messageId, deve ser comparado com os messageNumbers
774                                         * passados no filtro, se houverem.
775                                         */
776                                        if (!empty($map['messageNumber'])) {
777                                                foreach ($messages as $k => $m)
778                                                        if (!in_array($m, $map['messageNumber']))
779                                                                unset($messages[$k]);
780                                        }
781
782                                        $s = true;
783                                        foreach ($messages as $k => $m) {                                               
784                                                $s = imap_clearflag_full($this->mbox, $m, '$Followupflagged', ST_UID) && $s;
785                                        }
786
787                                        /**
788                                         * Se é uma busca por messageId e todos os messageIds foram econstrados:
789                                         * Stop searching in all folders
790                                         */
791                                        if (!empty($map['messageId']) && empty($messagesIds))
792                                                break;
793                                }
794                               
795                                return $s;
796                        }
797                }
798
799                //TODO - return
800        }
801
802    public function deleteAll( $URI, $justthese = false, $criteria = false )
803    {
[6566]804                $op = $criteria['filter'][0];
805                $ids = $criteria['filter'][2];
806                if($op == 'IN'){
807                        foreach ($ids as $id){
808                                self::delete( array( 'concept' => $URI['concept'], 'id' => $id), false, false);
809                        }
810                }
811
[6243]812                /**
813                 * TODO - implementar a deleção de todos os followupflaggeds conforme filtro
814                 */
815        }
816
817    public function update( $URI, $data, $criteria = false )
818    {
819                /**
820                 * Os únicos atributos da sinalização presentes no IMAP são folderName, messageNumber e messageId,
821                 * porém a operação de update desses atributos não faz sentido para o usuário da DataLayer,
822                 * pois na prática elas são executadas através das operações de CREATE e DELETE.
823                 * Assim, para os conceitos "labeled" e "followupflagged", só faz sentido o update de
824                 * atributos gravados no banco de dados e nunca no IMAP.
825                 */
826        }
827
828//     public function retrieve( $concept, $id, $parents, $justthese = false, $criteria = false )
829//     {
830//                      return $this->read( array( 'id' => $id,
831//                          'concept' => $concept,
832//                          'context' => $parents ), $justthese );
833//     }
834
835    public function replace( $URI, $data, $criteria = false )
836    {}
837
838    public function close()
839    {}
840
841    public function setup()
842    {}
843
844    public function commit( $uri )
845    { return( true ); }
846
847    public function rollback( $uri )
848    {}
849
850    public function begin( $uri )
851    {}
852
853
854    public function teardown()
855    {}
856
857    function to_utf8($in)
858    {
859                if (is_array($in)) {
860                        foreach ($in as $key => $value) {
861                                $out[$this->to_utf8($key)] = $this->to_utf8($value);
862                        }
863                } elseif(is_string($in)) {
864                                return mb_convert_encoding( $in , 'UTF-8' , 'UTF-8 , ISO-8859-1' );
865                } else {
866                        return $in;
867                }
868                return $out;
869    }
870       
871           
872    private static function parseFilter($filter ,&$map){
873               
874                if( !is_array( $filter ) || count($filter) <= 0) return null;
875                                       
876                $op = array_shift( $filter );
877                switch(strtolower($op))
878                {
879                        case 'and': {
880                                foreach ($filter as $term)
881                                        self::parseFilter($term ,&$map);
882                                return;
883                        }
884                        case 'in': {
885                                if(is_array($map[$filter[0]]) && is_array($filter[1]))
886                                        $map[$filter[0]] = array_unique(array_merge($map[$filter[0]], $filter[1]));
887                                return;
888                        }
889                        case '=': {
890                                $map[$filter[0]][] = $filter[1];
891                        }
892                }
893        }
894
895}
Note: See TracBrowser for help on using the repository browser.