phpimapapple-mail

imap - get attached file


How do I get the attached file from this email?

This email is sent from an apple computer and the email struture is not like any other (surprise).. here the part with the disposition is one dimension deeper than else..

The script works with every other email where the part with the file is in the first dimension, but not with this one

$part->dparameters[0]->value returns the file name, but strlen($data) returns 0

imap stream

$structure = imap_fetchstructure($this->stream, $this->msgno);

if(isset($structure->parts)){
    print_r($structure->parts);
    $this->parse_parts($structure->parts);
}

function parse_parts($parts){
    foreach($parts as $section => $part){
        if(isset($part->parts)){

            // some mails have one extra dimension
            $this->parse_parts($part->parts);

        }
        elseif(isset($part->disposition)){
            if(in_array(strtolower($part->disposition), array('attachment','inline'))){
                $data = imap_fetchbody($this->stream, $this->msgno, $section+1);
                echo $part->dparameters[0]->value.' '.strlen($data)."\n";
            }
        }
    }
}

print_r

Array
(
    [0] => stdClass Object
        (
            [type] => 0
            [encoding] => 0
            [ifsubtype] => 1
            [subtype] => PLAIN
            [ifdescription] => 0
            [ifid] => 0
            [lines] => 15
            [bytes] => 173
            [ifdisposition] => 0
            [ifdparameters] => 0
            [ifparameters] => 1
            [parameters] => Array
                (
                    [0] => stdClass Object
                        (
                            [attribute] => CHARSET
                            [value] => us-ascii
                        )

                )

        )

    [1] => stdClass Object
        (
            [type] => 1
            [encoding] => 0
            [ifsubtype] => 1
            [subtype] => MIXED
            [ifdescription] => 0
            [ifid] => 0
            [bytes] => 23420
            [ifdisposition] => 0
            [ifdparameters] => 0
            [ifparameters] => 1
            [parameters] => Array
                (
                    [0] => stdClass Object
                        (
                            [attribute] => BOUNDARY
                            [value] => Apple-Mail=_800896E0-A9C9-456E-B063-79CED9DD4FD7
                        )

                )

            [parts] => Array
                (
                    [0] => stdClass Object
                        (
                            [type] => 0
                            [encoding] => 0
                            [ifsubtype] => 1
                            [subtype] => HTML
                            [ifdescription] => 0
                            [ifid] => 0
                            [bytes] => 136
                            [ifdisposition] => 0
                            [ifdparameters] => 0
                            [ifparameters] => 1
                            [parameters] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [attribute] => CHARSET
                                            [value] => us-ascii
                                        )

                                )

                        )

                    [1] => stdClass Object
                        (
                            [type] => 3
                            [encoding] => 3
                            [ifsubtype] => 1
                            [subtype] => PDF
                            [ifdescription] => 0
                            [ifid] => 0
                            [bytes] => 17780
                            [ifdisposition] => 1
                            [disposition] => INLINE
                            [ifdparameters] => 1
                            [dparameters] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [attribute] => FILENAME
                                            [value] => 057 - LPJ - Stik og labels.pdf
                                        )

                                )

                            [ifparameters] => 1
                            [parameters] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [attribute] => NAME
                                            [value] => 057 - LPJ - Stik og labels.pdf
                                        )

                                )

                        )

                    [2] => stdClass Object
                        (
                            [type] => 0
                            [encoding] => 4
                            [ifsubtype] => 1
                            [subtype] => HTML
                            [ifdescription] => 0
                            [ifid] => 0
                            [lines] => 75
                            [bytes] => 4931
                            [ifdisposition] => 0
                            [ifdparameters] => 0
                            [ifparameters] => 1
                            [parameters] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [attribute] => CHARSET
                                            [value] => us-ascii
                                        )

                                )

                        )

                )

        )

)

Solution

  • You are not providing the correct section number for nested attachments. You need to pass in the section number in the recursive step.

    function parse_parts($parts, $parentsection = ""){
        foreach($parts as $subsection => $part){
            $section = $parentsection . ($subsection + 1);
            if(isset($part->parts)){
    
                // some mails have one extra dimension
                $this->parse_parts($part->parts, $section . "." );
    
            }
            elseif(isset($part->disposition)){
                if(in_array(strtolower($part->disposition), array('attachment','inline'))){
                    $data = imap_fetchbody($this->stream, $this->msgno, $section );
                    echo 'Getting section ' . $section;
                    echo $part->dparameters[0]->value.' '.strlen($data)."\n";
                }
            }
        }
    }
    

    (Untested, but should do the right thing...)