получить вложения из вложенных частей imap - PullRequest
0 голосов
/ 17 сентября 2018

Я использую приведенную ниже функцию для получения вложений из электронного письма (индекс $ m) по существующему соединению imap ($ imap)

function parse_parts(&$structure, &$attachments, &$imap, $m, $par){
if(isset($structure->parts) && count($structure->parts) ) {
    for($i = 0; $i < count($structure->parts); $i++) {
        $attachments[] = array(
            'is_attachment' => false,
            'filename' => '',
            'name' => '',
            'attachment' => ''
        );
        $lstk= array_keys($attachments);  $j=end($lstk); // use this instead of $i to avoid overlapping indices when there's sub-parts and recursion

        if($structure->parts[$i]->ifdparameters) {
            foreach($structure->parts[$i]->dparameters as $object) {
                if(strtolower($object->attribute) == 'filename') {
                    $attachments[$j]['is_attachment'] = true;
                    $attachments[$j]['filename'] = $object->value;
                }
            }
        }
        if($structure->parts[$i]->ifparameters) {
            foreach($structure->parts[$i]->parameters as $object) {
                if(strtolower($object->attribute) == 'name') {
                    $attachments[$j]['is_attachment'] = true;
                    $attachments[$j]['filename'] = imap_utf8($object->value);
                }
            }
        }
        if($attachments[$j]['is_attachment']) {
            if($par==''){
                $attachments[$j]['attachment'] = imap_fetchbody($imap, $m,  $i+1);
            }else{
                $attachments[$j]['attachment'] = imap_fetchbody($imap, $m,  $par . $i+1);
            }
            if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
                $attachments[$j]['attachment'] = base64_decode($attachments[$j]['attachment']);
            }
            elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
                $attachments[$j]['attachment'] = quoted_printable_decode($attachments[$j]['attachment']);
            }else{echo "encod:". $structure->parts[$i]->encoding . PHP_EOL; }
        } 
        if(isset($structure->parts[$i]->parts) && count($structure->parts[$i]->parts)){ //if the part contains its own parts, recurse
             $prnt = $i;
             $prnt = $prnt . '.';
             parse_parts($structure->parts[$i], $attachments, $imap, $m, $prnt );    
        }
    }
}

}

, более поздняя функция, котораявызывает это выглядит так:

$structure = imap_fetchstructure($imap, $m);
$attachments = array();
parse_parts($structure, $attachments, $imap, $m, '');

стандартная функция работает нормально, но когда она должна рекурсировать (т. е. есть вложенные части), результирующий файл не читается, хотя кажется, что он имеет правильный размер,Есть идеи, что я делаю не так?Я попытался изменить $ prnt на

$prnt = $i+1 .'.';

, но затем он просто выводит пустой файл.я заметил, что у других людей были похожие проблемы: imap - получите прикрепленный файл

, но их решения не работают для этого электронного письма / кода.

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

вложение может быть встроенным или внешним файлом.

, поэтому мы должны получить оба типа вложений.

$structure = imap_fetchstructure($this->imap, $id);
    $fileName = $attachments = array();
    /* if any attachments found... */
    if (isset($structure->parts) && count($structure->parts)) {
        $n = 0;
        for($i = 0; $i < count($structure->parts); $i++){
            if(isset($structure->parts[$i]->parts) && !empty($structure->parts[$i]->parts) && count($structure->parts[$i]->parts)>0){
                for($y = 0; $y < count($structure->parts[$i]->parts); $y++) 
                {
                    $attachments[$n] = array('is_attachment' => false,'filename' => '','name' => '','attachment' => '','size' => '','cid' => 0);
                    if($structure->parts[$i]->parts[$y]->ifdparameters==1) {
                        foreach($structure->parts[$i]->parts[$y]->dparameters as $object){
                            if(strtolower($object->attribute) == 'filename'){
                                $attachments[$n]['is_attachment'] = true; 
                                $fileName[0] = $object->value;
                                $filename = $this->filterFileName($fileName);                               
                                $attachments[$n]['filename'] = $filename;
                                $attachments[$n]['name'] = $filename;
                            }
                        }
                    }
                    if($structure->parts[$i]->parts[$y]->ifparameters){
                        foreach($structure->parts[$i]->parts[$y]->parameters as $object){
                            if(strtolower($object->attribute) == 'name'){
                                $attachments[$n]['is_attachment'] = true;
                                $fileName[0] = $object->value;
                                $filename = $this->filterFileName($fileName);
                                $attachments[$n]['name'] = $filename;
                                $attachments[$n]['filename'] = $filename;
                            }
                        }
                    }
                    if($attachments[$n]['is_attachment']){
                        $attachments[$n]['attachment'] = imap_fetchbody($this->imap, $id, ($i+1).'.'.($y+1));                            
                        if($structure->parts[$i]->parts[$y]->encoding == 3){ /* 4 = QUOTED-PRINTABLE encoding */
                            $attachments[$n]['attachment'] = base64_decode($attachments[$n]['attachment']);
                        }                            
                        elseif($structure->parts[$i]->parts[$y]->encoding == 4){ /* 3 = BASE64 encoding */
                            $attachments[$n]['attachment'] = quoted_printable_decode($attachments[$n]['attachment']);
                        }
                        $attachments[$n]['size'] = $structure->parts[$i]->parts[$y]->bytes;
                        $attachments[$n]['cid'] = ($structure->parts[$i]->parts[$y]->ifid) ? str_replace(array('<', '>'), '', $structure->parts[$i]->parts[$y]->id) : 0;                            
                    }
                    $email['attachments'][] = $attachments[$n];$n++;
                }
            }else{
                $attachments[$n] = array('is_attachment' => false,'filename' => '','name' => '','attachment' => '','size' => '','cid' => 0);
                if($structure->parts[$i]->ifdparameters==1){
                    foreach($structure->parts[$i]->dparameters as $object){
                        if(strtolower($object->attribute) == 'filename'){
                            $attachments[$n]['is_attachment'] = true;
                            $fileName[0] = $object->value;
                            $filename = $this->filterFileName($fileName);
                            $attachments[$n]['filename'] = $filename;
                            $attachments[$n]['name'] = $filename;
                        }
                    }
                }
                if($structure->parts[$i]->ifparameters){
                    foreach($structure->parts[$i]->parameters as $object){
                        if(strtolower($object->attribute) == 'name'){
                            $attachments[$n]['is_attachment'] = true;
                            $fileName[0] = $object->value;
                            $filename = $this->filterFileName($fileName);
                            $attachments[$n]['name'] = $filename;
                            $attachments[$n]['filename'] = $filename;
                        }
                    }
                }
                if($attachments[$n]['is_attachment']){
                    $attachments[$n]['attachment'] = imap_fetchbody($this->imap, $id, $i+1);                        
                    if($structure->parts[$i]->encoding == 3){/* 4 = QUOTED-PRINTABLE encoding */ 
                        $attachments[$n]['attachment'] = base64_decode($attachments[$n]['attachment']);
                    }elseif($structure->parts[$i]->encoding == 4){ /* 3 = BASE64 encoding */
                        $attachments[$n]['attachment'] = quoted_printable_decode($attachments[$n]['attachment']);
                    }
                    $attachments[$n]['size'] = $structure->parts[$i]->bytes;
                    $attachments[$n]['cid'] = ($structure->parts[$i]->ifid) ? str_replace(array('<', '>'), '', $structure->parts[$i]->id) : 0;                        
                }
                $email['attachments'][] = $attachments[$n];$n++;
            }
        }            
    }
public function filterFileName($fileName) {
    $newstr = preg_replace('/[^a-zA-Z0-9\-\.\']/', '_', $fileName[0]);
    $fileName = str_replace("'", '', $newstr);
    return $fileName;       
}

, после этого вам необходимо сохранить эти вложения

0 голосов
/ 17 сентября 2018

спасибо ИВО ГЕЛОВУ за обнаружение моей ошибки.конечная рабочая функция:

function parse_parts(&$structure, &$attachments, &$imap, $m, $par){
if(isset($structure->parts) && count($structure->parts) ) {
    for($i = 0; $i < count($structure->parts); $i++) {
        $attachments[] = array(
            'is_attachment' => false,
            'filename' => '',
            'name' => '',
            'attachment' => ''
        );
        $lstk= array_keys($attachments);  $j=end($lstk); // use this instead of $i to avoid overlapping indices when there's sub-parts and recursion

        if($structure->parts[$i]->ifdparameters) {
            foreach($structure->parts[$i]->dparameters as $object) {
                if(strtolower($object->attribute) == 'filename') {
                    $attachments[$j]['is_attachment'] = true;
                    $attachments[$j]['filename'] = $object->value;
                }
            }
        }
        if($structure->parts[$i]->ifparameters) {
            foreach($structure->parts[$i]->parameters as $object) {
                if(strtolower($object->attribute) == 'name') {
                    $attachments[$j]['is_attachment'] = true;
                    $attachments[$j]['filename'] = imap_utf8($object->value);
                }
            }
        }
        if($attachments[$j]['is_attachment']) {
            if($par==''){
                $attachments[$j]['attachment'] = imap_fetchbody($imap, $m,  ($i+1));
            }else{
                $attachments[$j]['attachment'] = imap_fetchbody($imap, $m,  $par . ($i+1));
            }
            if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
                $attachments[$j]['attachment'] = base64_decode($attachments[$j]['attachment']);
            }
            elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
                $attachments[$j]['attachment'] = quoted_printable_decode($attachments[$j]['attachment']);
            }else{echo "encod:". $structure->parts[$i]->encoding . PHP_EOL; }
        } 
        if(isset($structure->parts[$i]->parts) && count($structure->parts[$i]->parts)){ //if the part contains its own parts, recurse
             $prnt = $i+1;
             $prnt = $prnt . '.';
             parse_parts($structure->parts[$i], $attachments, $imap, $m, $prnt );    
        }
    }
}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...