Search code examples
phpmacosemailimap

How to read Apple Mail custom IMAP flags with PHP?


On Mac Mail, you can set flags Red, Orange, Yellow, Green, Blue, Purple, Gray. On iOS and most other email clients, whichever flag you choose, it ends up Red.

However, the flag colors are kept on other Macs with the same email account, so I assume it must be saved on the IMAP-server. This might be called keyword/custom flags, but I can't find any documentation on it.

This code returns an object containg the IMAP data for the oldest message in the inbox:

$imap = imap_open("{".$server.":143}INBOX", "$email", "$password");
$header = imap_header($imap, 1);
echo "".nl2br(var_dump($header))."";

If I flag the message, in any color, this part changes, but always "F" no matter what color I choose.

["Flagged"]=> string(1) "F"

By using imap_fetch_overview() i get this (0 for no flag, 1 for any flag)

["flagged"]=> int(1)

I found this: "these are implemented (by Apple) using 3 IMAP keywords as bits (providing 8 different states although only 7 are used I believe)." http://lists.freron.com/mailmate/2015-January/003578.html

But I can't find anything that changes in the data that looks like any bits related to "FLAGGED". Where in IMAP is Mac Mail storing this and how do I read it with PHP?


Solution

  • Actually you are not able to do so using standard imap extension as it is impossible to fetch custom flags using it. You can try some 3rd party IMAP implementantion or manage to write it on your own using sockets.

    Zend_Mail_Protocol_Imap, which is a part of Zend_Framework, has own IMAP implementation which supports custom comands. Using it you can simply:

    $imap = new Zend_Mail_Protocol_Imap($server, 143);
    $imap->login($email, $password);
    $imap->select('INBOX'); 
    
    $flags = $imap->fetch('FLAGS', 1);
    var_dump($flags);
    

    You'll get something like:

    array(5) {
        [0] => string(8) "\Flagged"
        [1] => string(5) "\Seen"
        [2] => string(8) "$NotJunk"
        [3] => string(13) "$MailFlagBit0"
        [4] = >string(13) "$MailFlagBit1"
    }
    

    As you can see $MailFlagBit0 and $MailFlagBit1 are set, so according to link you posted this message has a yellow flag (this is actually not true - I've picked green).

    I've made some test and this is how flag colors are determined:

    • (0b000) red - none of $MailFlagBit0, $MailFlagBit1 and $MailFlagBit3 set

    • (0b001) orange - only $MailFlagBit0 set

    • (0b010) yellow - only $MailFlagBit1 set

    • (0b011) green - $MailFlagBit0 and $MailFlagBit1 set

    • (0b100) blue - only $MailFlagBit2 set

    • (0b101) purple - $MailFlagBit0 and $MailFlagBit2 set

    • (0b110) gray - $MailFlagBit1 and $MailFlagBit2 set