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

Revision 6545, 25.6 KB checked in by natan, 12 years ago (diff)

Ticket #2845 - Atualizacao da API na busca de mensagens - Correcao do problema nas paginacoes

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