source: sandbox/expressoServiceImap/prototype/services/ImapServiceAdapter.php @ 6529

Revision 6529, 25.5 KB checked in by natan, 12 years ago (diff)

Ticket #2845 - Atualizacao da API na busca de mensagens - Migracao das funcionalidades do ImapServiceAdapter?

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