Nmsgs; echo "Number of messages to Process ".$number_of_messages."\n"; if($number_of_messages == 0) { exit(0); } /* Loop through the messages and sort them into ones to be processed or discarded */ for ($i=30000; $i <= $number_of_messages; $i++) { $this_header = imap_headerinfo($mbox, $i); $message = $this->getMessage($mbox, $i, $this_header); //echo "Checking msg number: $i \tSubject: ".$message['subject']."\n"; $enquiry = $this->checkIfValidEnquiry($message['subject'], $testing); if($enquiry) { echo "Found Enquiry number: ".$enquiry['Enquiry']['title']." Processing.\n"; //Process it and store the message and its attachments. //Generate a Uniqid for this email. $uniqid = $this->getUniqId($email_dir); $this->Email->create(); $this->data['Email']['enquiry_id'] = $enquiry['Enquiry']['id']; $this->data['Email']['to'] = $message['to']; $this->data['Email']['cc'] = $message['cc']; $this->data['Email']['from'] = $message['from']; $this->data['Email']['date'] = $message['date']; $this->data['Email']['subject'] = $message['subject']; $this->data['Email']['body'] = ""; $this->data['Email']['plainbody'] = ""; $this->data['Email']['uniqid'] = $uniqid; $structure = imap_fetchstructure($mbox, $i); $attachments = 1; if (empty($structure->parts)) { /* A single part message. No attachments and is plain text */ $this->data['Email']['body'] = imap_body($mbox, $i); } else { $attachments = $this->fetchBodyAttachments($mbox, $i, $temp_filename, $email_dir, $uniqid, $ripmime_path); if($attachments != 1) { foreach ($attachments as $attachment) { if($attachment['type'] == 'text/html') { //Assuming All HTML attachments are the body of the email if(file_exists($email_dir.'/'.$uniqid.'/'.$attachment['name'])) { $filecontents = file_get_contents($email_dir.'/'.$uniqid.'/'.$attachment['name']); $size = filesize($email_dir.'/'.$uniqid.'/'.$attachment['name']); $this->data['Email']['body'] .= $filecontents; } } if($attachment['type'] == 'text/plain') { //Found plain text if(file_exists($email_dir.'/'.$attachment['name'])) { $filecontents = file_get_contents($email_dir.'/'.$uniqid.'/'.$attachment['name']); $size = filesize($email_dir.'/'.$uniqid.'/'.$attachment['name']); $this->data['Email']['plainbody'] .= $filecontents; } } } } } //Sanitize::clean($this->data); if( ($this->data['Email']['body'] != "") || ($this->data['Email']['plainbody'] != "") || ($attachments != 1) ) { if($this->Email->save($this->data)) { $email_id = $this->Email->id; if($attachments != 1) { foreach ($attachments as $attachment) { if(file_exists($email_dir.'/'.$uniqid.'/'.$attachment['name']) != FALSE) { if( ($attachment['type'] != 'text/html') && ($attachment['type'] != 'multipart/mixed') && ($attachment['type'] != 'multipart/alternative') ) { $this->EmailAttachment->create(); $this->data['EmailAttachment']['email_id'] = $email_id; $this->data['EmailAttachment']['name'] = $attachment['name']; $this->data['EmailAttachment']['type'] = $attachment['type']; $this->data['EmailAttachment']['size'] = filesize($email_dir.'/'.$uniqid.'/'.$attachment['name']); $this->data['EmailAttachment']['filename'] = $email_dir.'/'.$uniqid.'/'.$attachment['name']; if ($this->EmailAttachment->save($this->data)) { echo "Saved file successfully to database\n"; } else { echo "Something went wrong saving the file to the DB\n"; } } //unlink($email_dir.'/'.$attachment['name']); #Delete this attachment now we're done with it. } } } echo "Email stored in the DB under enquiry ".$enquiry['Enquiry']['title']." Will be moved to the stored folder\n"; $stored_msgs[] = imap_uid($mbox,$i); // if($attachments != 1) { // $this->clearEmailAttachmentDirs($email_dir, $temp_filename, $attachments); //unlink($email_dir.'/'.$temp_filename); #remove the temp email. start again // } } else { echo 'Unable to save the Email\n'; } } else { echo "Unable to find either HTML or Plaintext body to this email. Ignoring it"; } } else { /* Can't find a valid-looking CMC Enquiry Number. Move the message to the discarded folder * I may change this to simply delete the emails. This will do for now, but it's doubling up on the storage for useless files. * */ $discarded_msgs[] = imap_uid($mbox,$i); } } // $this->rmdirr($email_dir); //delete all attachments from the working directory. Easiest way to stop random files persisting if(isset($stored_msgs)) { foreach($stored_msgs as $msg) { $no = imap_msgno($mbox,$msg); $this_header = imap_headerinfo($mbox, $i); echo "Going to store: $no\t $msg\t".$this_header->subject."\n"; if($testing == 0) { imap_mail_move($mbox, $no, 'INBOX/Stored'); } } } if(isset($discarded_msgs)) { foreach($discarded_msgs as $msg) { $no = imap_msgno($mbox,$msg); $this_header = imap_headerinfo($mbox, $i); echo "Going to discard: $no\t $msg\t".$this_header->subject."\n"; if($testing == 0) { imap_mail_move($mbox,$no, 'INBOX/Discarded'); } } } /* Finished working with the IMAP server. Make the changes and close the connection */ imap_expunge($mbox); imap_close($mbox); } /* * Fetches the body and attachments from a MIME encoded email. Uses ripmime to do the decoding * */ function fetchBodyAttachments($mailbox, $msg_number, $filename, $email_dir, $uniqid, $ripmime_path) { $mkdirresult = mkdir ($email_dir.'/'.$uniqid); if($mkdirresult == FALSE) { echo "ERROR: Failed to make ".$email_dir.'/'.$uniqid; return 1; } $email_file = $email_dir.'/'.$uniqid.'/'.$filename; imap_savebody($mailbox, $email_file, $msg_number); $command = "$ripmime_path -i $email_file -d $email_dir/$uniqid -v --verbose-contenttype --paranoid --prefix $msg_number"; $output = array(); exec($command, $output, $status); /* Check the $output array and find the filenames of the attachments */ if($status == 0) { $attachments = array(); for($i=0, $j=0; $i< count($output); $i++, $j++) { $words = explode(' ', $output[$i]); $type = explode('=', $words[1]); $name = explode('=', $words[2]); $attachments[$j]['type'] = $type[1]; $attachments[$j]['name'] = $name[1]; echo "in message number $msg_number: found attachment ".$attachments[$j]['name'].' '.$attachments[$j]['type']."\n"; } return $attachments; } else { return 1; } } /* clearEmailyAttachmentDirs($email_dir, $filename, $attachment_dir, $attachments) * * Deletes $email_dir/$filename.eml and the attachments specified by $attachments * */ function clearEmailAttachmentDirs($email_dir, $filename, $attachments) { unlink("$email_dir/$filename"); foreach ($attachments as $attachment) { unlink($email_dir.'/'.$attachment['name']); } } function getMessage($mbox, $msgnumber, $headers) { $subject = $headers->subject; $subject = iconv_mime_decode($subject, 0, "ISO-8859-1//IGNORE"); $date = $headers->date; $recipients = $this->getRecipients($headers); $message['subject'] = $subject; $message['date'] = $date; $message['to'] = $recipients['to']; $message['from'] = $recipients['from']; $message['cc'] = $recipients['cc']; return $message; } /* get Recipients from the headers of an email */ function getRecipients($headers) { $recipients = array(); $recipients['to'] = ""; $recipients['from'] = ""; $recipients['cc'] = ""; if(isset($headers->to)) { $to = $headers->to; if(count($to) > 0) { foreach ($to as $id => $object) { $recipients['to'] .= "$object->mailbox@$object->host "; } } } if(isset($headers->cc)) { $cc = $headers->cc; if(count($cc) > 0) { foreach ($cc as $id => $object) { $recipients['cc'] .= "$object->mailbox@$object->host "; } } } if(isset($headers->from)) { $from = $headers->from; if(count($from) > 0) { foreach ($from as $id => $object) { $recipients['from'] .= "$object->mailbox@$object->host"; } } } return $recipients; } function getBody($mbox, $msgnumber) { $structure = imap_fetchstructure($mbox, $msgnumber); if (!empty($structure->parts)) { $body = $this->getParts($structure->parts, $mbox, $msgnumber); } else { $body = imap_body($mbox, $msgnumber); /* Or get the plaintext */ } return $body; } function checkIfValidEnquiry($subject, $testing) { $subject = iconv_mime_decode($subject, 0, "ISO-8859-1"); $output = array(); // $decoded_subject = iconv_mime_decode($subject, 2, "ISO-8859-1"); preg_match("/CMC\d+([NVQWSOT]|ACT|NT)E\d+-\d+/", $subject, $output); if(isset($output[0])) { //Found a valid-looking Enquiry Number $fetched_enquirynumber = $output[0]; // echo $fetched_enquirynumber."\n"; $enquiry = $this->Enquiry->findByTitle($fetched_enquirynumber); if($enquiry) { return $enquiry; } } else { return FALSE; } } /** * Delete a file, or a folder and its contents (recursive algorithm) * * @author Aidan Lister * @version 1.0.3 * @link http://aidanlister.com/repos/v/function.rmdirr.php * @param string $dirname Directory to delete * @return bool Returns TRUE on success, FALSE on failure */ function rmdirr($dirname) { // Sanity check if (!file_exists($dirname)) { return false; } // Simple delete for a file if (is_file($dirname) || is_link($dirname)) { return unlink($dirname); } // Loop through the folder $dir = dir($dirname); while (false !== $entry = $dir->read()) { // Skip pointers if ($entry == '.' || $entry == '..') { continue; } // Recurse $this->rmdirr($dirname . DIRECTORY_SEPARATOR . $entry); } // Clean up $dir->close(); return; //removing the last recursion - should remove the deletion of the last directory I hope. Lazy hack using this but should work //rmdir($dirname); } /** * Generate a uniq id. * @todo Ensure the sub-directory doesn't exist to avoid collisions * */ function getUniqId($email_dir) { $uniqid = uniqid(null,TRUE); //while(is_dir($email_dir."/".$uniqid) == TRUE) { // // } return $uniqid; } } ?>