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

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