source: sandbox/newExpressoMail/prototype/services/ImapServiceAdapter.php @ 7265

Revision 7265, 30.2 KB checked in by gustavo, 12 years ago (diff)

Ticket #0000 - Criado novo modulo para o desenvolvimento do novo ExpressoMail?

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