cmc-sales/vendors/shells/vault.php

398 lines
14 KiB
PHP
Raw Normal View History

2009-02-05 15:10:57 -08:00
<?
App::import('Sanitize');
class VaultShell extends Shell {
2010-03-18 15:30:29 -07:00
/* vault.php - To be run in CLI via Cron. Fetches the mail from a certain mailbox, searches for a CMC Technologies Enquiry Numbeer
2009-02-05 15:10:57 -08:00
* then loads the data into the 'emails' table and the attachments in the 'email_attachments' table.
* Emails are discared or moved to a subfolder once processed
2010-03-18 15:30:29 -07:00
*/
2009-02-05 15:10:57 -08:00
2010-03-18 15:30:29 -07:00
var $uses = array('Enquiry', 'Email', 'EmailAttachment');
function main() {
/******************************************************
* Config Variables
* *****************************************************/
2010-03-18 15:30:29 -07:00
$testing = 1; //Whether to actually move the emails. 1=test, 0=production
/* Setup Connection to the IMAP server */
$username = 'vault';
$password = 'xjdYOsmJWc37'; /* The password for the account to be checked */
$email_dir = '/var/www/cakephp/app/emails';
2010-03-18 15:30:29 -07:00
$temp_filename = 'temp.eml';
$ripmime_path = '/usr/local/bin/ripmime';
2010-03-18 15:30:29 -07:00
if($testing == 1) {
$email_dir = '/Users/karlcordes/Sites/quotenik/app/emails';
$ripmime_path = '/opt/local/bin/ripmime';
2010-03-18 15:30:29 -07:00
}
$mbox = imap_open("{mail.cmctechnologies.com.au:143}INBOX", $username, $password) or die("can't connect: " . imap_last_error());
$MC = imap_check($mbox);
$number_of_messages = $MC->Nmsgs;
echo "Number of messages to Process ".$number_of_messages."\n";
if($number_of_messages == 0) {
exit(0);
}
2010-03-18 15:30:29 -07:00
/* Loop through the messages and sort them into ones to be processed or discarded */
for ($i=30000; $i <= $number_of_messages; $i++) {
2010-03-18 15:30:29 -07:00
$this_header = imap_headerinfo($mbox, $i);
$message = $this->getMessage($mbox, $i, $this_header);
//echo "Checking msg number: $i \tSubject: ".$message['subject']."\n";
2010-03-18 15:30:29 -07:00
$enquiry = $this->checkIfValidEnquiry($message['subject'], $testing);
if($enquiry) {
echo "Found Enquiry number: ".$enquiry['Enquiry']['title']." Processing.\n";
2010-03-18 15:30:29 -07:00
//Process it and store the message and its attachments.
//Generate a Uniqid for this email.
$uniqid = $this->getUniqId($email_dir);
2010-03-18 15:30:29 -07:00
$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;
2010-03-18 15:30:29 -07:00
$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);
2010-03-18 15:30:29 -07:00
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']);
2010-03-18 15:30:29 -07:00
$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']);
2010-03-18 15:30:29 -07:00
$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) {
2010-03-18 15:30:29 -07:00
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.'/'.$attachment['name']);
$this->data['EmailAttachment']['filename'] = $email_dir.'/'.$uniqid.'/'.$attachment['name'];
2010-03-18 15:30:29 -07:00
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
2009-02-05 15:10:57 -08:00
* 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.
* */
2009-07-02 18:11:22 -07:00
2010-03-18 15:30:29 -07:00
$discarded_msgs[] = imap_uid($mbox,$i);
}
}
// $this->rmdirr($email_dir); //delete all attachments from the working directory. Easiest way to stop random files persisting
2010-03-18 15:30:29 -07:00
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);
echo "Going to discard: $no\t $msg\t".$this_header->subject."\n";
if($testing == 0) {
imap_mail_move($mbox,$no, 'INBOX/Discarded');
}
}
2009-02-05 15:10:57 -08:00
2010-03-18 15:30:29 -07:00
}
/* Finished working with the IMAP server. Make the changes and close the connection */
imap_expunge($mbox);
imap_close($mbox);
2009-02-05 15:10:57 -08:00
2010-03-18 15:30:29 -07:00
}
2009-02-05 15:10:57 -08:00
2010-03-18 15:30:29 -07:00
/*
* Fetches the body and attachments from a MIME encoded email. Uses ripmime to do the decoding
*
2010-03-18 15:30:29 -07:00
*/
2009-02-05 15:10:57 -08:00
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;
2010-03-18 15:30:29 -07:00
imap_savebody($mailbox, $email_file, $msg_number);
$command = "$ripmime_path -i $email_file -d $email_dir/$uniqid -v --verbose-contenttype --paranoid --prefix $msg_number";
2009-02-05 15:10:57 -08:00
2010-03-18 15:30:29 -07:00
$output = array();
exec($command, $output, $status);
2010-03-18 15:30:29 -07:00
/* Check the $output array and find the filenames of the attachments */
2010-03-18 15:30:29 -07:00
if($status == 0) {
$attachments = array();
2010-03-18 15:30:29 -07:00
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;
}
}
2010-03-18 15:30:29 -07:00
/* 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");
2010-03-18 15:30:29 -07:00
$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");
2009-02-05 15:10:57 -08:00
2010-03-18 15:30:29 -07:00
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";
2010-03-18 15:30:29 -07:00
$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 <aidan@php.net>
* @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;
}
}
2010-03-18 15:30:29 -07:00
?>