-
Notifications
You must be signed in to change notification settings - Fork 7.6k
IMAP POP3 Wrapper Class
Here's a basic example:
try this out in a controller after dropping the file named imap_pop3.php into the libraries dir: [code] $this->load->library('imap_pop3'); // settings for gmail, you must have // SSL support compiled into PHP // and turn on POP in gmail $config['server']='pop.gmail.com:995'; $config['login']='[email protected]'; $config['pass']='password'; $config['service_flags'] = '/pop3/ssl/novalidate-cert'; $config['mailbox']='INBOX'; $msg_count = $this->imap_pop3->connect_and_count($config); $em = $this->imap_pop3->grab_email_as_array(1); $this->imap_pop3->close(); print_r($em); [/code]
And the class:
[code] <? if (!defined('BASEPATH')) exit('No direct script access allowed'); /*
An interface for the PHP IMAP functions Grabs email messages from a POP3 or IMAP account so they can be put into a database
This code's only link to a database is the nested associative array built in the grab_email_as_array() function - it serves as a rudimentary 'interface' but, is limited because it embeds the field names directly in this class
If there are attachments, this class creates a directory for each email that has an attachment and puts them all there
Known limitations: tested on POP3 server only, should work on IMAP, but never been tested only extracts the last HTML and PLAIN sub parts in a message may be conflicts with filenames of attachments all in one dir
Class Created by: sophistry --inspired by CodeIgniter, but not beholden to it 20079019
*/
class email_grabber {
// despite the names, these IMAP vars // can be pop3 server vars too var $IMAP_server; var $IMAP_login; var $IMAP_pass;
var $IMAP_service_flags; var $IMAP_mailbox;
var $IMAP_resource; var $IMAP_state; var $connected;
// /full/path/to/attachment/directory/ // (dir must have www chmod read/write permissions) var $IMAP_attachment_dir;
// make this property so we can separate // the parts parsing into its own method var $parts_array = array();
// when extract_a_part() is called // it fills these vars with the string // found in the PLAIN and HTML parts // for the current message being processed // only keeps the last part, so it will only // keep the last of multiple HTML parts var $PLAIN; var $HTML;
var $msg_id = 0; var $msg_count = 0;
// constructor function handles array items passed // by the config file loader in CI, or they can be passed // directly into the new() step // this design allows the library to be autoloaded // and used in multiple controllers function email_grabber($init_array = NULL) { // if no init parameter sent // nothing happens in constructor // user has to call connect_and_count() // and pass the parameters if ( !is_null($init_array) ) { // handle the array items // pass to connect_and_count() $this->connect_and_count($init_array); }
}
// grab email from a POP3 account
function connect_and_count($init_array)
{
// these array items need to be the
// same names as the config items OR
// the db table fields that store the account info
$this->IMAP_server = $init_array['server'];
$this->IMAP_login = $init_array['login'];
$this->IMAP_pass = $init_array['pass'];
$this->IMAP_service_flags = $init_array['service_flags'];
$this->IMAP_mailbox = $init_array['mailbox'];
// grab the resource returned by imap_open()
// suppress warning with @ so we can handle it internally
$imap_str = '{'. $this->IMAP_server . $this->IMAP_service_flags.'}'.$this->IMAP_mailbox;
//p($imap_str);
$this->IMAP_resource = @imap_open($imap_str, $this->IMAP_login, $this->IMAP_pass);
if($this->IMAP_resource)
{
// handle the strange mailbox is empty error
// so we can just get on with things
// this clears all errors in the stack
// but, at this point there shouldn't be more than one
$err = imap_errors();
if($err[0] == 'Mailbox is empty')
{
// keep the state
$this->IMAP_state = 'Mailbox is empty';
}
// store the number of emails
// waiting at server into var
$m = $this->count_messages();
$this->IMAP_state = 'Connected. Message count: ' . $m;
$this->connected = TRUE;
return TRUE;
}
else
{
$this->IMAP_state = 'Not connected';
$this->connected = FALSE;
return FALSE;
}
}
/**
- Get the number of emails at server
- Calling this function updates msg_count var */ function count_messages() { $this->msg_count = imap_num_msg($this->IMAP_resource); return $this->msg_count; }
/**
- Get count of messages returned by latest
- call to the imap_num_msg() function that
- was stored in the property
- ACCESSOR method */ function get_message_count() { return $this->msg_count; }
/**
- Get an array of emails waiting
- returns empty array if no messages
- SLOW: all these functions process about 5 messages per second!
- But, there seems to be some kind of cache that
- speeds up subsequent mailbox requests / function get_message_list_overview() { $a = imap_fetch_overview($this->IMAP_resource,'1:'); return $a; }
// this is fairly useless because imap_headers() // returns a string rather than an array // not faster than the other listers // but it may be useful later function get_message_list_headers() { $a = imap_headers($this->IMAP_resource); return $a; }
// 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) ? 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;
}
// set the directory where we will store // attachments. check it is there and // writeable by the webserver function set_IMAP_attachment_dir($dir) { if (is_dir($dir)) { $this->IMAP_state = 'Attachment directory exists: ' . $dir; if (is_writeable($dir)) { $this->IMAP_state = 'Attachment directory writeable: ' . $dir; $this->IMAP_attachment_dir = $dir; } else { $this->IMAP_state = 'Attachment directory NOT writeable: ' . $dir; } } }
// sets the msg_id and then checks it // returns FALSE if id is > msg_count // otherwise TRUE // should also set an error here function set_msg_id($id) { $this->msg_id = $id; // make sure it is less than message count // and greater than zero $id_ok = (bool)( ($this->msg_count >= $this->msg_id) && ($this->msg_id > 0) ); if (!$id_ok) { $this->IMAP_state = 'Not a valid message id: ' . $this->msg_id; //unset($this->msg_id); } return $id_ok; }
// Normal POP3 does not mark messages for later deletion // must delete them and expunge them in same connection // TRUE on success, FALSE on failure // BUT... Google's gmail service does mark as read and // then does not serve them up to POP3 again even though // they are still in the INBOX. They are doing some extra // thing to the message to make it invisible once it has been // picked up by ANY POP3 request that grabs the email data // So, gmail does not seem to be affected by imap_delete() imap_expunge(), // it only cares about its own settings with regard to how // to handle message storage after a POP3 connection function delete_and_expunge($id_or_range) { // make sure we've got a message there of that id // and it's not a bogus id like 0 or -1 // also allow ranges to be sent to this function // format 1:5, so if a colon is sent, we assume // it is properly formatted - not the best idea // should check the full formatting with regexp '/[0-9]+:[0-9*]/' if ($this->set_msg_id($id_or_range) || strpos($id_or_range,':') || strpos($id_or_range,',')) { // should capture error here when the message doesn't exist imap_delete($this->IMAP_resource, $this->msg_id); imap_expunge($this->IMAP_resource); $this->IMAP_state = 'Deleted and Expunged message id_or_range: ' . $this->msg_id; return TRUE; } else { $this->IMAP_state = 'Could not delete and expunge message id_or_range: ' . $this->msg_id; return FALSE; } }
// deal with most of the variations in the msg_id spec // just handles 0, single value whole number, or colon range x:y // other variations (not handled at the moment) // are comma separated list of ids and 1:* (star) function _prepare_msg_ids ($id_or_range=0) { if (!$id_or_range) { // zero or EMPTY means get all emails in mailbox $id_start = 1; $id_end = $this->msg_count; } else { // just a number, assign both start and end $id_start = $id_end = $id_or_range; }
// range value, explode, overwrite previous
if (strpos($id_or_range,':'))
{
list($id_start, $id_end) = explode(':',$id_or_range);
}
return array($id_start,$id_end);
}
/**
-
Get email by coordinating multiple imap functions
-
imap_fetchstructure, imap_fetchbody,
-
imap_fetchheader, and/or imap_body
-
(imap_fetchbody is called in sub-routine extract_a_part)
-
gmail "removes" the message from the POP3 INBOX (if set to do so)
-
when you call any body or structure type of imap_ function
-
but does not "remove" it when you call header imap_ functions */ function grab_email_as_array($id = 0) { //p($id); // set this to 1 to keep errors in imap parsing out of the php stack $cap_errs = 0; // we are going to return this // array with all the email data // from one email message in it // hold the email addresses in arrays // for transport to the related db tables $email_arrays_array = array(); // email elements that are not arrays - // they are in the email table $email_strings_array = array(); // an array to hold them both $main_email_array = array(); // set the msg_id if one is sent in // if not valid, return empty array $bool = $this->set_msg_id($id);
if (!$bool) return $email_array;
// make sure we start fresh unset($this->PLAIN); unset($this->HTML);
// get the header info first // NOTE: this function does not remove the message from gmail's INBOX $header_obj=imap_headerinfo($this->IMAP_resource, $this->msg_id); //p($header_obj);exit();
// check for errors here to clear the // error stack and prevent it from posting // errors about badly formatted emails // should probably store the errors with the email in the db if ($cap_errs) $err = imap_errors(); //p($err);
// fill the parts_array var with the parts // $structure is the map to the email message
// NOTE: calling this function removes message from // gmail's POP3 INBOX - not by deleting it, but making // it effectively invisible (depending on gmail account's POP3 settings) $structure = imap_fetchstructure($this->IMAP_resource, $this->msg_id); //p($structure); //exit(); // check for erros here to clear the // error stack and prevent it from posting // errors about badly formatted emails // should probably store the errors with the email in the db if ($cap_errs) $err = imap_errors();
// could pull out the raw email body here for storage/export potential //$text=imap_body($this->IMAP_resource,$this->msg_id); //p($text);//exit(); // see if it is a multipart messsage // should handle bothe these cases in the extract_a_part function if (isset($structure->parts) && count($structure->parts)) { // extract every part of the email into the array_parts var // this is a custom array to help unify what we need from the parts foreach ($structure->parts as $index => $part_def_obj) { // extract this part of email // if this is a PLAIN or HTML part it will // be written to the respective property $this->extract_a_part($part_def_obj,$index+1); } } else { // not a multipart message // get the body of message
// NOTE: calling this function removes message from // gmail's POP3 INBOX - not deleting it, but making // it effectively invisible $text=imap_body($this->IMAP_resource,$this->msg_id); // decode if quoted-printable if ($structure->encoding==4) $text=quoted_printable_decode($text); // create a var for $this->PLAIN or $this->HTML $this->{$structure->subtype} = $text; $this->parts_array['not multipart']['text'] = array('type'=>$structure->subtype,'string'=>$text);
} //p($this->parts_array); //exit();
// start stuffing the single email array
// first make sure the header_obj has the properties // we want to use later in this code so we don't have to // do a bunch of isset checks to avoid PHP warnings // from to message_id subject date udate Size // also gather the data for later fingerprinting // by stringing out the data points that won't change // these are items in the email that come here as arrays // rather than strings so they are handled differently // NOTE: the only time a BCC array will be set is if // you are looking at sent mail or the mailserver does something // unusual to show that there was a BCC but it was removed. // otherwise the BCC state will // have to be deduced from the lack of address in the to or cc // fields (as well as any other fields like Resent-To: etc...) // and its presence in one of the Received: header strings // Resent-To: addresses have to be parsed out of the header manually $address_keys_we_need_to_be_set = explode(' ', 'from to cc bcc reply_to sender return_path'); $other_keys_we_need_to_be_set = explode(' ', 'message_id subject date udate Size'); $data_points_for_fingerprint = explode(' ', 'fromaddress toaddress subject date'); $email_data_to_use_in_fingerprint = ''; foreach ($other_keys_we_need_to_be_set as $prop) { $header_obj->$prop = isset($header_obj->$prop) ? $header_obj->$prop : ''; }
// turn each of the arrays of objects into arrays of arrays // with each address part getting encoding foreach ($address_keys_we_need_to_be_set as $key) {
// make sure the array item is set if (isset($header_obj->$key)) { // it's there, // variable is named for the key $$key = array(); $arr = array(); foreach ($header_obj->$key as $obj) { // coerce it to an array $arr[] = (array)$obj; //p($key); //p($arr); // take the personal part and apply decoding if (isset($arr['personal'])) { $arr['personal'] = $this->decode_mime_text($arr['personal']); }// push the array onto the array array_push( $$key, $arr ); } $email_arrays_array[$key] = $arr; //p($$key); }
}
//p($to);p($from);p($header_obj);exit();
foreach ($data_points_for_fingerprint as $prop) { // will use this subset of raw strings later in fingerprinting $email_data_to_use_in_fingerprint .= $header_obj->$prop; } //p($email_data_to_use_in_fingerprint);exit();
// the email_strings_array keys correspond to database fields // this will make it easy to add the data to the email table
// NOTE: this header function does not remove the message from gmail's INBOX $email_strings_array['header'] = imap_fetchheader($this->IMAP_resource, $this->msg_id); //p($email_strings_array['header']);exit();
// use the extract_headers_to_array() fn // to get any header that is not included // in the native imap_ function calls // commented here since it is not in use //$header_array = $this->extract_headers_to_array($email_strings_array['header']);
$email_strings_array['message_id'] = $header_obj->message_id; $email_strings_array['subject'] = $this->decode_mime_text($header_obj->subject); $email_strings_array['date_string']= $header_obj->date; $email_strings_array['date_sent_stamp'] = date("Y-m-d H:i:s",$header_obj->udate); // this is actually the datestamp of // when the message was put into this array // rather than "received" (which should better // be the datestamp for when the message // was accepted to the receiving SMTP server $email_strings_array['date_received_stamp'] = date("Y-m-d H:i:s"); $email_strings_array['size'] = $header_obj->Size; $email_strings_array['text'] = (isset($this->PLAIN)) ? $this->PLAIN : ''; $email_strings_array['html'] = (isset($this->HTML)) ? $this->HTML : '';
// set a temporary array item to enable // message to be deleted at mailserver to // sync with db, unset before db insert // not needed for google's gmail // since they make POP3 pulled emails invisible // once they are pulled one time $email_strings_array['temp_msg_id']= $this->msg_id;
// generate a unique id so we // can do reliable dupe detection // hashes the string representation // of some datapoints of this email // so, if we get the same email again // it will result in the same hash // we could do basic dupe detection using // message_id, but it is not reliable // because it is not always there $email_strings_array['email_fingerprint_auto'] = $this->email_fingerprint( $email_data_to_use_in_fingerprint ); //p($email_array);exit();
$this->IMAP_state = 'Got email as array, message id: ' . $this->msg_id;
// load them up as two items in the main array $main_email_array['strings'] = $email_strings_array; // arrays are separated because thay will be used to // populate related database tables in a normalized email storage schema $main_email_array['arrays'] = $email_arrays_array;
return $main_email_array;
}
// standard place to do fingerprinting // so we can use it to check email dupes // send it a string with unchanging data // that are pulled from the email header // could "salt" this but md5'ing the var_export // is kind of like salt (except if everyone does it!) function email_fingerprint($str) { return md5(var_export($str,TRUE)); }
/**
- Parse e-mail structure into array var
- this will handle nested parts properly
- it will recurse and use the initial part number
- concatenating it with nested parts using dot .
- Useful information copied from http://php.net
Table 142. Returned Objects for imap_fetchstructure()
type Primary body type encoding Body transfer encoding ifsubtype TRUE if there is a subtype string subtype MIME subtype ifdescription TRUE if there is a description string description Content description string ifid TRUE if there is an identification string id Identification string lines Number of lines bytes Number of bytes ifdisposition TRUE if there is a disposition string disposition Disposition string ifdparameters TRUE if the dparameters array exists dparameters An array of objects where each object has an "attribute" and a "value" property corresponding to the parameters on the Content-disposition MIMEheader. ifparameters TRUE if the parameters array exists parameters An array of objects where each object has an "attribute" and a "value" property. parts An array of objects identical in structure to the top-level object, each of which corresponds to a MIME body part.
Table 143. Primary body type 0 text 1 multipart 2 message 3 application 4 audio 5 image 6 video 7 model 8 other 9 unknown/unknown
Table 144. Transfer encodings 0 7BIT 1 8BIT 2 BINARY 3 BASE64 4 QUOTED-PRINTABLE 5 OTHER */
function extract_a_part($part_def_obj, $part_number) { // get just one part as a string $part_string=imap_fetchbody($this->IMAP_resource, $this->msg_id, $part_number);
//p($part_string);
// DECODE the part
// if base64
if ($part_def_obj->encoding==3) $part_string=base64_decode($part_string);
// if quoted printable
if ($part_def_obj->encoding==4) $part_string=quoted_printable_decode($part_string);
// If binary or 8bit - we don't need to decode
$sub_type = strtoupper($part_def_obj->subtype);
// attachments, multipart types are 1-9
//p($part_def_obj);
if ($part_def_obj->type)
{
// determine body type (more to do here)
switch($part_def_obj->type)
{
case '5': // image, should put proper name here for the image
//$this->parts_array[$part_number]['image'] = array('filename'=>'IMAGE', 'string'=>$part_string, 'part_no'=>$part_number);
break;
}
// get an attachment, set filename to dparameter value
$filename='';
if ($part_def_obj->ifdparameters && count($part_def_obj->dparameters))
{
foreach ($part_def_obj->dparameters as $dp)
{
if ((strtoupper($dp->attribute)=='NAME') || (strtoupper($dp->attribute)=='FILENAME')) $filename=$dp->value;
}
}
// if no filename yet, set filename to parameter value
if ($filename=='')
{
if ($part_def_obj->ifparameters && count($part_def_obj->parameters))
{
foreach ($part_def_obj->parameters as $p)
{
if ((strtoupper($p->attribute)=='NAME') || (strtoupper($p->attribute)=='FILENAME')) $filename=$p->value;
}
}
}
// we've got to have a filename by now!
if ($filename!='' )
{
$this->parts_array[$part_number]['attachment'] =
array('filename'=>$filename,
'string'=>$part_string,
'encoding'=>$part_def_obj->encoding,
'part_no'=>$part_number,
'type'=>$part_def_obj->type,
'subtype'=>$sub_type);
}
// now write the attachments to the disk
// Get store dir, call this every message based on
// the email data so it can hold all parts for a single email
//$dir = $this->dir_name();
$a_f = $this->decode_mime_text($filename);
// replace crap with underscore, there is a CI function to do this
$a_f = preg_replace('/[^a-z0-9_\-\.]/i', '_', $a_f);
//$this->save_files($dir.$a_f, $part_string);
}
// Text or HTML email, type is 0
else
{
// creates an instance var for $this->HTML or $this->PLAIN
// NOTE: only works for the last part or sub-part extracted
$this->$sub_type = $part_string;
$this->parts_array[$part_number]['text'] = array('type'=>$sub_type,'string'=>$part_string);
}
// if there are subparts call this function recursively
if (isset($part_def_obj->parts) && count($part_def_obj->parts))
{
foreach ($part_def_obj->parts as $index => $sub_part_def_obj)
{
$this->extract_a_part($sub_part_def_obj, ($part_number.'.'.($index+1)));
}
}
return TRUE;
}
// get mime meta data // this needs some attention function decode_mime_text($str) {
$txt = '';
$str = htmlspecialchars(chop($str));
$elements = imap_mime_header_decode($str);
if(is_array($elements))
{
for ($i=0; $i<count($elements); $i++)
{
$charset = $elements[$i]->charset;
$txt .= $elements[$i]->text;
}
}
else
{
$txt = $str;
}
if($txt == '')
{
$txt = 'NO DATA - value missing';
}
return $txt;
}
/**
-
Helper function
-
Extract an array listing from the header
-
This code makes sure this is done in a way that we get
-
all the possible headers (multi-line, domain keys,
-
repeated headers , etc...) tucked away nicely into
-
a nested array
-
To Do: 20070904
-
These headers (resent) have to be plucked out
-
as they are not supported in the imap_headerinfo() function
-
used in the grab_email_as_array() function above
-
resent-from = "Resent-From:" mailbox-list CRLF
-
resent-sender = "Resent-Sender:" mailbox CRLF
-
resent-to = "Resent-To:" address-list CRLF
-
resent-cc = "Resent-Cc:" address-list CRLF
-
resent-bcc = "Resent-Bcc:" (address-list / [CFWS]) CRLF */ function extract_headers_to_array($header) { //p($header); $header_array = explode("\n", rtrim($header)); // drop off any empty, null or FALSE values $header_array=array_filter($header_array); //p($header_array);
$new_header_array = array(); foreach ($header_array as $key => $line) { //p($new_header_array); // check if this line starts with a header name // if it does, build the new header item // if it doesn't, build the string out if (preg_match('/^([^:\s]+):\s(.+)/',$line,$m)) { //p($m[1]); //p($m[2]); $current_header = $m[1]; $current_data = $m[2]; // if there is no header by this name yet // set the data, otherwise, append it as array item if (!isset($new_header_array[$current_header])) { // this is the normal branch, new header, one line of data $new_header_array[$current_header] = $current_data; } else { // if it is not an array, it is a string and we need // to convert the existing data to an array, and add the new if (!is_array($new_header_array[$current_header])) { // this runs when a header name is repeated (like Received often is) // runs the 1st time it is repeated (second occurance of the header) // converts the existing string and the incoming string to a 2-item sub-array $new_header_array[$current_header] = array($new_header_array[$current_header],$current_data);
} else // if it is already an array then append an array item { // this runs when a header name is repeated (like Received often is) // runs 3rd and subsequent times $new_header_array[$current_header][] = $current_data; } } } else { // if it is already an array then append // the string to the last sub-array item // because we assume the lines with no header names // are part of the most recently added sub-array item if (is_array($new_header_array[$current_header])) { // this runs if there has already been a header of the same header name $new_header_array[$current_header][count($new_header_array[$current_header])-1] .= $line; } else // if it is not an array, it is still just a string and we need // to build the string out { // this runs if the line is part of the first header encountered // but is part of a long multiline string (like Received header) $new_header_array[$current_header] .= $line; } } }return $new_header_array; }
/**
-
Wrapper to close the IMAP connection
-
Returns TRUE if closed with no errors */ function close() { if (is_resource($this->IMAP_resource)) { $closed = imap_close($this->IMAP_resource); $this->IMAP_state = 'Connection closed.'; } else { $closed = FALSE; $this->IMAP_state = 'Connection could not be closed - no resource.'; }
return $closed; }
// This is a pretty lame function... // if it doesn't exist already // create a writeable directory // named for current month and year // where we can store attachments function make_dir($potential_name='') { //$dir_n = date('Y') . "_" . date('m'); $dir_n = $potential_name;
if (!is_dir($this->IMAP_attachment_dir . $dir_n))
mkdir($this->IMAP_attachment_dir . $dir_n, 0777);
return $dir_n . '/';
}
/**
- Save messages on local disc, potential
- name and file lock collision here */ function save_files($filename, $part) { $fp=fopen($this->IMAP_attachment_dir.$filename,"w+"); fwrite($fp,$part); fclose($fp); chown($this->IMAP_attachment_dir.$filename, 'www'); }
//----------------------------------------------- // wrapper function to loop over the emails and get them all // in a nice tidy, decoded and converted format // accepts no param, one number (msgid), or range specified with x:y function grab_emails_as_nested_array($id_or_range = 0) { $a = array();
// deals with all the variations in msg_id spec
list($id_start, $id_end) = $this->_prepare_msg_ids($id_or_range);
for ($id=$id_start; $id <= $id_end; $id++)
{
$a[] = $this->grab_email_as_array($id);
}
return $a;
}
//----------------------------------------------- // This is the same function wrapper as the nested array fn above // but, this one writes attachments to files too // loop over the emails and get them all // in a nice tidy, decoded and converted format // also, write the attachments to files in the attachment folder // accepts no param, one number (msgid), or range specified with x:y function grab_emails_as_nested_array_and_store($id_or_range = 0) { $a = array();
// deals with all the variations in msg_id spec
list($id_start, $id_end) = $this->_prepare_msg_ids($id_or_range);
for ($id=$id_start; $id <= $id_end; $id++)
{
$a[] = $this->grab_email_as_array_and_store($id);
}
return $a;
}
//------------------------------------------------ // grab the email and save attachments to files // this is just like grab_email_as_array() but, // attachment files are written to disk // this is the function to use when you are // transferring to a db and you want the files // to be written to disk at the same time all the // email data is transferred and deleted from the mailserver // function grab_email_as_array_and_store($id = 0) { // make sure we've got a message there of that id // and it's not a bogus id like 0 or -1 if (!$this->set_msg_id($id)) return FALSE;
// Get message header as array of pertinent values
$email_array = $this->grab_email_as_array($this->msg_id);
// Get store dir, call this every message based on
// the email data so it can hold all parts for a single email
// make a new dir based on the fingerprint
$dir = $this->make_dir($email_array['strings']['email_fingerprint_auto']);
// now write files into the new directory
// named with the fingerprint hash
// I think this loop may be subject to missing some stuff
// loop through the parts extracted in the grab_email_as_array() method
// and either save them to disk (attachments) or write to db (HTML or text)
// define the pattern that is going to make a nice filename
// there is a CI function that does this
$pattern_for_filename = '/[^a-z0-9_\-\.]/i';
foreach ($this->parts_array as $part)
{
if (isset($part['text']['type']) AND ($part['text']['type'] == 'HTML' OR $part['text']['type'] == 'PLAIN'))
{
// handle PLAIN and HTML types elsewhere
}
elseif (isset($part['attachment']) AND $part['attachment'])
{
// Save file attachments to disk
foreach (array($part['attachment']) as $attach)
{
$a_f = $this->decode_mime_text($attach['filename']);
// replace crap with underscore, there is a CI function to do this
$a_f = preg_replace($pattern_for_filename, '_', $a_f);
$filename = $dir.$a_f;
$this->save_files($filename, $attach['string']);
}
}
elseif (isset($part['image']) AND $part['image'])
{
// Save image attachments to disk
foreach ($part['image'] as $image)
{
$i_f = $this->decode_mime_text($image['filename']);
// replace crap with underscore, there is a CI function to do this
$i_f = preg_replace($pattern_for_filename, '_', $i_f);
$filename = $dir.$i_f;
$this->save_files($filename, $image['string']);
}
}
}
if($email_array != '')
{
unset($this->parts_array);
}
// return so the data can be used for a db insert
return $email_array;
}
}
?> [/code]