source: trunk/prototype/services/ImapServiceAdapter.php @ 6265

Revision 6265, 26.4 KB checked in by cristiano, 8 years ago (diff)

Ticket #2773 - Caracteres indevidos na identificação de nome de mensagens em anexo

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