This is a function I wrote a while back so I could access more of the
headers available in a mail message.  The imap_headers and
imap_fetchheaders functions work fine for retrieving headers for the
main body of a given message, but if you receive an email with an
attachment which is itself an email message  (ie. mime type
'message/rfc822'), you can use this function to retrieve the (raw)
headers for the attached message.

An example:

    $headers = imap_fetch_header($mbox, 2, '1.2', '', FT_PEEK);
    $headers = imap_mime_header_decode($headers);
    $headers = $headers[0]->text;
    $headers = imap_rfc822_parse_headers($headers,
$default->from_server);

This would give you the headers (if any) for an attached email message
at part 1.2, and in the same (or close to the same) object format as
imap_headerinfo...

Perhaps the imap_fetchbody function can be used to the same effect, but
I would have to agree that it is broken, and the documentation should be
modified to reflect it's use in this respect:
> rfinnie at kefta dot com
> 14-Dec-2000 02:23
>
> With regard to message/rfc822 parts, it appears that the IMAP c-client
that
> PHP uses does not follow the IMAP RFC (#2060) correctly.  The RFC
> specifies that to grab the headers for a message/rfc822 part, you
would
> request part "2.HEADER" (assuming 2 is your part number), and
> the full text of the part would be "2.TEXT".  Instead,
> "2.0" will grab the headers, and just "2" will get the
> text.
I don't think it is the c-Client lib that is broken here, but the PHP
implementation.  Perhaps this has been fixed since I wrote this...

Anyway, if someone has a better way to do this than adding this function
to PHP (ie. with the existing functions), please let me know.
Otherwise, I think it would be a valuable addition, so am donating it
for whoever wishes to add it to the IMAP module.

-Brad

------------------ Begin Code ---------------------

/* BF 7/25/00 ([EMAIL PROTECTED]) Added to allow more advanced header
fetching */
/* {{{ proto string imap_fetch_header(int stream_id, int msg_no [,
string section [, array lines [, int options]]])
   Get the (optionally filtered) header for a given section of a message

   NOTE: You need to explicitly set FT_PEEK to not mark message as READ
when calling this function.
   Empty strings are ignored in the lines array.
*/
PHP_FUNCTION(imap_fetch_header)
{
        zval **streamind, **msgno, **sec = NIL, **lines = NIL, **flags,
**tmp;
        int i, ind, ind_type, msgindex;
        pils *imap_le_struct;
        int myargc = ZEND_NUM_ARGS();
        HashPosition pos;
        STRINGLIST *cur_lines = NIL, *cur;

        if (myargc < 2 ||
            myargc > 5 ||
            zend_get_parameters_ex(myargc, &streamind, &msgno, &sec,
&lines, &flags) == FAILURE)
        {
                ZEND_WRONG_PARAM_COUNT();
        } //if

        convert_to_long_ex(streamind);
        convert_to_long_ex(msgno);

        if (myargc > 2) {
                convert_to_string_ex(sec);
        } //if

        /* Convert the <lines> array to a STRINGLIST */
        if (myargc > 3) {
                convert_to_array_ex(lines);

                zend_hash_internal_pointer_reset_ex((*lines)->value.ht,
&pos);
                while (zend_hash_get_current_data_ex((*lines)->value.ht,
(void **) &tmp, &pos) == SUCCESS) {
                        convert_to_string_ex(tmp);

                        // Only add to the filter list if not an empty
string
                        if (*Z_STRVAL_PP(tmp)) {
                                if (cur_lines) {
                                        cur->next =
mail_newstringlist();
                                        cur = cur->next;
                                } else {
                                        cur_lines =
mail_newstringlist();
                                        cur = cur_lines;
                                } //if

                                cur->LSIZE = (*tmp)->value.str.len;
                                cur->LTEXT = (char*)
cpystr((*tmp)->value.str.val);
                        } //if

                        zend_hash_move_forward_ex((*lines)->value.ht,
&pos);
                } //while
        } //if

        if (myargc == 5) {
                convert_to_long_ex(flags);
        } //if
        ind = Z_LVAL_PP(streamind);

        imap_le_struct = (pils *) zend_list_find(ind, &ind_type);
//      if (!imap_le_struct || !IS_STREAM(ind_type)) {
        if (!imap_le_struct) {
                php_error(E_WARNING, "Unable to find stream pointer");
                RETURN_FALSE;
        } //if

        if ((myargc == 5) && (Z_LVAL_PP(flags) & FT_UID)) {
        /* This should be cached; if it causes an extra RTT to the
           IMAP server, then that's the price we pay for making sure
           we don't crash. */
                msgindex = mail_msgno(imap_le_struct->imap_stream,
Z_LVAL_PP(msgno));
        } else {
                msgindex = Z_LVAL_PP(msgno);
        } //if
        if ((msgindex < 1) || ((unsigned) msgindex >
imap_le_struct->imap_stream->nmsgs)) {
                php_error(E_WARNING, "Bad message number");
                RETURN_FALSE;
        } //if

        /* Perform the header fetch */
        RETVAL_STRING(mail_fetch_header(imap_le_struct->imap_stream,
Z_LVAL_PP(msgno), Z_STRVAL_PP(sec),
                                        cur_lines, NIL, myargc==5 ?
Z_LVAL_PP(flags) : NIL), 1);

        /* Free the temporary string list */
        mail_free_stringlist(&cur_lines);
} // PHP_FUNCTION(imap_fetch_header)
/* }}} */



-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to