compcobalt
compcobalt

Reputation: 1362

PHP - IMAP: Save Attachment to Specific Folder

I found this code that works almost great but I need it to:

1. (MUST) Save the attachments to a specific folder on the server and not where the .php file is.

2. (IF POSSIBLE) Right now the code generates some files that are Zero bytes in size. (I can write something that checks the file-size and then deletes the files that are Zero in size but I would like to stop it from being created in the first place if possible.

 <?php

    function getFileExtension($fileName){
       $parts=explode(".",$fileName);
       return $parts[count($parts)-1];
    }

    $imap = imap_open($server, $username, $password) or die("imap connection error");
    $message_count = imap_num_msg($imap);
    for ($m = 1; $m <= $message_count; ++$m){

        $header = imap_header($imap, $m);
        //print_r($header);

        $email[$m]['from'] = $header->from[0]->mailbox.'@'.$header->from[0]->host;
        $email[$m]['fromaddress'] = $header->from[0]->personal;
        $email[$m]['to'] = $header->to[0]->mailbox;
        $email[$m]['subject'] = $header->subject;
        $email[$m]['message_id'] = $header->message_id;
        $email[$m]['date'] = $header->udate;

        $from = $email[$m]['fromaddress'];
        $from_email = $email[$m]['from'];
        $to = $email[$m]['to'];
        $subject = $email[$m]['subject'];

        echo $from_email . '</br>';
        echo $to . '</br>';
        echo $subject . '</br>';

        $structure = imap_fetchstructure($imap, $m);

        $attachments = array();
        if(isset($structure->parts) && count($structure->parts)) {

            for($i = 0; $i < count($structure->parts); $i++) {

                $attachments[$i] = array(
                    'is_attachment' => false,
                    'filename' => '',
                    'name' => '',
                    'attachment' => ''
                );

                if($structure->parts[$i]->ifdparameters) {
                    foreach($structure->parts[$i]->dparameters as $object) {
                        if(strtolower($object->attribute) == 'filename') {
                            $attachments[$i]['is_attachment'] = true;
                            $attachments[$i]['filename'] = $object->value;
                        }
                    }
                }

                if($structure->parts[$i]->ifparameters) {
                    foreach($structure->parts[$i]->parameters as $object) {
                        if(strtolower($object->attribute) == 'name') {
                            $attachments[$i]['is_attachment'] = true;
                            $attachments[$i]['name'] = $object->value;
                        }
                    }
                }

                if($attachments[$i]['is_attachment']) {
                    $attachments[$i]['attachment'] = imap_fetchbody($imap, $m, $i+1);
                    if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
                        $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
                    }
                    elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
                        $attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
                    }
                }
            }
        }

        foreach ($attachments as $key => $attachment) {
            $name = $attachment['name'];
            $contents = $attachment['attachment'];
            file_put_contents($name, $contents);
        }

        //imap_setflag_full($imap, $i, "\\Seen");
        //imap_mail_move($imap, $i, 'Trash');
    }

    imap_close($imap);

    ?>

Upvotes: 1

Views: 7288

Answers (3)

Joao Pessolato
Joao Pessolato

Reputation: 11

You can put the file directly on your desired path like this:

$mypath = '../../myfiles/';
foreach ($attachments as $attachment) {
           file_put_contents( $mypath . $attachment['name'], $attachment['attachment']);
 }

Upvotes: 1

Replace

foreach ($attachments as $key => $attachment) {
            $name = $attachment['name'];
            $contents = $attachment['attachment'];
            file_put_contents($name, $contents);
}

with

 foreach ($attachments as $attachment) {
           file_put_contents($attachment['name'], $attachment['attachment']);
 }

and it will save your attachment to your root, from there you can move it as you wish.

Upvotes: 0

Shobi
Shobi

Reputation: 11451

You can write the file to any folder you like, The rename() function can be used for this purpose

http://php.net/manual/en/function.rename.php

rename('image1.jpg', 'del/image1.jpg');

If you want to keep the existing file in the same place you should use copy

http://php.net/manual/en/function.copy.php

copy('image1.jpg', 'del/image1.jpg');

you can use the code after you put_file_contents() to move the file around directories/folders

EDIT: Create file in another directory rather than moving it around after creation

file_put_contents('./myDir/myFile', $file);

Where the . represents the current directory of your project.

Also, remember file_put_contents() does not create folders/directories they need to be existing or you need to create it using mkdir()

Upvotes: 2

Related Questions