I have fixed the "Mail for Exchange" sender name issue with this Zimbra backend.
It took me a long time to figure out how to extract information from the SoapResponse as I have never used the Soap API before, and I am sure I have not done this in the most efficient manner - so if the OP or anyone else here can help to streamline the calls to Zimbra - please chime in.
The basics -
Add a new key to config.php -
Code:
define('ZIMBRA_NOKIA_MFE_FIX',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( 'NokiaMFEFix is defined & true' );
$useragent = $GLOBALS['useragent'];
debugLog("User-Agent " . $useragent);
$MFE = "MailforExchange";
$found = stripos($useragent, $MFE);
if ($found !== false) {
debugLog( 'User-Agent contains MailforExchange' );
debugLog( 'rfc822: ' . $rfc822 );
$MFE = '"Mail for Exchange" ';
$soap ='<GetInfoRequest xmlns="urn:zimbraAccount"/>';
$response = $this->SoapRequest($soap);
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' ) {
debugLog( 'Got : ' . $items[$i] );
$displayName = $array['soap:Envelope'][0]['soap:Body'][0]['GetInfoResponse'][0]['prefs'][0]['pref'][$i];
break;
}
}
if ( $i == $total ) {
debugLog( 'Found No zimbraPrefFromDisplay' );
// 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' ) {
debugLog( 'Got : ' . $items[$i] );
$displayName = $array['soap:Envelope'][0]['soap:Body'][0]['GetInfoResponse'][0]['attrs'][0]['attr'][$i];
}
if ( $items[$i] == 'cn' ) {
debugLog( 'Got : ' . $items[$i] );
$cn = $array['soap:Envelope'][0]['soap:Body'][0]['GetInfoResponse'][0]['attrs'][0]['attr'][$i];
}
}
if ( !$displayName ) {
debugLog( 'Found No displayName ' );
if ( !$cn ) {
// Third Choice: display nothing rather than "Mail for Exchange"
debugLog( 'Found No cn : Clearing "Mail for Exchange"' );
}
else {
debugLog( 'Using cn as FROM ADDRESS' );
$displayName = $cn;
}
}
// Format $display_name as ["Display Name" ] including quotes and trailing space
if (!$displayName) {
$displayName = "";
}
else {
$displayName = '"' . $displayName . '" ';
}
debugLog( 'displayName [' . $displayName . ']' );
}
debugLog( 'Got [' . $displayName . ']' );
}
else {
debugLog( 'Got No SOAP Response' );
$displayName = ""; //default to nothing - better than "Mail for Exchange"
}
$rfc822 = str_replace( $MFE, $displayName, $rfc822 );
debugLog( 'rfc822: ' . $rfc822 );
}
else {
debugLog( 'User-Agent does not contain MailforExchange' );
}
}
else {
debugLog( 'NokiaMFEFix is set to FALSE' );
}
}
$temp_file = tempnam(BASE_PATH . STATE_DIR . "/", "ZIMBRA_MSG_");
$handle = fopen($temp_file, "w"); The code will replace "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.
UPDATED: 2010-04-09 - Added User-Agent test to identify only Nokia phones