function run_action(SugarBean $bean, $params = array()) { global $sugar_config; include_once 'modules/EmailTemplates/EmailTemplate.php'; $emailTemp = new EmailTemplate(); $emailTemp->retrieve($params['email_template']); $object_arr[$bean->module_dir] = $bean->id; $parsedSiteUrl = parse_url($sugar_config['site_url']); $host = $parsedSiteUrl['host']; if (!isset($parsedSiteUrl['port'])) { $parsedSiteUrl['port'] = 80; } $port = $parsedSiteUrl['port'] != 80 ? ":" . $parsedSiteUrl['port'] : ''; $path = !empty($parsedSiteUrl['path']) ? $parsedSiteUrl['path'] : ""; $cleanUrl = "{$parsedSiteUrl['scheme']}://{$host}{$port}{$path}"; $url = $cleanUrl . "/index.php?module={$bean->module_dir}&action=DetailView&record={$bean->id}"; $subject = $emailTemp->parse_template($emailTemp->subject, $object_arr); $body_html = $emailTemp->parse_template($emailTemp->body_html, $object_arr); $body_html = str_replace("\$url", $url, $body_html); $body_plain = $emailTemp->parse_template($emailTemp->body, $object_arr); $body_plain = str_replace("\$url", $url, $body_plain); $email = $this->getEmailFromParams($bean, $params); return $this->sendEmail($email, $subject, $body_html, $body_plain, $bean); }
$object_arr = array(); if (!empty($focus->parent_id)) { $object_arr[$focus->parent_type] = $focus->parent_id; } if (isset($focus->to_addrs_arr[0]['contact_id'])) { $object_arr['Contacts'] = $focus->to_addrs_arr[0]['contact_id']; } if (empty($object_arr)) { $object_arr = array('Contacts' => '123'); } // do not parse email templates if the email is being saved as draft.... if ($focus->type != 'draft' && count($object_arr) > 0) { require_once $beanFiles['EmailTemplate']; $focus->name = EmailTemplate::parse_template($focus->name, $object_arr); $focus->description = EmailTemplate::parse_template($focus->description, $object_arr); $focus->description_html = EmailTemplate::parse_template($focus->description_html, $object_arr); } //// END TEMPLATE PARSING /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// //// PREP FOR ATTACHMENTS if (empty($focus->id)) { $focus->id = create_guid(); $focus->new_with_id = true; } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// //// ATTACHMENT HANDLING $focus->handleAttachments(); //// END ATTACHMENT HANDLING ///////////////////////////////////////////////////////////////////////////////
/** * Sends Email for Email 2.0 */ function email2Send($request) { global $mod_strings; global $app_strings; global $current_user; global $sugar_config; global $locale; global $timedate; global $beanList; global $beanFiles; $OBCharset = $locale->getPrecedentPreference('default_email_charset'); /********************************************************************** * Sugar Email PREP */ /* preset GUID */ $orignialId = ""; if (!empty($this->id)) { $orignialId = $this->id; } // if if (empty($this->id)) { $this->id = create_guid(); $this->new_with_id = true; } /* satisfy basic HTML email requirements */ $this->name = $request['sendSubject']; $this->description_html = '<html><body>' . $request['sendDescription'] . '</body></html>'; /********************************************************************** * PHPMAILER PREP */ $mail = new SugarPHPMailer(); $mail = $this->setMailer($mail, '', $_REQUEST['fromAccount']); if (empty($mail->Host) && !$this->isDraftEmail($request)) { $this->status = 'send_error'; if ($mail->oe->type == 'system') { echo $app_strings['LBL_EMAIL_ERROR_PREPEND'] . $app_strings['LBL_EMAIL_INVALID_SYSTEM_OUTBOUND']; } else { echo $app_strings['LBL_EMAIL_ERROR_PREPEND'] . $app_strings['LBL_EMAIL_INVALID_PERSONAL_OUTBOUND']; } return false; } $subject = $this->name; $mail->Subject = from_html($this->name); // work-around legacy code in SugarPHPMailer if ($_REQUEST['setEditor'] == 1) { $_REQUEST['description_html'] = $_REQUEST['sendDescription']; $this->description_html = $_REQUEST['description_html']; } else { $this->description_html = ''; $this->description = $_REQUEST['sendDescription']; } // end work-around if ($this->isDraftEmail($request)) { if ($this->type != 'draft' && $this->status != 'draft') { $this->id = create_guid(); $this->new_with_id = true; $this->date_entered = ""; } // if $q1 = "update emails_email_addr_rel set deleted = 1 WHERE email_id = '{$this->id}'"; $r1 = $this->db->query($q1); } // if if (isset($request['saveDraft'])) { $this->type = 'draft'; $this->status = 'draft'; $forceSave = true; } else { /* Apply Email Templates */ // do not parse email templates if the email is being saved as draft.... $toAddresses = $this->email2ParseAddresses($_REQUEST['sendTo']); $sea = new SugarEmailAddress(); $object_arr = array(); if (isset($_REQUEST['parent_type']) && !empty($_REQUEST['parent_type']) && isset($_REQUEST['parent_id']) && !empty($_REQUEST['parent_id']) && ($_REQUEST['parent_type'] == 'Accounts' || $_REQUEST['parent_type'] == 'Contacts' || $_REQUEST['parent_type'] == 'Leads' || $_REQUEST['parent_type'] == 'Users' || $_REQUEST['parent_type'] == 'Prospects')) { if (isset($beanList[$_REQUEST['parent_type']]) && !empty($beanList[$_REQUEST['parent_type']])) { $className = $beanList[$_REQUEST['parent_type']]; if (isset($beanFiles[$className]) && !empty($beanFiles[$className])) { if (!class_exists($className)) { require_once $beanFiles[$className]; } $bean = new $className(); $bean->retrieve($_REQUEST['parent_id']); $object_arr[$bean->module_dir] = $bean->id; } // if } // if } foreach ($toAddresses as $addrMeta) { $addr = $addrMeta['email']; $beans = $sea->getBeansByEmailAddress($addr); foreach ($beans as $bean) { if (!isset($object_arr[$bean->module_dir])) { $object_arr[$bean->module_dir] = $bean->id; } } } /* template parsing */ if (empty($object_arr)) { $object_arr = array('Contacts' => '123'); } $object_arr['Users'] = $current_user->id; $this->description_html = EmailTemplate::parse_template($this->description_html, $object_arr); $this->name = EmailTemplate::parse_template($this->name, $object_arr); $this->description = EmailTemplate::parse_template($this->description, $object_arr); $this->description = html_entity_decode($this->description, ENT_COMPAT, 'UTF-8'); if ($this->type != 'draft' && $this->status != 'draft') { $this->id = create_guid(); $this->date_entered = ""; $this->new_with_id = true; $this->type = 'out'; $this->status = 'sent'; } } if (isset($_REQUEST['parent_type']) && empty($_REQUEST['parent_type']) && isset($_REQUEST['parent_id']) && empty($_REQUEST['parent_id'])) { $this->parent_id = ""; $this->parent_type = ""; } // if $mail->Subject = $this->name; $mail = $this->handleBody($mail); $mail->Subject = $this->name; $this->description_html = from_html($this->description_html); $this->description_html = $this->decodeDuringSend($this->description_html); $this->description = $this->decodeDuringSend($this->description); /* from account */ $replyToAddress = $current_user->emailAddress->getReplyToAddress($current_user); $replyToName = ""; if (empty($request['fromAccount'])) { $defaults = $current_user->getPreferredEmail(); $mail->From = $defaults['email']; $mail->FromName = $defaults['name']; $replyToName = $mail->FromName; //$replyToAddress = $current_user->emailAddress->getReplyToAddress($current_user); } else { // passed -> user -> system default $ie = new InboundEmail(); $ie->retrieve($request['fromAccount']); $storedOptions = unserialize(base64_decode($ie->stored_options)); $fromName = ""; $fromAddress = ""; $replyToName = ""; //$replyToAddress = ""; if (!empty($storedOptions)) { $fromAddress = $storedOptions['from_addr']; $fromName = from_html($storedOptions['from_name']); $replyToAddress = isset($storedOptions['reply_to_addr']) ? $storedOptions['reply_to_addr'] : ""; $replyToName = isset($storedOptions['reply_to_name']) ? from_html($storedOptions['reply_to_name']) : ""; } // if $defaults = $current_user->getPreferredEmail(); // Personal Account doesn't have reply To Name and Reply To Address. So add those columns on UI // After adding remove below code // code to remove if ($ie->is_personal) { if (empty($replyToAddress)) { $replyToAddress = $current_user->emailAddress->getReplyToAddress($current_user); } // if if (empty($replyToName)) { $replyToName = $defaults['name']; } // if //Personal accounts can have a reply_address, which should //overwrite the users set default. if (!empty($storedOptions['reply_to_addr'])) { $replyToAddress = $storedOptions['reply_to_addr']; } } // end of code to remove $mail->From = !empty($fromAddress) ? $fromAddress : $defaults['email']; $mail->FromName = !empty($fromName) ? $fromName : $defaults['name']; $replyToName = !empty($replyToName) ? $replyToName : $mail->FromName; } $mail->Sender = $mail->From; /* set Return-Path field in header to reduce spam score in emails sent via Sugar's Email module */ if (!empty($replyToAddress)) { $mail->AddReplyTo($replyToAddress, $locale->translateCharsetMIME(trim($replyToName), 'UTF-8', $OBCharset)); } else { $mail->AddReplyTo($mail->From, $locale->translateCharsetMIME(trim($mail->FromName), 'UTF-8', $OBCharset)); } // else $emailAddressCollection = array(); // used in linking to beans below // handle to/cc/bcc foreach ($this->email2ParseAddresses($request['sendTo']) as $addr_arr) { if (empty($addr_arr['email'])) { continue; } if (empty($addr_arr['display'])) { $mail->AddAddress($addr_arr['email'], ""); } else { $mail->AddAddress($addr_arr['email'], $locale->translateCharsetMIME(trim($addr_arr['display']), 'UTF-8', $OBCharset)); } $emailAddressCollection[] = $addr_arr['email']; } foreach ($this->email2ParseAddresses($request['sendCc']) as $addr_arr) { if (empty($addr_arr['email'])) { continue; } if (empty($addr_arr['display'])) { $mail->AddCC($addr_arr['email'], ""); } else { $mail->AddCC($addr_arr['email'], $locale->translateCharsetMIME(trim($addr_arr['display']), 'UTF-8', $OBCharset)); } $emailAddressCollection[] = $addr_arr['email']; } foreach ($this->email2ParseAddresses($request['sendBcc']) as $addr_arr) { if (empty($addr_arr['email'])) { continue; } if (empty($addr_arr['display'])) { $mail->AddBCC($addr_arr['email'], ""); } else { $mail->AddBCC($addr_arr['email'], $locale->translateCharsetMIME(trim($addr_arr['display']), 'UTF-8', $OBCharset)); } $emailAddressCollection[] = $addr_arr['email']; } /* parse remove attachments array */ $removeAttachments = array(); if (!empty($request['templateAttachmentsRemove'])) { $exRemove = explode("::", $request['templateAttachmentsRemove']); foreach ($exRemove as $file) { $removeAttachments = substr($file, 0, 36); } } /* handle attachments */ if (!empty($request['attachments'])) { $exAttachments = explode("::", $request['attachments']); foreach ($exAttachments as $file) { $file = trim(from_html($file)); $file = str_replace("\\", "", $file); if (!empty($file)) { //$fileLocation = $this->et->userCacheDir."/{$file}"; $fileGUID = substr($file, 0, 36); $fileLocation = $this->et->userCacheDir . "/{$fileGUID}"; $filename = substr($file, 36, strlen($file)); // strip GUID for PHPMailer class to name outbound file $mail->AddAttachment($fileLocation, $filename, 'base64', $this->email2GetMime($fileLocation)); //$mail->AddAttachment($fileLocation, $filename, 'base64'); // only save attachments if we're archiving or drafting if ($this->type == 'draft' && !empty($this->id) || isset($request['saveToSugar']) && $request['saveToSugar'] == 1) { $note = new Note(); $note->id = create_guid(); $note->new_with_id = true; // duplicating the note with files $note->parent_id = $this->id; $note->parent_type = $this->module_dir; $note->name = $filename; $note->filename = $filename; $noteFile = "{$sugar_config['upload_dir']}{$note->id}"; $note->file_mime_type = $this->email2GetMime($fileLocation); if (!copy($fileLocation, $noteFile)) { $GLOBALS['log']->debug("EMAIL 2.0: could not copy attachment file to cache/upload [ {$fileLocation} ]"); } $note->save(); } } } } /* handle sugar documents */ if (!empty($request['documents'])) { $exDocs = explode("::", $request['documents']); foreach ($exDocs as $docId) { $docId = trim($docId); if (!empty($docId)) { $doc = new Document(); $docRev = new DocumentRevision(); $doc->retrieve($docId); $docRev->retrieve($doc->document_revision_id); $filename = $docRev->filename; $fileLocation = "{$sugar_config['upload_dir']}{$docRev->id}"; $mime_type = $docRev->file_mime_type; $mail->AddAttachment($fileLocation, $locale->translateCharsetMIME(trim($filename), 'UTF-8', $OBCharset), 'base64', $mime_type); // only save attachments if we're archiving or drafting if ($this->type == 'draft' && !empty($this->id) || isset($request['saveToSugar']) && $request['saveToSugar'] == 1) { $note = new Note(); $note->id = create_guid(); $note->new_with_id = true; // duplicating the note with files $note->parent_id = $this->id; $note->parent_type = $this->module_dir; $note->name = $filename; $note->filename = $filename; $note->file_mime_type = $mime_type; $noteFile = "{$sugar_config['upload_dir']}{$note->id}"; if (!copy($fileLocation, $noteFile)) { $GLOBALS['log']->debug("EMAIL 2.0: could not copy SugarDocument revision file to {$sugar_config['upload_dir']} [ {$fileLocation} ]"); } $note->save(); } } } } /* handle template attachments */ if (!empty($request['templateAttachments'])) { $exNotes = explode("::", $request['templateAttachments']); foreach ($exNotes as $noteId) { $noteId = trim($noteId); if (!empty($noteId)) { $note = new Note(); $note->retrieve($noteId); if (!empty($note->id)) { $filename = $note->filename; $fileLocation = "{$sugar_config['upload_dir']}{$note->id}"; $mime_type = $note->file_mime_type; if (!$note->embed_flag) { $mail->AddAttachment($fileLocation, $filename, 'base64', $mime_type); // only save attachments if we're archiving or drafting if ($this->type == 'draft' && !empty($this->id) || isset($request['saveToSugar']) && $request['saveToSugar'] == 1) { if ($note->parent_id != $this->id) { $this->saveTempNoteAttachments($filename, $fileLocation, $mime_type); } } // if } // if } else { //$fileLocation = $this->et->userCacheDir."/{$file}"; $fileGUID = substr($noteId, 0, 36); $fileLocation = $this->et->userCacheDir . "/{$fileGUID}"; //$fileLocation = $this->et->userCacheDir."/{$noteId}"; $filename = substr($noteId, 36, strlen($noteId)); // strip GUID for PHPMailer class to name outbound file $mail->AddAttachment($fileLocation, $locale->translateCharsetMIME(trim($filename), 'UTF-8', $OBCharset), 'base64', $this->email2GetMime($fileLocation)); //If we are saving an email we were going to forward we need to save the attachments as well. if ($this->type == 'draft' && !empty($this->id) || isset($request['saveToSugar']) && $request['saveToSugar'] == 1) { $mimeType = $this->email2GetMime($fileLocation); $this->saveTempNoteAttachments($filename, $fileLocation, $mimeType); } // if } } } } /********************************************************************** * Final Touches */ /* save email to sugar? */ $forceSave = false; if ($this->type == 'draft' && !isset($request['saveDraft'])) { // sending a draft email $this->type = 'out'; $this->status = 'sent'; $forceSave = true; } elseif (isset($request['saveDraft'])) { $this->type = 'draft'; $this->status = 'draft'; $forceSave = true; } /********************************************************************** * SEND EMAIL (finally!) */ $mailSent = false; if ($this->type != 'draft') { $mail->prepForOutbound(); $mail->Body = $this->decodeDuringSend($mail->Body); $mail->AltBody = $this->decodeDuringSend($mail->AltBody); if (!$mail->Send()) { $this->status = 'send_error'; ob_clean(); echo $app_strings['LBL_EMAIL_ERROR_PREPEND'] . $mail->ErrorInfo; return false; } } if (!(empty($orignialId) || isset($request['saveDraft']) || $this->type == 'draft' && $this->status == 'draft') && ($_REQUEST['composeType'] == 'reply' || $_REQUEST['composeType'] == 'replyAll' || $_REQUEST['composeType'] == 'replyCase') && $orignialId != $this->id) { $originalEmail = new Email(); $originalEmail->retrieve($orignialId); $originalEmail->reply_to_status = 1; $originalEmail->save(); $this->reply_to_status = 0; } // if if ($_REQUEST['composeType'] == 'reply' || $_REQUEST['composeType'] == 'replyCase') { if (isset($_REQUEST['ieId']) && isset($_REQUEST['mbox'])) { $emailFromIe = new InboundEmail(); $emailFromIe->retrieve($_REQUEST['ieId']); $emailFromIe->mailbox = $_REQUEST['mbox']; if (isset($emailFromIe->id) && $emailFromIe->is_personal) { if ($emailFromIe->isPop3Protocol()) { $emailFromIe->mark_answered($this->uid, 'pop3'); } elseif ($emailFromIe->connectMailserver() == 'true') { $emailFromIe->markEmails($this->uid, 'answered'); $emailFromIe->mark_answered($this->uid); } } } } if ($forceSave || $this->type == 'draft' || isset($request['saveToSugar']) && $request['saveToSugar'] == 1) { // saving a draft OR saving a sent email $decodedFromName = mb_decode_mimeheader($mail->FromName); $this->from_addr = "{$decodedFromName} <{$mail->From}>"; $this->from_addr_name = $this->from_addr; $this->to_addrs = $_REQUEST['sendTo']; $this->to_addrs_names = $_REQUEST['sendTo']; $this->cc_addrs = $_REQUEST['sendCc']; $this->cc_addrs_names = $_REQUEST['sendCc']; $this->bcc_addrs = $_REQUEST['sendBcc']; $this->bcc_addrs_names = $_REQUEST['sendBcc']; $this->assigned_user_id = $current_user->id; $this->date_sent = $timedate->now(); /////////////////////////////////////////////////////////////////// //// LINK EMAIL TO SUGARBEANS BASED ON EMAIL ADDY if (isset($_REQUEST['parent_type']) && !empty($_REQUEST['parent_type']) && isset($_REQUEST['parent_id']) && !empty($_REQUEST['parent_id'])) { $this->parent_id = $_REQUEST['parent_id']; $this->parent_type = $_REQUEST['parent_type']; $q = "SELECT count(*) c FROM emails_beans WHERE email_id = '{$this->id}' AND bean_id = '{$_REQUEST['parent_id']}' AND bean_module = '{$_REQUEST['parent_type']}'"; $r = $this->db->query($q); $a = $this->db->fetchByAssoc($r); if ($a['c'] <= 0) { if (isset($beanList[$_REQUEST['parent_type']]) && !empty($beanList[$_REQUEST['parent_type']])) { $className = $beanList[$_REQUEST['parent_type']]; if (isset($beanFiles[$className]) && !empty($beanFiles[$className])) { if (!class_exists($className)) { require_once $beanFiles[$className]; } $bean = new $className(); $bean->retrieve($_REQUEST['parent_id']); if ($bean->load_relationship('emails')) { $bean->emails->add($this->id); } // if } // if } // if } // if } else { if (!class_exists('aCase')) { } else { $c = new aCase(); if ($caseId = InboundEmail::getCaseIdFromCaseNumber($mail->Subject, $c)) { $c->retrieve($caseId); $c->load_relationship('emails'); $c->emails->add($this->id); $this->parent_type = "Cases"; $this->parent_id = $caseId; } // if } } // else //// LINK EMAIL TO SUGARBEANS BASED ON EMAIL ADDY /////////////////////////////////////////////////////////////////// $this->save(); } if (!empty($request['fromAccount'])) { if (isset($ie->id) && !$ie->isPop3Protocol()) { $sentFolder = $ie->get_stored_options("sentFolder"); if (!empty($sentFolder)) { $data = $mail->CreateHeader() . "\r\n" . $mail->CreateBody() . "\r\n"; $ie->mailbox = $sentFolder; if ($ie->connectMailserver() == 'true') { $connectString = $ie->getConnectString($ie->getServiceString(), $ie->mailbox); $returnData = imap_append($ie->conn, $connectString, $data, "\\Seen"); if (!$returnData) { $GLOBALS['log']->debug("could not copy email to {$ie->mailbox} for {$ie->name}"); } // if } else { $GLOBALS['log']->debug("could not connect to mail serve for folder {$ie->mailbox} for {$ie->name}"); } // else } else { $GLOBALS['log']->debug("could not copy email to {$ie->mailbox} sent folder as its empty"); } // else } // if } // if return true; }
public function testparse_template() { $emailTemplate = new EmailTemplate(); $bean_arr = array('Users' => 1, 'Leads' => 1); //test with empty string $result = $emailTemplate->parse_template('', $bean_arr); $this->assertEquals('', $result); //test with valid string $result = $emailTemplate->parse_template('some value', $bean_arr); $this->assertEquals('some value', $result); }
/** * Send Email with attachment Report to specified emails * @param string $attachFileName * name of report file * @param string $attachFilePath * path to report file for read it and attach to email * @param array $toAddresses * array with email and names of contacts for send him this email * array( array('email' => EMAIL_ADDR, 'display' => DISPLAY_NAME) ) * @param string $templateId * optional argument. Id of Email template * @param SugarBean $bean * optional argument, uses for parse template with values of this bean * @return array * return array with status send email in this format: array('status' => TRUE_OR_FALSE, 'error' => ERROR_MSG) */ public static function sendEmailTemplate($attachFileName, $attachFilePath, $toAddresses, $templateId = '', $bean = NULL) { global $locale, $current_user, $app_strings; $sea = new SugarEmailAddress(); $answer = array('status' => true, 'error' => ''); $email = new Email(); $email->email2init(); $email->type = 'out'; $email->status = 'sent'; $email->id = create_guid(); $email->new_with_id = true; $emailTemplate = new EmailTemplate(); $emailTemplate->retrieve($templateId); if (empty($emailTemplate->subject)) { $emailTemplate->subject = $attachFileName; //set file name as subject } $email->name = $emailTemplate->subject; $email->description = $emailTemplate->body; $email->description_html = '<html><body>' . $emailTemplate->body_html . '</body></html>'; $mail = new SugarPHPMailer(); $mail = $email->setMailer($mail, '', ''); if (empty($mail->Host)) { if ($mail->oe->type == 'system') { $answer['error'] = $app_strings['LBL_EMAIL_ERROR_PREPEND'] . $app_strings['LBL_EMAIL_INVALID_SYSTEM_OUTBOUND']; } else { $answer['error'] = $app_strings['LBL_EMAIL_ERROR_PREPEND'] . $app_strings['LBL_EMAIL_INVALID_PERSONAL_OUTBOUND']; } $answer['status'] = false; return $answer; } $object_arr = array(); if ($bean !== NULL) { $object_arr[$bean->module_dir] = $bean->id; } foreach ($toAddresses as $addrMeta) { $addr = $addrMeta['email']; $beans = $sea->getBeansByEmailAddress($addr); foreach ($beans as $bean) { if (!isset($object_arr[$bean->module_dir])) { $object_arr[$bean->module_dir] = $bean->id; } } } $object_arr['Users'] = $current_user->id; $email->description_html = $email->decodeDuringSend(from_html(EmailTemplate::parse_template($email->description_html, $object_arr))); $email->description = $email->decodeDuringSend(html_entity_decode(EmailTemplate::parse_template($email->description, $object_arr), ENT_COMPAT, 'UTF-8')); $email->name = from_html(EmailTemplate::parse_template($email->name, $object_arr)); $mail->Body = $email->description_html; $mail->AltBody = $email->description; $mail->Subject = $email->name; $replyToAddress = $current_user->emailAddress->getReplyToAddress($current_user); $defaults = $current_user->getPreferredEmail(); $mail->From = $defaults['email']; $mail->FromName = $defaults['name']; $mail->Sender = $mail->From; /* set Return-Path field in header to reduce spam score in emails sent via Sugar's Email module */ $replyToName = $mail->FromName; $OBCharset = $locale->getPrecedentPreference('default_email_charset'); if (!empty($replyToAddress)) { $mail->AddReplyTo($replyToAddress, $locale->translateCharsetMIME(trim($replyToName), 'UTF-8', $OBCharset)); } else { $mail->AddReplyTo($mail->From, $locale->translateCharsetMIME(trim($mail->FromName), 'UTF-8', $OBCharset)); } foreach ($toAddresses as $addr_arr) { if (empty($addr_arr['email'])) { continue; } if (empty($addr_arr['display'])) { $mail->AddAddress($addr_arr['email'], ""); } else { $mail->AddAddress($addr_arr['email'], $locale->translateCharsetMIME(trim($addr_arr['display']), 'UTF-8', $OBCharset)); } } $mail->AddAttachment($attachFilePath, $attachFileName, 'base64', self::getMimeType($attachFileName)); $mail->prepForOutbound(); $mail->Body = $email->decodeDuringSend($mail->Body); $mail->AltBody = $email->decodeDuringSend($mail->AltBody); if (!$mail->Send()) { ob_clean(); $answer['error'] = $app_strings['LBL_EMAIL_ERROR_PREPEND'] . $mail->ErrorInfo; $answer['status'] = false; return $answer; } //TODO check settings if email need save, save $email bean class return $answer; }
/** * Sends Email for Email 2.0 */ function email2Send($request) { global $current_user; global $timedate; $saveAsDraft = !empty($request['saveDraft']); if (!$saveAsDraft && !empty($request["MAIL_RECORD_STATUS"]) && $request["MAIL_RECORD_STATUS"] == 'archived') { $archived = true; $this->type = 'archived'; } else { $archived = false; if (!empty($request['MAIL_RECORD_STATUS']) && $request['MAIL_RECORD_STATUS'] === 'ready') { $this->type = 'out'; } } /********************************************************************** * Sugar Email PREP */ /* preset GUID */ $orignialId = ""; if (!empty($this->id)) { $orignialId = $this->id; } // if if (empty($this->id)) { $this->id = create_guid(); $this->new_with_id = true; } /* satisfy basic HTML email requirements */ $this->name = $request['sendSubject']; if (isset($_REQUEST['setEditor']) && $_REQUEST['setEditor'] == 1) { $_REQUEST['description_html'] = $_REQUEST['sendDescription']; $this->description_html = $_REQUEST['description_html']; } else { $this->description_html = ''; $this->description = $_REQUEST['sendDescription']; } if ($this->isDraftEmail($request)) { if ($this->type != 'draft' && $this->status != 'draft') { $this->id = create_guid(); $this->new_with_id = true; $this->date_entered = ""; } // if $q1 = "update emails_email_addr_rel set deleted = 1 WHERE email_id = '{$this->id}'"; $this->db->query($q1); } // if if ($saveAsDraft) { $this->type = 'draft'; $this->status = 'draft'; } else { if ($archived) { $this->type = 'archived'; $this->status = 'archived'; } /* Apply Email Templates */ // do not parse email templates if the email is being saved as draft.... $toAddresses = $this->email2ParseAddresses($_REQUEST['sendTo']); $sea = BeanFactory::getBean('EmailAddresses'); $object_arr = array(); if (!empty($_REQUEST['parent_type']) && !empty($_REQUEST['parent_id']) && ($_REQUEST['parent_type'] == 'Accounts' || $_REQUEST['parent_type'] == 'Contacts' || $_REQUEST['parent_type'] == 'Leads' || $_REQUEST['parent_type'] == 'Users' || $_REQUEST['parent_type'] == 'Prospects')) { $bean = BeanFactory::getBean($_REQUEST['parent_type'], $_REQUEST['parent_id']); if (!empty($bean->id)) { $object_arr[$bean->module_dir] = $bean->id; } } foreach ($toAddresses as $addrMeta) { $addr = $addrMeta['email']; $beans = $sea->getBeansByEmailAddress($addr); foreach ($beans as $bean) { if (!isset($object_arr[$bean->module_dir])) { $object_arr[$bean->module_dir] = $bean->id; } } } /* template parsing */ if (empty($object_arr)) { $object_arr = array('Contacts' => '123'); } $object_arr['Users'] = $current_user->id; $this->description_html = EmailTemplate::parse_template($this->description_html, $object_arr); $this->name = EmailTemplate::parse_template($this->name, $object_arr); $this->description = EmailTemplate::parse_template($this->description, $object_arr); $this->description = html_entity_decode($this->description, ENT_COMPAT, 'UTF-8'); if ($this->type != 'draft' && $this->status != 'draft' && $this->type != 'archived' && $this->status != 'archived') { $this->id = create_guid(); $this->date_entered = ""; $this->new_with_id = true; $this->type = 'out'; $this->status = 'sent'; } } if (isset($_REQUEST['parent_type']) && empty($_REQUEST['parent_type']) && isset($_REQUEST['parent_id']) && empty($_REQUEST['parent_id'])) { $this->parent_id = ""; $this->parent_type = ""; } // if $forceSave = false; $subject = $this->name; $textBody = from_html($this->description); $htmlBody = from_html($this->description_html); //------------------- HANDLEBODY() --------------------------------------------- if (isset($_REQUEST['setEditor']) && $_REQUEST['setEditor'] == 1 && trim($_REQUEST['description_html']) != '' || trim($this->description_html) != '' && $current_user->getPreference('email_editor_option', 'global') !== 'plain') { $textBody = strip_tags(br2nl($htmlBody)); } else { // plain-text only $textBody = str_replace(" ", " ", $textBody); $textBody = str_replace("</p>", "</p><br />", $textBody); $textBody = strip_tags(br2nl($textBody)); $textBody = html_entity_decode($textBody, ENT_QUOTES, 'UTF-8'); $this->description_html = ""; // make sure it's blank to avoid any mishaps $htmlBody = $this->description_html; } $textBody = $this->decodeDuringSend($textBody); $htmlBody = $this->decodeDuringSend($htmlBody); $this->description = $textBody; $this->description_html = $htmlBody; $mailConfig = null; try { if (isset($request["fromAccount"]) && !empty($request["fromAccount"])) { $mailConfig = OutboundEmailConfigurationPeer::getMailConfigurationFromId($current_user, $request["fromAccount"]); } else { $mailConfig = OutboundEmailConfigurationPeer::getSystemMailConfiguration($current_user); } } catch (Exception $e) { if (!$saveAsDraft && !$archived) { throw $e; } } if (!$saveAsDraft && !$archived && is_null($mailConfig)) { throw new MailerException("No Valid Mail Configurations Found", MailerException::InvalidConfiguration); } try { $mailer = null; if (!$saveAsDraft && !$archived) { $mailerFactoryClass = $this->MockMailerFactoryClass; $mailer = $mailerFactoryClass::getMailer($mailConfig); $mailer->setSubject($subject); $mailer->setHtmlBody($htmlBody); $mailer->setTextBody($textBody); $replyTo = $mailConfig->getReplyTo(); if (!empty($replyTo)) { $replyToEmail = $replyTo->getEmail(); if (!empty($replyToEmail)) { $mailer->setHeader(EmailHeaders::ReplyTo, new EmailIdentity($replyToEmail, $replyTo->getName())); } } } if (!is_null($mailer)) { // Any individual Email Address that is not valid will be logged and skipped // If all email addresses in the request are skipped, an error "No Recipients" is reported for the request foreach ($this->email2ParseAddresses($request['sendTo']) as $addr_arr) { try { $mailer->addRecipientsTo(new EmailIdentity($addr_arr['email'], $addr_arr['display'])); } catch (MailerException $me) { // Invalid Email Address - Log it and Skip $GLOBALS["log"]->warning($me->getLogMessage()); } } foreach ($this->email2ParseAddresses($request['sendCc']) as $addr_arr) { try { $mailer->addRecipientsCc(new EmailIdentity($addr_arr['email'], $addr_arr['display'])); } catch (MailerException $me) { // Invalid Email Address - Log it and Skip $GLOBALS["log"]->warning($me->getLogMessage()); } } foreach ($this->email2ParseAddresses($request['sendBcc']) as $addr_arr) { try { $mailer->addRecipientsBcc(new EmailIdentity($addr_arr['email'], $addr_arr['display'])); } catch (MailerException $me) { // Invalid Email Address - Log it and Skip $GLOBALS["log"]->warning($me->getLogMessage()); } } } /* handle attachments */ if (!empty($request['attachments'])) { $exAttachments = explode("::", $request['attachments']); foreach ($exAttachments as $file) { $file = trim(from_html($file)); $file = str_replace("\\", "", $file); if (!empty($file)) { $fileGUID = preg_replace('/[^a-z0-9\\-]/', "", substr($file, 0, 36)); $fileLocation = $this->et->userCacheDir . "/{$fileGUID}"; $filename = substr($file, 36, strlen($file)); // strip GUID for PHPMailer class to name outbound file // only save attachments if we're archiving or drafting if ($this->type == 'draft' && !empty($this->id) || isset($request['saveToSugar']) && $request['saveToSugar'] == 1) { $note = new Note(); $note->id = create_guid(); $note->new_with_id = true; // duplicating the note with files $note->parent_id = $this->id; $note->parent_type = $this->module_dir; $note->name = $filename; $note->filename = $filename; $note->file_mime_type = $this->email2GetMime($fileLocation); $note->team_id = isset($_REQUEST['primaryteam']) ? $_REQUEST['primaryteam'] : $current_user->getPrivateTeamID(); $noteTeamSet = new TeamSet(); $noteteamIdsArray = isset($_REQUEST['teamIds']) ? explode(",", $_REQUEST['teamIds']) : array($current_user->getPrivateTeamID()); $note->team_set_id = $noteTeamSet->addTeams($noteteamIdsArray); $dest = "upload://{$note->id}"; if (!file_exists($fileLocation) || !copy($fileLocation, $dest)) { $GLOBALS['log']->debug("EMAIL 2.0: could not copy attachment file to {$fileLocation} => {$dest}"); } else { $note->save(); $validNote = true; } } else { $note = new Note(); $validNote = (bool) $note->retrieve($fileGUID); } if (isset($validNote) && $validNote === true) { $attachment = AttachmentPeer::attachmentFromSugarBean($note); if (!is_null($mailer)) { $mailer->addAttachment($attachment); } } } } } /* handle sugar documents */ if (!empty($request['documents'])) { $exDocs = explode("::", $request['documents']); foreach ($exDocs as $docId) { $docId = trim($docId); if (!empty($docId)) { $doc = new Document(); $doc->retrieve($docId); if (empty($doc->id) || $doc->id != $docId) { throw new Exception("Document Not Found: Id='" . $request['documents'] . "'"); } $documentRevision = new DocumentRevision(); $documentRevision->retrieve($doc->document_revision_id); //$documentRevision->x_file_name = $documentRevision->filename; //$documentRevision->x_file_path = "upload/{$documentRevision->id}"; //$documentRevision->x_file_exists = (bool) file_exists($documentRevision->x_file_path); //$documentRevision->x_mime_type = $documentRevision->file_mime_type; $filename = $documentRevision->filename; $docGUID = preg_replace('/[^a-z0-9\\-]/', "", $documentRevision->id); $fileLocation = "upload://{$docGUID}"; if (empty($documentRevision->id) || !file_exists($fileLocation)) { throw new Exception("Document Revision Id Not Found"); } // only save attachments if we're archiving or drafting if ($this->type == 'draft' && !empty($this->id) || isset($request['saveToSugar']) && $request['saveToSugar'] == 1) { $note = new Note(); $note->id = create_guid(); $note->new_with_id = true; // duplicating the note with files $note->parent_id = $this->id; $note->parent_type = $this->module_dir; $note->name = $filename; $note->filename = $filename; $note->file_mime_type = $documentRevision->file_mime_type; $note->team_id = $this->team_id; $note->team_set_id = $this->team_set_id; $dest = "upload://{$note->id}"; if (!file_exists($fileLocation) || !copy($fileLocation, $dest)) { $GLOBALS['log']->debug("EMAIL 2.0: could not copy SugarDocument revision file {$fileLocation} => {$dest}"); } $note->save(); } $attachment = AttachmentPeer::attachmentFromSugarBean($documentRevision); //print_r($attachment); if (!is_null($mailer)) { $mailer->addAttachment($attachment); } } } } /* handle template attachments */ if (!empty($request['templateAttachments'])) { $exNotes = explode("::", $request['templateAttachments']); foreach ($exNotes as $noteId) { $noteId = trim($noteId); if (!empty($noteId)) { $note = new Note(); $note->retrieve($noteId); if (!empty($note->id)) { $filename = $note->filename; $noteGUID = preg_replace('/[^a-z0-9\\-]/', "", $note->id); $fileLocation = "upload://{$noteGUID}"; $mime_type = $note->file_mime_type; if (!$note->embed_flag) { $attachment = AttachmentPeer::attachmentFromSugarBean($note); //print_r($attachment); if (!is_null($mailer)) { $mailer->addAttachment($attachment); } // only save attachments if we're archiving or drafting if ($this->type == 'draft' && !empty($this->id) || isset($request['saveToSugar']) && $request['saveToSugar'] == 1) { if ($note->parent_id != $this->id) { $this->saveTempNoteAttachments($filename, $fileLocation, $mime_type); } } // if } // if } else { $fileGUID = preg_replace('/[^a-z0-9\\-]/', "", substr($noteId, 0, 36)); $fileLocation = $this->et->userCacheDir . "/{$fileGUID}"; $filename = substr($noteId, 36, strlen($noteId)); // strip GUID for PHPMailer class to name outbound file $mimeType = $this->email2GetMime($fileLocation); $note = $this->saveTempNoteAttachments($filename, $fileLocation, $mimeType); $attachment = AttachmentPeer::attachmentFromSugarBean($note); //print_r($attachment); if (!is_null($mailer)) { $mailer->addAttachment($attachment); } } } } } /********************************************************************** * Final Touches */ if ($this->type == 'draft' && !$saveAsDraft) { // sending a draft email $this->type = 'out'; $this->status = 'sent'; $forceSave = true; } elseif ($saveAsDraft) { $this->type = 'draft'; $this->status = 'draft'; $forceSave = true; } if (!is_null($mailer)) { $mailer->send(); } } catch (MailerException $me) { $GLOBALS["log"]->error($me->getLogMessage()); throw $me; } catch (Exception $e) { // eat the phpmailerException but use it's message to provide context for the failure $me = new MailerException("Email2Send Failed: " . $e->getMessage(), MailerException::FailedToSend); $GLOBALS["log"]->error($me->getLogMessage()); $GLOBALS["log"]->info($me->getTraceMessage()); if (!empty($mailConfig)) { $GLOBALS["log"]->info($mailConfig->toArray(), true); } throw $me; } if (!(empty($orignialId) || $saveAsDraft || $this->type == 'draft' && $this->status == 'draft') && ($_REQUEST['composeType'] == 'reply' || $_REQUEST['composeType'] == 'replyAll' || $_REQUEST['composeType'] == 'replyCase') && $orignialId != $this->id) { $originalEmail = BeanFactory::getBean('Emails', $orignialId); $originalEmail->reply_to_status = 1; $originalEmail->save(); $this->reply_to_status = 0; } // if if (isset($_REQUEST['composeType']) && ($_REQUEST['composeType'] == 'reply' || $_REQUEST['composeType'] == 'replyCase')) { if (isset($_REQUEST['ieId']) && isset($_REQUEST['mbox'])) { $emailFromIe = BeanFactory::getBean('InboundEmail', $_REQUEST['ieId'], array('disable_row_level_security' => true)); $emailFromIe->mailbox = $_REQUEST['mbox']; if (isset($emailFromIe->id) && $emailFromIe->is_personal) { if ($emailFromIe->isPop3Protocol()) { $emailFromIe->mark_answered($this->uid, 'pop3'); } elseif ($emailFromIe->connectMailserver() == 'true') { $emailFromIe->markEmails($this->uid, 'answered'); $emailFromIe->mark_answered($this->uid); } } } } if ($forceSave || $this->type == 'draft' || $this->type == 'archived' || isset($request['saveToSugar']) && $request['saveToSugar'] == 1) { // Set Up From Name and Address Information if ($this->type == 'archived') { $this->from_addr = empty($request['archive_from_address']) ? '' : $request['archive_from_address']; } elseif (!empty($mailConfig)) { $sender = $mailConfig->getFrom(); $decodedFromName = mb_decode_mimeheader($sender->getName()); $this->from_addr = "{$decodedFromName} <" . $sender->getEmail() . ">"; } else { $ret = $current_user->getUsersNameAndEmail(); if (empty($ret['email'])) { $systemReturn = $current_user->getSystemDefaultNameAndEmail(); $ret['email'] = $systemReturn['email']; $ret['name'] = $systemReturn['name']; } $decodedFromName = mb_decode_mimeheader($ret['name']); $this->from_addr = "{$decodedFromName} <" . $ret['email'] . ">"; } $this->from_addr_name = $this->from_addr; $this->to_addrs = $_REQUEST['sendTo']; $this->to_addrs_names = $_REQUEST['sendTo']; $this->cc_addrs = $_REQUEST['sendCc']; $this->cc_addrs_names = $_REQUEST['sendCc']; $this->bcc_addrs = $_REQUEST['sendBcc']; $this->bcc_addrs_names = $_REQUEST['sendBcc']; $this->team_id = isset($_REQUEST['primaryteam']) ? $_REQUEST['primaryteam'] : $current_user->getPrivateTeamID(); $teamSet = BeanFactory::getBean('TeamSets'); $teamIdsArray = isset($_REQUEST['teamIds']) ? explode(",", $_REQUEST['teamIds']) : array($current_user->getPrivateTeamID()); $this->team_set_id = $teamSet->addTeams($teamIdsArray); $this->assigned_user_id = $current_user->id; $this->date_sent = $timedate->now(); /////////////////////////////////////////////////////////////////// //// LINK EMAIL TO SUGARBEANS BASED ON EMAIL ADDY if (!empty($_REQUEST['parent_type']) && !empty($_REQUEST['parent_id'])) { $this->parent_id = $this->db->quote($_REQUEST['parent_id']); $this->parent_type = $this->db->quote($_REQUEST['parent_type']); $a = $this->db->fetchOne("SELECT count(*) c FROM emails_beans WHERE email_id = '{$this->id}' AND bean_id = '{$this->parent_id}' AND bean_module = '{$this->parent_type}'"); if ($a['c'] == 0) { $bean = BeanFactory::getBean($_REQUEST['parent_type'], $_REQUEST['parent_id']); if (!empty($bean)) { if (!empty($bean->field_defs['emails']['type']) && $bean->field_defs['emails']['type'] == 'link') { $email_link = "emails"; } else { $email_link = $this->findEmailsLink($bean); } if ($email_link && $bean->load_relationship($email_link)) { $bean->{$email_link}->add($this); } } } // if } else { $c = BeanFactory::getBean('Cases'); if ($caseId = InboundEmail::getCaseIdFromCaseNumber($subject, $c)) { $c->retrieve($caseId); $c->load_relationship('emails'); $c->emails->add($this->id); $this->parent_type = "Cases"; $this->parent_id = $caseId; } // if } // else //// LINK EMAIL TO SUGARBEANS BASED ON EMAIL ADDY /////////////////////////////////////////////////////////////////// $this->save(); } /**** --------------------------------- ????????? if(!empty($request['fromAccount'])) { $ie = new InboundEmail(); $ie->retrieve($request['fromAccount']); if (isset($ie->id) && !$ie->isPop3Protocol() && $mail->oe->mail_smtptype != 'gmail') { $sentFolder = $ie->get_stored_options("sentFolder"); if (!empty($sentFolder)) { $data = $mail->CreateHeader() . "\r\n" . $mail->CreateBody() . "\r\n"; $ie->mailbox = $sentFolder; if ($ie->connectMailserver() == 'true') { $connectString = $ie->getConnectString($ie->getServiceString(), $ie->mailbox); $returnData = imap_append($ie->conn,$connectString, $data, "\\Seen"); if (!$returnData) { $GLOBALS['log']->debug("could not copy email to {$ie->mailbox} for {$ie->name}"); } // if } else { $GLOBALS['log']->debug("could not connect to mail serve for folder {$ie->mailbox} for {$ie->name}"); } // else } else { $GLOBALS['log']->debug("could not copy email to {$ie->mailbox} sent folder as its empty"); } // else } // if } // if ------------------------------------- ****/ return true; }