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

Revision 6486, 26.7 KB checked in by natan, 12 years ago (diff)

Ticket #2845 - Atualizacao da API na busca de mensagens - Migracao do anexar mensagens para API atual

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