tags:

views:

1037

answers:

3

I am working on a script that downloads emails and stores them in a db, I usually receive thousands of emails on this account, once downloaded the mails are deleted.

Being paranoic, I want to have at least one month backup of my emails, but I cannot clutter my main mailbox address leaving them in there.

So i need to move the mails (via php code) from one mailbox to another. I came up with this solution that uses imap_append(). This solution, however recreates the email, and does not really move it.

Do you have any suggestions or alternative ways of doing this?

Remember: it must be done in php, because I need to integrate it in my readmail script.

I have already seen this thread where a fetchmail solution was proposed

Here follows the code I wrote for this task

<?php
/**
* Conn params
*/

$fromMboxServerPath = "{imap.from.server/notls/imap:143}";
$fromMboxMailboxPath = "INBOX";
$fromMboxMailAddress = "login";
$fromMboxMailPass = "pass";


$toMboxServerPath = "{imap.to.server/notls/imap:143}";
$toMboxMailboxPath = "INBOX";
$toMboxMailAddress = "login";
$toMboxMailPass = "pass";

$fromMboxConnStr = $fromMboxServerPath.$fromMboxMailboxPath;
$toMboxConnStr = $toMboxServerPath.$toMboxMailboxPath;

$fetchStartSeq = 1;
$fetchEndSeq = 10;

function myLog($str)
{
    echo "Log [".date('Y-m-d H:i:s')."]: $str\n";
}

myLog("Connecting to mailbox");

function mboxConn($connstr,$addr,$pass)
{
    if(!($mbox = @imap_open($connstr, $addr, $pass)))
    {
        myLog("Error: ".imap_last_error());
        die;
    }
    else
    {
        myLog("Connected to: $addr $connstr");
        return $mbox;
    }
}

function mboxCheck($mbox)
{
    if(!($mbox_data = imap_check($mbox)))
    {
       myLog("Error: ".imap_last_error());
       die;   
    }
    else
    {
        myLog("Mailbox check ".$mbox_data->Mailbox." OK");
        myLog($mbox_data->Nmsgs." messages present");
        return $mbox_data->Nmsgs;
    }
}

$fromMbox = mboxConn($fromMboxConnStr, $fromMboxMailAddress, $fromMboxMailPass);
$toMbox = mboxConn($toMboxConnStr, $toMboxMailAddress, $toMboxMailPass);

$fromMboxCount = mboxCheck($fromMbox);
$toMboxCount = mboxCheck($toMbox);

/**
* Loop on mails
*/

$fetchStartUID = imap_uid($fromMbox,$fetchStartSeq);
if ($fromMboxCount < $fetchEndSeq)
{
    $fetchEndSeq = $fromMboxCount;
}
$fetchEndUID = imap_uid($fromMbox,$fetchEndSeq);

/**
* Loop on mails
*/

myLog("Do stuff and backup from UID [$fetchStartUID] to UID [$fetchEndUID]");

for ($i=$fetchStartSeq;$i<=$fetchEndSeq;$i++)
{
    $pfx = "Msg #$i : ";
    $h = imap_header($fromMbox, $i);
    $fh = imap_fetchheader($fromMbox, $i);
    $fb = imap_body($fromMbox, $i);
    $message = $fh.$fb;

    $msgUID = imap_uid($fromMbox,$i);

    $struct = imap_fetchstructure ($fromMbox, $i);

    /**
     * We do some logging
     */

    myLog($pfx."UID [".$msgUID."] SEQ [".imap_msgno($fromMbox,$msgUID)."] Flags: [". $h->Unseen . $h->Recent . $h->Deleted . $h->Answered . $h->Draft . $h->Flagged."]");
    myLog($pfx."From: [". htmlspecialchars($h->fromaddress) . "] To: [".htmlspecialchars($h->toaddress)."]");
    myLog($pfx."Subject: [$h->subject]");

    /**
     * Here you do whaterver you need with your email
     */

    /**
     * Backup email
     */
    if (!($ret = imap_append($toMbox,$toMboxServerPath.$toMboxMailboxPath,$message))) 
    {
        myLog("Error: ".imap_last_error());
        die;
    }
    else
    {
        myLog("everything ok, mail [$fetchStartUID:$fetchEndUID] downloaded and moved in $newMailboxNameMOVE");
    }
}

/**
* End
*/

imap_close($fromMbox);
imap_close($toMbox);

myLog("Connection closed");

?>
A: 

Why separate account and all the hassle that will be involved? Can't you either

a) backup the mail account using standard backup tools like, eg. rdiff-backup?

b) back them up in the db?

or even

c) create an alias so that emails go to both accounts and you have different criteria for removing mails from both accounts (ie. keep them for one more month in the backup account)

tpk
A: 

tpk, i need to keep my backup emails in a mail account so (in case of emergency) i can retreive them from the same script I use to download them.

This script contains a lot of header/subject/body controls using imap_* functions so I cannot simply store them in a database without writing an all new script to fetch them from db.

I am looking for a programmatical solution to this.

Anonymous
+1  A: 

First, IMAP does not have a MOVE command only copy but even if it did you can copy from one IMAP server to another directly.

Why not use a subfolder in the account for backups. Download them to your local machine then COPY them to the subfolder and then DELETE them from the INBOX.

COPY and DELETE are imap server side commands so they don't have to leave the server to do the "move"

If both accounts are on the same server there is another option, allow access to the backup account's INBOX to the primary account user. Then you can use server side copy/delete to move it to the backup folder.

Not all IMAP servers allow for shared folders.

php does have a imap_move function but I assume it does a copy/delete.

Craig