Search code examples
phpimap

PHP IMAP function to detach attachment and save to a directory


I'm trying to use IMAP function to detach an attachment received from inbox and save into the server directory specified.

I am doing this for all UNSEEN messages but the problem is that it only does for one message only.

Below is the code (I deleted $host,$login,$password variables for obvious reasons):

$type = 'ReadAttachment';
    $obj = new $type;
    $obj->getdata($host,$login,$password,$savedirpath,$delete_emails=false);
    class ReadAttachment
    {

        function getdecodevalue($message,$coding) {
            switch($coding) {
                case 0:
                case 1:
                    $message = imap_8bit($message);
                    break;
                case 2:
                    $message = imap_binary($message);
                    break;
                case 3:
                case 5:
                    $message = imap_base64($message);
                    break;
                case 4:
                    $message = imap_qprint($message);
                    break;
            }
            return $message;
        }


        function getdata($host,$login,$password,$savedirpath,$delete_emails=false, $read_type="UNSEEN") {
            // make sure save path has trailing slash (/)
            //print_r("test");
            $savedirpath = str_replace('\\', '/', $savedirpath);
            if (substr($savedirpath, strlen($savedirpath) - 1) != '/') {
                $savedirpath .= '/';
            }

            $mbox = imap_open ($host, $login, $password) or die("can't connect: " . imap_last_error());
            $message = array();
            $message["attachment"]["type"][0] = "text";
            $message["attachment"]["type"][1] = "multipart";
            $message["attachment"]["type"][2] = "message";
            $message["attachment"]["type"][3] = "application";
            $message["attachment"]["type"][4] = "audio";
            $message["attachment"]["type"][5] = "image";
            $message["attachment"]["type"][6] = "video";
            $message["attachment"]["type"][7] = "other";
            //print_r($message);
            $emails = imap_search($mbox,$read_type) or die(print_r(imap_last_error()));
            print_r($emails);

            $e = imap_search($mbox,$read_type, SE_UID) or die(print_r(imap_last_error()));
            print_r($e);
            $i=0;
            foreach($emails as $email_number) {
                $structure = imap_fetchstructure($mbox, $e[$i] , FT_UID) or die(print_r(imap_last_error()));
                $parts = $structure->parts;
                $fpos=2;
                for($i = 1; $i < count($parts); $i++) {
                    $message["pid"][$i] = ($i);
                    $part = $parts[$i];

                    if($part->disposition == "attachment") {
                        $message["type"][$i] = $message["attachment"]["type"][$part->type] . "/" . strtolower($part->subtype);
                        $message["subtype"][$i] = strtolower($part->subtype);
                        $ext=$part->subtype;
                        $params = $part->dparameters;
                        $filename=$part->dparameters[0]->value;

                        $mege="";
                        $data="";
                        $mege = imap_fetchbody($mbox,$email_number,$fpos);  
                        $filename="$filename";
                        $fp=fopen($savedirpath.$filename,"w");
                        $data=$this->getdecodevalue($mege,$part->type);
                        //print_r($mege);
                        fputs($fp,$data);
                        fclose($fp);
                        $fpos+=1;
                    }
                }
                ++$i;
            }
            // imap_expunge deletes all tagged messages

            imap_close($mbox);
        }
    }

Is there something that I could change above?


Solution

  • I'm not sure whether this is the cause of the problem, or if I even understood your code correctly. However I think your $i=0 needs to go inside the foreach loop, and you need to lose the ++$i at the end.

    Let's go through it. First, you set $i=0. foreach gets the first message and enters the for loop, which iterates over incrementing values of $i. Let's say that $i is set to 4 when the for loop ends. At that point, ++$i sets it to 5. The foreach iteration ends and the next email should be processed. But this does not happen because $i is still 5, so when you do:

    $structure = imap_fetchstructure($mbox, $e[$i] , FT_UID)
    

    You are picking the wrong email.