From 21781271e426f7ee177be77d8c8d58713bf0e84f Mon Sep 17 00:00:00 2001 From: Nathan Gray Date: Tue, 2 Jun 2015 21:21:21 +0000 Subject: [PATCH] Fix some problems with merging into email files: - Use correct merge sub-class when merging multiple entries - Accept merge placeholders in to/cc/bcc fields (displayed as invalid, but still accepted) - Use merge placeholders to pull addresses from associated entry --- .../inc/class.emailadmin_imapbase.inc.php | 55 ++++++++++++++----- etemplate/inc/class.bo_merge.inc.php | 2 +- .../class.etemplate_widget_taglist.inc.php | 5 +- mail/inc/class.mail_compose.inc.php | 12 ++-- 4 files changed, 55 insertions(+), 19 deletions(-) diff --git a/emailadmin/inc/class.emailadmin_imapbase.inc.php b/emailadmin/inc/class.emailadmin_imapbase.inc.php index 6dada51d71..025588d010 100644 --- a/emailadmin/inc/class.emailadmin_imapbase.inc.php +++ b/emailadmin/inc/class.emailadmin_imapbase.inc.php @@ -6066,6 +6066,7 @@ class emailadmin_imapbase $AltBody = ($html_body = $mailObject->findBody('html')) ? $html_body->getContents() : null; //error_log(__METHOD__.' ('.__LINE__.') '.' AltBody:'.$AltBody); //error_log(__METHOD__.' ('.__LINE__.') '.array2string($mailObject->GetReplyTo())); + // Fetch ReplyTo - Address if existing to check if we are to replace it $replyTo = $mailObject->getReplyTo(); if (isset($replyTo['replace@import.action'])) @@ -6078,18 +6079,40 @@ class emailadmin_imapbase } foreach ($SendAndMergeTocontacts as $k => $val) { - $errorInfo = ''; + $errorInfo = $email = ''; $sendOK = $openComposeWindow = $openAsDraft = null; //error_log(__METHOD__.' ('.__LINE__.') '.' Id To Merge:'.$val); if (/*$GLOBALS['egw_info']['flags']['currentapp'] == 'addressbook' &&*/ - count($SendAndMergeTocontacts) > 1 && - is_numeric($val) || $GLOBALS['egw']->accounts->name2id($val)) // do the merge + count($SendAndMergeTocontacts) > 1 && $val && + (is_numeric($val) || $GLOBALS['egw']->accounts->name2id($val))) // do the merge { //error_log(__METHOD__.' ('.__LINE__.') '.array2string($mailObject)); - $contact = $bo_merge->contacts->read($val); - //error_log(__METHOD__.' ('.__LINE__.') '.' ID:'.$val.' Data:'.array2string($contact)); - $email = ($contact['email'] ? $contact['email'] : $contact['email_home']); - $nfn = ($contact['n_fn'] ? $contact['n_fn'] : $contact['n_given'].' '.$contact['n_family']); + + // Parse destinations for placeholders + foreach(egw_mailer::$type2header as $type => $h) + { + //error_log('ID ' . $val . ' ' .$type . ': ' . $mailObject->getHeader(egw_mailer::$type2header[$type]) . ' -> ' .$bo_merge->merge_string($mailObject->getHeader(egw_mailer::$type2header[$type]),$val,$e,'text/plain',array(),self::$displayCharset)); + $merged = $bo_merge->merge_string($mailObject->getHeader(egw_mailer::$type2header[$type]),$val,$e,'text/plain',array(),self::$displayCharset); + $mailObject->addAddress($merged,'',$type); + if($type == 'to') + { + $email = $merged; + } + } + + // No addresses from placeholders? Treat it as just a contact ID + if (!$email) + { + $contact = $bo_merge->contacts->read($val); + //error_log(__METHOD__.' ('.__LINE__.') '.' ID:'.$val.' Data:'.array2string($contact)); + $email = ($contact['email'] ? $contact['email'] : $contact['email_home']); + $nfn = ($contact['n_fn'] ? $contact['n_fn'] : $contact['n_given'].' '.$contact['n_family']); + if($email) + { + $mailObject->addAddress(self::$idna2->encode($email),$mailObject->EncodeHeader($nfn)); + } + } + $activeMailProfiles = $this->getAccountIdentities($this->profileID); $activeMailProfile = self::getStandardIdentityForProfile($activeMailProfiles,$this->profileID); //error_log(__METHOD__.' ('.__LINE__.') '.array2string($activeMailProfile)); @@ -6098,14 +6121,12 @@ class emailadmin_imapbase $mailObject->removeHeader('Message-ID'); $mailObject->removeHeader('Date'); - $mailObject->clearAllRecipients(); $mailObject->clearCustomHeaders(); - $mailObject->addAddress(self::$idna2->encode($email),$mailObject->EncodeHeader($nfn)); $mailObject->addHeader('Subject', $bo_merge->merge_string($Subject, $val, $e, 'text/plain', array(), self::$displayCharset)); //error_log(__METHOD__.' ('.__LINE__.') '.' ContentType:'.$mailObject->BodyContentType); - if (!empty($Body)) $text_body->setContents($bo_merge->merge_string($Body, $val, $e, 'text/plain', array(), self::$displayCharset),array('encoding'=>Horde_Mime_Part::DEFAULT_ENCODING)); + if($text_body) $text_body->setContents($bo_merge->merge_string($Body, $val, $e, 'text/plain', array(), self::$displayCharset),array('encoding'=>Horde_Mime_Part::DEFAULT_ENCODING)); //error_log(__METHOD__.' ('.__LINE__.') '.' Result:'.$mailObject->Body.' error:'.array2string($e)); - if (!empty($AltBody)) $html_body->setContents($bo_merge->merge_string($AltBody, $val, $e, 'text/html', array(), self::$displayCharset),array('encoding'=>Horde_Mime_Part::DEFAULT_ENCODING)); + if($html_body) $html_body->setContents($bo_merge->merge_string($AltBody, $val, $e, 'text/html', array(), self::$displayCharset),array('encoding'=>Horde_Mime_Part::DEFAULT_ENCODING)); //error_log(__METHOD__.' ('.__LINE__.') '.array2string($mailObject)); // set a higher timeout for big messages @@ -6125,9 +6146,17 @@ class emailadmin_imapbase $openAsDraft = true; $mailObject->removeHeader('Message-ID'); $mailObject->removeHeader('Date'); - $mailObject->clearAllRecipients(); $mailObject->clearCustomHeaders(); - if (/*$GLOBALS['egw_info']['flags']['currentapp'] == 'addressbook' &&*/ + + // Parse destinations for placeholders + foreach(egw_mailer::$type2header as $type => $h) + { + //error_log($type . ': ' . $mailObject->getHeader(egw_mailer::$type2header[$type]) . ' -> ' .$bo_merge->merge_string($mailObject->getHeader(egw_mailer::$type2header[$type]),$val,$e,'text/plain',array(),self::$displayCharset)); + $mailObject->addAddress($bo_merge->merge_string($mailObject->getHeader(egw_mailer::$type2header[$type]),$val,$e,'text/plain',array(),self::$displayCharset),'',$type); + } + + // No addresses from placeholders? Treat it as just a contact ID + if (count($mailObject->getAddresses('to',true)) == 0 && is_numeric($val) || $GLOBALS['egw']->accounts->name2id($val)) // do the merge { $contact = $bo_merge->contacts->read($val); diff --git a/etemplate/inc/class.bo_merge.inc.php b/etemplate/inc/class.bo_merge.inc.php index ca470765ea..38da7b7fe3 100644 --- a/etemplate/inc/class.bo_merge.inc.php +++ b/etemplate/inc/class.bo_merge.inc.php @@ -1878,7 +1878,7 @@ abstract class bo_merge $action['nm_action'] = 'long_task'; $action['popup'] = egw_link::get_registry('mail', 'edit_popup'); $action['message'] = lang('insert in %1',egw_vfs::decodePath($file['name'])); - $action['menuaction'] = 'mail.mail_compose.ajax_merge&document='.$file['path']; + $action['menuaction'] = 'mail.mail_compose.ajax_merge&document='.$file['path'].'&merge='. get_called_class(); } /** diff --git a/etemplate/inc/class.etemplate_widget_taglist.inc.php b/etemplate/inc/class.etemplate_widget_taglist.inc.php index b55ef2a6a6..535f374b1b 100644 --- a/etemplate/inc/class.etemplate_widget_taglist.inc.php +++ b/etemplate/inc/class.etemplate_widget_taglist.inc.php @@ -120,7 +120,10 @@ class etemplate_widget_taglist extends etemplate_widget self::set_validation_error($form_name,lang("'%1' is NOT allowed ('%2')!",$val,implode("','",array_keys($lists))),''); } } - else if($this->type == 'taglist-email' && !preg_match(etemplate_widget_url::EMAIL_PREG, $val)) + else if($this->type == 'taglist-email' && !preg_match(etemplate_widget_url::EMAIL_PREG, $val) && + // Allow merge placeholders. Might be a better way to do this though. + !preg_match('/{{.+}}|\$\$.+\$\$/',$val) + ) { self::set_validation_error($form_name,lang("'%1' has an invalid format",$val),''); } diff --git a/mail/inc/class.mail_compose.inc.php b/mail/inc/class.mail_compose.inc.php index 256efd86bb..dd2baad2e8 100644 --- a/mail/inc/class.mail_compose.inc.php +++ b/mail/inc/class.mail_compose.inc.php @@ -3364,7 +3364,14 @@ class mail_compose public function ajax_merge($contact_id) { $response = egw_json_response::get(); - $document_merge = new addressbook_merge(); + if(class_exists($_REQUEST['merge']) && is_subclass_of($_REQUEST['merge'],'bo_merge')) + { + $document_merge = new $_REQUEST['merge'](); + } + else + { + $document_merge = new addressbook_merge(); + } $this->mail_bo->openConnection(); if(($error = $document_merge->check_document($_REQUEST['document'],''))) @@ -3373,9 +3380,6 @@ class mail_compose return; } - // Merge does not work correctly (missing to) if current app is not addressbook - //$GLOBALS['egw_info']['flags']['currentapp'] = 'addressbook'; - // Actually do the merge $folder = $merged_mail_id = null; $results = $this->mail_bo->importMessageToMergeAndSend(