EllisLab text mark
Advanced Search
1 of 2
1
   
New IMAP library!
Posted: 06 April 2009 03:36 PM
Joined: 2008-07-31
194 posts

I wrote a library to perform some basic Imap functions. I saw some throughout the forum but they didn’t seem to work right for me. This can be used with Gmail, Yahoo, or your own shared hosting email setup (as long as you have server access). The main reason I wrote is pretty cool if I must say so myself smile I don’t have shell access on my server but I wanted people to be able to email me and have my PHP code take those emails and do stuff with them. Well without using a forward script, I’m using this library in a PHP cron job that checks for new mail and takes the date, subject, body, etc. from the email and store it in a database as I please. The functions I have right now are:

- connect()
- current_mailbox()
- msg_count()
- delete()
- mailbox_info()
- switch_mailbox()
- search()
- msg_list()


The functions are quite simple to understand but you will probably have to read up on the different flags that PHP’s Imap functions accept. Other than that, let me know if you have any problems. Enjoy!

http://www.gandylabs.com/ci/imap

 Signature 

Spam Helper | Html Helper | GPoll Library | IMAP Library

 
Posted: 06 April 2009 04:51 PM   [ # 1 ]   [ Rating: 0 ]
Avatar
Joined: 2006-08-06
918 posts

hey, this is great work! and your docs are really spiffy smile

a few things you may want to ignore:
1) i don’t see any decoding in the class - assuming that is left as an exercise for the reader? guaranteed that is the first question you are going to get about this: “why does the subject of the email say =?UTF8?Q?my_subject_here?=”
2) i think you can cast an object to an array and the property names become keys - shorter code for the conversion routine

the imap_pop class on the wiki is focused more on POP functionality (built originally for a moblog) than IMAP so it’s good to see how you approached wrapping the pure IMAP functions. if you are interested, the imap_pop class at the wiki shows how to do attachments and decoding. there is also a utility there that will parse any header string into a nested array of ALL headers instead of just the ones the IMAP class decides you should have.

looking forward to seeing where you take this.

 Signature 

peeker email (imap/pop) | site_migrate | OOCalendar | PhotoBox2 | word_limiter

 
Posted: 06 April 2009 04:56 PM   [ # 2 ]   [ Rating: 0 ]
Joined: 2008-07-31
194 posts

Thanks. I’ll look into the object->array conversion. As far as the decoding goes, there’s none needed. The only decoding that’s done is the “body” element when calling msg_list(). I take the actual body of the email instead of the entire body which includes the specific stuff.

 Signature 

Spam Helper | Html Helper | GPoll Library | IMAP Library

 
Posted: 06 April 2009 05:11 PM   [ # 3 ]   [ Rating: 0 ]
Avatar
Joined: 2006-08-06
918 posts

you won’t need decoding if you are only getting emails that don’t have encoded subjects, address (personal component), and other header items.

see here: http://en.wikipedia.org/wiki/MIME in the section on Encoded-Word format for more detail.

cheers.

 Signature 

peeker email (imap/pop) | site_migrate | OOCalendar | PhotoBox2 | word_limiter

 
Posted: 06 April 2009 05:50 PM   [ # 4 ]   [ Rating: 0 ]
Joined: 2008-07-31
194 posts
sophistry - 06 April 2009 09:11 PM

you won’t need decoding if you are only getting emails that don’t have encoded subjects, address (personal component), and other header items.

see here: http://en.wikipedia.org/wiki/MIME in the section on Encoded-Word format for more detail.

cheers.

Yeah the Imap functionality I’m using in PHP is parsing the properties without using the 822 decoding. Certain properties don’t get sent when parsing the headers with rfc822 such as flags, the message #, the size, and the Unix date. I figure those are more important. I’ll just make it an optional parameter.

 Signature 

Spam Helper | Html Helper | GPoll Library | IMAP Library

 
Posted: 06 April 2009 06:12 PM   [ # 5 ]   [ Rating: 0 ]
Avatar
Joined: 2006-08-06
918 posts

actually it’s not RFC822, but RFC2047 i was referring to… as far as the encoded subject and personal component of the from address. get the library “out in the wild” (receiving messages from various people and email clients) and you’ll see what i am talking about.

but, i tend to over-engineer things like this! maybe the “don’t anticipate too much too soon” approach is better?

 Signature 

peeker email (imap/pop) | site_migrate | OOCalendar | PhotoBox2 | word_limiter

 
Posted: 06 April 2009 06:38 PM   [ # 6 ]   [ Rating: 0 ]
Joined: 2008-07-31
194 posts
sophistry - 06 April 2009 10:12 PM

actually it’s not RFC822, but RFC2047 i was referring to… as far as the encoded subject and personal component of the from address. get the library “out in the wild” (receiving messages from various people and email clients) and you’ll see what i am talking about.

but, i tend to over-engineer things like this! maybe the “don’t anticipate too much too soon” approach is better?

Ohhh, I’ve already taken care of that. You can either use “fromaddress” index which simply returns the email address OR use the “from” index which is actually Another array with the following indexes: personal, adl, mailbox, and host.

 Signature 

Spam Helper | Html Helper | GPoll Library | IMAP Library

 
Posted: 06 April 2009 07:44 PM   [ # 7 ]   [ Rating: 0 ]
Avatar
Joined: 2006-08-06
918 posts

yes, and sometimes the ‘personal’ array index is “Word-Encoded” per RFC2047 so you have to decode it using quoted_printable_decode() or base64_decode() - it will be one or the other if it is encoded. most of the time it won’t be encoded, but it’s safer to detect encodings and handle every personal field as if it is encoded.

the subject data has the same issue.

as a test (to show what i am talking about), use the CI email class to send yourself an email. the CI class encodes the subject in UTF8 quoted printable. when you pick it up with your regular email client (say outlook or whatever) the email client decodes it for you without asking. but in your IMAP class, if you don’t decode it, it is almost unreadable.

 Signature 

peeker email (imap/pop) | site_migrate | OOCalendar | PhotoBox2 | word_limiter

 
Posted: 06 April 2009 08:03 PM   [ # 8 ]   [ Rating: 0 ]
Avatar
Joined: 2007-06-10
2937 posts
sophistry - 06 April 2009 08:51 PM

... this is great work! and your docs are really spiffy smile

+1

Good work Iverson.

 Signature 

URI Language Identifier | Modular Extensions - HMVC | View Object | Widget plugin | Access Control library

 
Posted: 06 April 2009 08:38 PM   [ # 9 ]   [ Rating: 0 ]
Joined: 2008-07-31
194 posts

Decoding should now be taken care of. Also, I’m now using PHP’s native ability to create an associative array of defined object accessible non-static properties. Thanks sophistry.

 Signature 

Spam Helper | Html Helper | GPoll Library | IMAP Library

 
Posted: 07 April 2009 12:11 PM   [ # 10 ]   [ Rating: 0 ]
Avatar
Joined: 2006-08-06
918 posts

i think you misunderstood my suggestion about quoted_printable_decode(). i see you’ve added a class method _quoted_printable_encode() which does some limited transformation of urlencoded text (using str_replace()) and then runs a preg_replace() looking for “not newline chars” and replacing them with equals signs (some kind of word wrapping routine?). but, that code doesn’t make sense there. that’s the sort of thing you would do to prepare an email to send, not to receive… and the fact that it is named encode rather than decode? i’m not sure what issue the code solves at that point - it seems extra. is there something i am missing?

did you send yourself an email from the CI email lib and look at the source of the email to see the way the CI email lib prepares a quoted_printable encoded subject?

 Signature 

peeker email (imap/pop) | site_migrate | OOCalendar | PhotoBox2 | word_limiter

 
Posted: 28 June 2009 12:36 PM   [ # 11 ]   [ Rating: 0 ]
Joined: 2008-06-09
23 posts

i get this error when i try to connect:

“Certificate failure for mail.domain.com: self signed certificate: blah blah blah”

can anybody help?

 Signature 

one… take control of me… you’re messing with the enemy… said it’s two… it’s another trick… messing with my mind i wake up…

 
Posted: 29 June 2009 12:50 PM   [ # 12 ]   [ Rating: 0 ]
Avatar
Joined: 2006-08-06
918 posts

add novalidate-cert to your service flags.

see http://www.php.net/imap-open for more info.

 Signature 

peeker email (imap/pop) | site_migrate | OOCalendar | PhotoBox2 | word_limiter

 
Posted: 28 September 2009 10:58 AM   [ # 13 ]   [ Rating: 0 ]
Joined: 2009-09-24
14 posts

Thanks for this code, it works really well. The only issue I have is that when i ask for a list of the messages so that i can show an overview on the inbox, it marks all the messages as read, is there a way to get a the list of messages without it marking them all read?

cheers

$this->data['title'"Optra Mail";
        
$this->data['connected'FALSE;
        
$this->load->view('header_view',$this->data);
        
$this->load->view('pagetop_view',$this->data);
        
$this->load->library('imap');
        
// build login data
        
$query=$this->db->get_where("users",array('users.id' => $this->session->userdata('id')));
        
$userdata $query->row();

        if(
$this->imap->connect($userdata->email_user.'+vdomain.net'$userdata->password"vdomain.net"))
        
{
            $this
->data['connected'TRUE;
            
$this->data['mailbox'$this->imap->mailbox_info('array');
            
$this->data['messages'$this->imap->msg_list();
        
}


        $this
->load->view('email_view',$this->data);
        
$this->load->view('footer_view',$this->data); 
 
Posted: 28 September 2009 11:18 AM   [ # 14 ]   [ Rating: 0 ]
Avatar
Joined: 2006-08-06
918 posts

hi promaneX welcome to CI!

i pulled this function out of my imap_pop class to show you how it could be done:

// loop over the messages by hand
// may be the best function to use
// to allow user feedback (i.e., progress bar)
function get_message_list_loop($start=0$end=0)
{    
    $a 
= array();
    
    
// start is the id
    // start it one down
    // because id immediately
    // increments in the next loop
    
$id = ($start==0) ? $start-1;
    
$end = ($end==0) ? $this->msg_count $end;

    while (
$id++ < $end)
    
{
        $a[] 
imap_headerinfo($this->IMAP_resource$id);
        
// it is not faster to use imap_fetchheader
        //$a[] = imap_fetchheader($this->IMAP_resource, $id);
    
}
    
return $a;
 Signature 

peeker email (imap/pop) | site_migrate | OOCalendar | PhotoBox2 | word_limiter

 
Posted: 28 September 2009 11:29 AM   [ # 15 ]   [ Rating: 0 ]
Joined: 2009-09-24
14 posts

Thanks for the fast reply, sophistry! I will try to integrate that into my code :D

thanks again

 
1 of 2
1