Here is an enhanced fix for the "Mail for Exchange" sender name issue with this Zimbra backend using Nokia phones.
As before - if anyone can make the SOAP calls and/or response processing more efficient please chime in.
The basics -
Add new key(s) to config.php -
Code:
define('ZIMBRA_NOKIA_MFE_FIX',true);
and optionally add
define('ZIMBRA_NOKIA_MFE_ALWAYS_OVERWRITE', true); Then add the following code to the SendMail function in zimbra.php, at the very top. So ...
Code:
/* Sends a message which is passed as rfc822.
*/
function SendMail($rfc822, $forward = false, $reply = false, $parent = false) {
debugLog('START SendMail { rfc822 = (see next line); forward = ' . $forward . '; reply = ' . $reply . '; parent = ' . $parent . ' }');
$temp_file = tempnam(BASE_PATH . STATE_DIR . "/", "ZIMBRA_MSG_");
$handle = fopen($temp_file, "w"); becomes ...
Code:
/* Sends a message which is passed as rfc822.
*/
function SendMail($rfc822, $forward = false, $reply = false, $parent = false) {
debugLog('START SendMail { rfc822 = (see next line); forward = ' . $forward . '; reply = ' . $reply . '; parent = ' . $parent . ' }');
// Nokia Mail for Exchange has a habit of sending "Mail for Exchange" instead of the sender's name
// Searches on the internet blame this behaviour on individual phones, MFE versions, or the weather (kidding)
// The following code block will check for the presense of a key in the config.php file - 'ZIMBRA_NOKIA_MFE_FIX'
// If found, and set to true - the code will perform a SOAP GetInfoRequest to Zimbra
// The Response is searched for
if (defined('ZIMBRA_NOKIA_MFE_FIX')) {
if (ZIMBRA_NOKIA_MFE_FIX == true) {
debugLog( 'ZIMBRA_NOKIA_MFE_FIX is defined & TRUE' );
$useragent = $GLOBALS['useragent'];
debugLog("User-Agent " . $useragent);
$MFE = "MailforExchange";
$found = stripos($useragent, $MFE);
if ($found !== false) {
debugLog( 'User-Agent contains MailforExchange' );
$oldSender = '"Mail for Exchange" ';
// It seems some Nokia phones send garbage other than "Mail for Exchange" as the sender
// Enabling this second flag 'ZIMBRA_NOKIA_MFE_ALWAYS_OVERWRITE' and setting it to 'true'
// will overwrite whatever happens to be in the sender field - good or bad.
if (defined('ZIMBRA_NOKIA_MFE_ALWAYS_OVERWRITE')) {
if (ZIMBRA_NOKIA_MFE_ALWAYS_OVERWRITE == true) {
debugLog( 'ZIMBRA_NOKIA_MFE_ALWAYS_OVERWRITE is defined & TRUE' );
$fromHeader = "From: ";
$fromPos = stripos($rfc822, "From: ");
$lessThan = "<";
$lessThanPos = stripos($rfc822, "<", $fromPos);
$oldSender = substr( $rfc822, ($fromPos+6), ($lessThanPos-($fromPos+6)) );
debugLog( 'Old sender from email [' . $oldSender . ']' );
}
else {
debugLog( 'ZIMBRA_NOKIA_MFE_ALWAYS_OVERWRITE is set to FALSE' );
debugLog( 'Old sender DEFAULT value [' . $oldSender . ']' );
}
}
else {
debugLog( 'ZIMBRA_NOKIA_MFE_ALWAYS_OVERWRITE is NOT defined' );
debugLog( 'Old sender DEFAULT value [' . $oldSender . ']' );
}
$soap ='<GetInfoRequest xmlns="urn:zimbraAccount"/>';
$response = $this->SoapRequest($soap);
$replaceWith = "DEFAULT";
if ($response) {
$array = $this->MakeXMLTree($response);
// First Choice: search prefs for 'zimbraPrefFromDisplay'
$items = $array['soap:Envelope'][0]['soap:Body'][0]['GetInfoResponse'][0]['prefs'][0]['pref_attribute_name'];
$total = sizeof($items);
for ($i=0;$i<$total;$i++) {
if ( $items[$i] == 'zimbraPrefFromDisplay' ) {
$newSender = $array['soap:Envelope'][0]['soap:Body'][0]['GetInfoResponse'][0]['prefs'][0]['pref'][$i];
$replaceWith = 'zimbraPrefFromDisplay';
break;
}
}
if ( !$newSender ) {
debugLog( 'pref zimbraPrefFromDisplay NOT found' );
// if 'zimbraPrefFromDisplay' was not found
// Second Choice: search attrs for 'displayName' or 'cn'
//$displayName = "";
//$cn = "";
$items = $array['soap:Envelope'][0]['soap:Body'][0]['GetInfoResponse'][0]['attrs'][0]['attr_attribute_name'];
$total = sizeof($items);
for ($i=0;$i<$total;$i++) {
if ( $items[$i] == 'displayName' ) {
$newSender = $array['soap:Envelope'][0]['soap:Body'][0]['GetInfoResponse'][0]['attrs'][0]['attr'][$i];
$replaceWith = 'displayName';
break;
}
if ( $items[$i] == 'cn' ) {
$cn = $array['soap:Envelope'][0]['soap:Body'][0]['GetInfoResponse'][0]['attrs'][0]['attr'][$i];
$replaceWith = 'cn';
}
}
if ( !$newSender ) {
debugLog( 'attr displayName NOT found' );
if ( !$cn ) {
// Third Choice: display nothing rather than "Mail for Exchange"
// so don't set $newSender
debugLog( 'attr cn NOT found' );
}
else {
$newSender = $cn;
}
}
}
}
else {
debugLog( 'Got No SOAP Response' );
}
// Format $newSender as ["Sender Name" ] including quotes and trailing space
// If not found then set to empty string to remove old sender name without replacing
if (!$newSender) {
$newSender = "";
}
else {
$newSender = '"' . $newSender . '" ';
}
debugLog( 'New sender using [' . $replaceWith .'] is [' . $newSender . ']' );
debugLog( 'rfc822 Before: ' . $rfc822 );
$rfc822 = str_replace( $oldSender, $newSender, $rfc822 );
debugLog( 'rfc822 After: ' . $rfc822 );
}
else {
debugLog( 'User-Agent does not contain MailforExchange - Assume non-Nokia' );
}
}
else {
debugLog( 'ZIMBRA_NOKIA_MFE_FIX is set to FALSE' );
}
}
$temp_file = tempnam(BASE_PATH . STATE_DIR . "/", "ZIMBRA_MSG_");
$handle = fopen($temp_file, "w");
The code - if enabled by defining the ZIMBRA_NOKIA_MFE_FIX key and setting it to TRUE - now checks the User-Agent string for the presence of the Nokia identifier "MailforExchange" so that if an email is from an iPhone or a Windows Mobile phone, etc it will not attempt to make any changes.
If only the ZIMBRA_NOKIA_MFE_FIX key is defined and set to TRUE, the code will replace the default sender name string "Mail for Exchange" with the contents of the first one of the following it finds
zimbraPrefFromDisplay
displayName
cn
and, if for some strange reason you have none of these set on your account it will simple remove the "Mail for Exchange" and leave the email address without a "Text" label.
However, if the second key ZIMBRA_NOKIA_MFE_ALWAYS_OVERWRITE is also defined and set to TRUE , the code will try to pick off the existing sender name from the email, and then replace it as above. This should take care of the strange behaviour described by one of the posters above where they were getting an old profile name instead of "Mail for Exchange" listed as the sender.
Assuming it is useful to some people, please feel free to incorporate this fix into the main source