/** * Function will return display message of exception if its set by the calle. * if it is not set then we are generating some default display messages based * on mapi error code. * @return string returns error-message that should be sent to client to display. */ public function getDisplayMessage() { if (!empty($this->displayMessage)) { return $this->displayMessage; } switch ($this->getCode()) { case MAPI_E_NO_ACCESS: return dgettext("zarafa", "You have insufficient privileges to open this object."); case MAPI_E_LOGON_FAILED: case MAPI_E_UNCONFIGURED: return dgettext("zarafa", "Logon Failed. Please check your name/password."); case MAPI_E_NETWORK_ERROR: return dgettext("zarafa", "Can not connect to Zarafa server."); case MAPI_E_UNKNOWN_ENTRYID: return dgettext("zarafa", "Can not open object with provided id."); case MAPI_E_NO_RECIPIENTS: return dgettext("zarafa", "There are no recipients in the message."); case MAPI_E_NOT_FOUND: return dgettext("zarafa", "Can not find object."); case MAPI_E_NOT_ENOUGH_MEMORY: return dgettext("zarafa", "Operation failed: Server does not have enough memory."); case MAPI_E_INTERFACE_NOT_SUPPORTED: case MAPI_E_INVALID_PARAMETER: case MAPI_E_INVALID_ENTRYID: case MAPI_E_INVALID_OBJECT: case MAPI_E_TOO_COMPLEX: case MAPI_E_CORRUPT_DATA: case MAPI_E_END_OF_SESSION: case MAPI_E_AMBIGUOUS_RECIP: case MAPI_E_COLLISION: case MAPI_E_UNCONFIGURED: default: return sprintf(dgettext("zarafa", "Unknown MAPI Error: %s"), get_mapi_error_name($this->getCode())); } }
function checkMapiError($msg) { global $log; if (mapi_last_hresult() != 0) { $log->warn("MAPI error {$msg}: " . get_mapi_error_name()); exit; } }
function build() { $user = htmlentities($_GET["user"]); header("Content-type: text/html; charset=utf-8"); $cookyname = md5("ZARAFUSR_{$_SERVER['SERVER_NAME']}"); if (isset($cookyname)) { if (trim($user) == null) { $user = $_COOKIE[$cookyname]; } } if ($user != null) { $user_post = "&user={$user}"; } $langs = $GLOBALS["language"]->getLanguages(); uasort($langs, 'langsort'); foreach ($langs as $lang => $title) { $lls[] = "<option value=\"{$lang}\">{$title}</option>"; } $hidden = "<input type=\"hidden\" name=\"action_url\" value=\"" . stristr($_SERVER["REQUEST_URI"], "?action=") . "\"></input>"; if ($_POST && $_POST["action_url"] != "") { $hidden = "<input type=\"hidden\" name=\"action_url\" value=\"{$_POST["action_url"]}\"></input>"; } if (defined("DEBUG_SERVER_ADDRESS")) { $footer[] = "Server: " . DEBUG_SERVER_ADDRESS; } if (defined("DEBUG_SERVER_ADDRESS")) { $footer[] = phpversion("mapi"); } if (defined("SVN")) { $footer[] = "svn" . SVN; } if (isset($_SESSION) && isset($_SESSION["hresult"])) { switch ($_SESSION["hresult"]) { case MAPI_E_LOGON_FAILED: case MAPI_E_UNCONFIGURED: $error = _("Logon failed, please check your name/password."); break; case MAPI_E_NETWORK_ERROR: $error = _("Cannot connect to the Zarafa Server."); break; default: $error = "Unknown MAPI Error: " . get_mapi_error_name($_SESSION["hresult"]); } unset($_SESSION["hresult"]); } else { if (isset($_GET["logout"]) && $_GET["logout"] == "auto") { $error = _("You have been automatically logged out"); } else { $error = " "; } } $html = "\r\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n<html>\r\n\t<head>\r\n\t\t<title>Zarafa WebAccess</title>\r\n\t\t<STYLE type=\"text/css\">\r\n\t\t\r\n.ui-corner-bottom {\r\n -moz-border-radius-bottomleft: 3px;\r\n -moz-border-radius-bottomright: 3px;\r\n}\r\n.ui-corner-right {\r\n -moz-border-radius-bottomright: 3px;\r\n -moz-border-radius-topright: 3px;\r\n}\r\n.ui-corner-left {\r\n -moz-border-radius-bottomleft: 3px;\r\n -moz-border-radius-topleft: 3px;\r\n}\r\n.ui-corner-all {\r\n -moz-border-radius: 3px 3px 3px 3px;\r\n}\r\n.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default {\r\n background-color: #263849;\r\n color: #FFFFFF;\r\n font-weight: bold;\r\n}\r\n.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited {\r\n color: #FFFFFF;\r\n text-decoration: none;\r\n}\t\t\r\n\t\t\t\r\n\t\t\tbody{\r\n\t\t\t\tfont: 10pt Arial, Helvetica, sans-serif;\r\n\t\t\t\tbackground: #263849 url('/client/layout/img/i/pattern.png');\r\n\t\t\t}\r\n\t\t\t#sum{\r\n\t\t\t\twidth: 485px;\r\n\t\t\t\theight: 221px;\r\n\t\t\t\tmargin: 167px auto;\r\n\t\t\t\t\r\n\t\t\t}\r\n\t\t\th1{\r\n\t\t\t\twidth: 401px;\r\n\t\t\t\theight: 127px;\r\n\t\t\t\tbackground: transparent url('/client/layout/img/i/logo.png') no-repeat;\r\n\t\t\t\tmargin: 0 27px 21px;\r\n\t\t\t} \r\n\t\t\th1 span{\r\n\t\t\t\tdisplay: none;\r\n\t\t\t}\r\n\t\t\t#content{\r\n\t\t\t\twidth: 485px;\r\n\t\t\t\theight: 221px;\r\n\t\t\t\tbackground: url('/client/layout/img/i/form.png') no-repeat;\t\r\n\t\t\t}\r\n\t\t\t.f{\r\n\t\t\t\tpadding: 18px 50px 45px 38px;\t\r\n\t\t\t\toverflow: hidden;\r\n\t\t\t}\r\n\t\t\t.field{\r\n\t\t\t\tclear:both;\r\n\t\t\t\ttext-align: right;\r\n\t\t\t\tmargin-bottom: 15px;\r\n\t\t\t}\r\n\t\t\t.field label{\r\n\t\t\t\tfloat:left;\r\n\t\t\t\tfont-weight: bold;\r\n\t\t\t\tline-height: 42px;\r\n\t\t\t\tfont-size:14px;\r\n\t\t\t}\r\n\t\t\t.field input{\r\n\t\t\t\tbackground: #fff url('/client/layout/img/i/input.png') no-repeat;\r\n\t\t\t\toutline: none;\r\n\t\t\t\tborder: none;\r\n\t\t\t\tfont-size: 10pt;\r\n\t\t\t\tpadding: 7px 9px 8px;\r\n\t\t\t\twidth: 279px;\r\n\t\t\t\theight: 25px;\r\n\t\t\t\tfont-size: 18px;\r\n\t\t\t\tfont-weight:bolder;\r\n\t\t\t\tcolor:#444444;\r\n\t\t\t}\r\n\t\t\t.field input.active{\r\n\t\t\t\tbackground: url('/client/layout/img/i/input_act.png') no-repeat;\r\n\t\t\t}\r\n\t\t\t.button{\r\n\t\t\t\twidth: 297px;\r\n\t\t\t\tfloat: right;\r\n\t\t\t}\r\n\t\t\t.button input{\r\n\t\t\t\twidth: 69px;\r\n\t\t\t\tbackground: url('/client/layout/img/i/btn_bg.png') no-repeat;\r\n\t\t\t\tborder: 0;\r\n\t\t\t\tfont-weight: bold;\r\n\t\t\t\theight: 27px;\r\n\t\t\t\tfloat: left;\r\n\t\t\t\tpadding: 0;\r\n\t\t\t}\r\n\t\t</STYLE>\r\n\t\t<link rel=\"icon\" href=\"client/layout/img/favicon.ico\" type=\"image/x-icon\">\r\n\t\t<link rel=\"shortcut icon\" href=\"client/layout/img/favicon.ico\" type=\"image/x-icon\">\t\r\n\t\t<script type=\"text/javascript\">\r\n\t\t\twindow.onload = function(){\r\n\t\t\t\tif (document.getElementById(\"username\").value == \"\"){\r\n\t\t\t\t\tdocument.getElementById(\"username\").focus();\r\n\t\t\t\t}else if (document.getElementById(\"password\").value == \"\"){\r\n\t\t\t\t\tdocument.getElementById(\"password\").focus();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t</script>\r\n\t</head>\r\n\r\n <div id=\"sum\">\r\n <div id=\"header\">\r\n <h1><span>{TEMPLATE_TITLE_HEAD}</span></h1>\r\n </div>\r\n\r\n\r\n <center><span style='color:white;font-size:16px'>{$error}</span></center>\r\n\r\n <div id=\"content\">\r\n\r\n\t\t\t<form action=\"index.php?logon{$user_post}\" method='post' id='myform'>\r\n\t\t\t{$hidden}\r\n\t\t\t\r\n\t\t\t\t<div class=\"f\">\r\n\t\t\t\t\t<div class=\"field\">\r\n\t\t\t\t\t\t<label for=\"username\">" . _("Name") . ":</label> <input type=\"text\" name=\"username\" id=\"username\" \r\n\t\t\t\t\t\tonfocus=\"this.setAttribute('class','active')\" \r\n\t\t\t\t\t\tonblur=\"this.removeAttribute('class');\" \r\n\t\t\t\t\t\tOnKeyPress=\"javascript:SubmitZarafaFormCheck(event);\"\r\n\t\t\t\t\t\tvalue=\"{$user}\">\r\n\t\t\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<div class=\"field\">\r\n\t\t\t\t\t\t<label for=\"password\">" . _("Password") . ":</label> <input type=\"password\" name=\"password\" id=\"password\" \r\n\t\t\t\t\t\tonfocus=\"this.setAttribute('class','active')\" \r\n\t\t\t\t\t\tonblur=\"this.removeAttribute('class');\" \r\n\t\t\t\t\t\tOnKeyPress=\"javascript:SubmitZarafaFormCheck(event);\">\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<div class=\"field\">\r\n\t\t\t\t\t\t<label for=\"language\">" . _("Language") . ":</label> <select name=\"language\" id=\"language\" onfocus=\"this.setAttribute('class','active')\" onblur=\"this.removeAttribute('class');\">\r\n\t\t\t\t\t\t<option value=\"last\">" . _("Last used language") . "</option>\r\n\t\t\t\t\t\t" . @implode("\n", $lls) . "\r\n\t\t\t\t\t\t</select>\r\n\t\t\t\t\t</div>\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t<div class=\"field button\">\r\n\t\t\t\t\t\t<button onclick=\"javascript:this.className='ui-state-over';PushForm();\" class=\"ui-state-default ui-corner-all\" onmouseover=\"javascript:this.className='ui-state-active ui-corner-all';this.style.cursor='pointer'\" onmouseout=\"javascript:this.className='ui-state-default ui-corner-all';this.style.cursor='auto'\" style=\"padding: 3px; font-size: 18px; cursor: auto;\" type=\"submit\"> Login »</button>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\r\n\t\t\t</form>\t\t\t\r\n </div><!-- /#content -->\r\n \r\n\r\n <div class=\"footer\">\r\n \t\r\n \t<center style='font-size:13px;font-weight:bold;color:white'>" . @implode("-", $footer) . "</center>\r\n </div><!-- /#footer -->\r\n </div>\r\n \r\n <script>\r\n \tfunction SubmitZarafaFormCheck(e){\r\n \t\tif(checkEnter(e)){PushForm();}\r\n \t}\r\n \t\r\n \tfunction PushForm(){\r\n \t\tSet_Cookie('{$cookyname}',document.getElementById('username').value);\r\n \t\tdocument.forms['myform'].submit();\r\n \t}\r\n \r\n \r\n\tfunction checkEnter(e){\r\n\t\tvar characterCode \r\n\t\tcharacterCode = (typeof e.which != \"undefined\") ? e.which : event.keyCode;\r\n\t\tif(characterCode == 13){ return true;}else{return false;}\r\n\t} \r\n\t\r\nfunction Set_Cookie( name, value, expires, path, domain, secure ) {\r\n\tvar today = new Date();\r\n\ttoday.setTime( today.getTime() );\r\n\r\n\tif ( expires ){\r\n\t\texpires = expires * 1000 * 60 * 60 * 24;\r\n\t}\r\n\tvar expires_date = new Date( today.getTime() + (expires) );\r\n\r\n\tdocument.cookie = name + \"=\" +escape( value ) +\r\n\t( ( expires ) ? \";expires=\" + expires_date.toGMTString() : \"\" ) + \r\n\t( ( path ) ? \";path=\" + path : \"\" ) + \r\n\t( ( domain ) ? \";domain=\" + domain : \"\" ) +\r\n\t( ( secure ) ? \";secure\" : \"\" );\r\n}\t\r\n \r\n </script>\r\n \r\n</body>\r\n</html>\t\r\n"; echo $html; }
/** * Custom error handler, here we check to see if it is a MAPI error and dump all info * to the dump file, and finally we redirect the error back to PHP */ function zarafa_error_handler($errno, $errstr, $errfile, $errline, $errcontext) { $error = array("msg" => $errstr, "file" => $errfile . ":" . $errline); if ($errno == E_STRICT) { return; } if (strpos($errstr, "mapi_") !== false) { $error["mapi"] = get_mapi_error_name(); } dump($error, "ERROR", true); switch ($errno) { case E_WARNING: $errno = E_USER_WARNING; break; case E_STRICT: case E_NOTICE: $errno = E_USER_NOTICE; break; case E_ERROR: $errno = E_USER_ERROR; break; } trigger_error($errstr . " - " . $errfile . ":" . $errline, $errno); }
/** * Assign a contact picture to a contact * @param entryId contact entry id * @param contactPicture must be a valid jpeg file. If contactPicture is NULL will remove contact picture from contact if exists */ public function setContactPicture(&$contact, $contactPicture) { $this->logger->trace("setContactPicture"); // Find if contact picture is already set $contactAttachment = -1; $hasattachProp = mapi_getprops($contact, array(PR_HASATTACH)); if ($hasattachProp) { $attachmentTable = mapi_message_getattachmenttable($contact); $attachments = mapi_table_queryallrows($attachmentTable, array(PR_ATTACH_NUM, PR_ATTACH_SIZE, PR_ATTACH_LONG_FILENAME, PR_ATTACH_FILENAME, PR_ATTACHMENT_HIDDEN, PR_DISPLAY_NAME, PR_ATTACH_METHOD, PR_ATTACH_CONTENT_ID, PR_ATTACH_MIME_TAG, PR_ATTACHMENT_CONTACTPHOTO, PR_EC_WA_ATTACHMENT_HIDDEN_OVERRIDE)); foreach ($attachments as $attachmentRow) { if (isset($attachmentRow[PR_ATTACHMENT_CONTACTPHOTO]) && $attachmentRow[PR_ATTACHMENT_CONTACTPHOTO]) { $contactAttachment = $attachmentRow[PR_ATTACH_NUM]; break; } } } // Remove existing attachment if necessary if ($contactAttachment != -1) { $this->logger->trace("removing existing contact picture"); $attach = mapi_message_deleteattach($contact, $contactAttachment); } if ($contactPicture !== NULL) { $this->logger->debug("Saving contact picture as attachment"); // Create attachment $attach = mapi_message_createattach($contact); // Update contact attachment properties $properties = array(PR_ATTACH_SIZE => strlen($contactPicture), PR_ATTACH_LONG_FILENAME => 'ContactPicture.jpg', PR_ATTACHMENT_HIDDEN => false, PR_DISPLAY_NAME => 'ContactPicture.jpg', PR_ATTACH_METHOD => ATTACH_BY_VALUE, PR_ATTACH_MIME_TAG => 'image/jpeg', PR_ATTACHMENT_CONTACTPHOTO => true, PR_ATTACH_DATA_BIN => $contactPicture, PR_ATTACHMENT_FLAGS => 1, PR_ATTACH_EXTENSION_A => '.jpg', PR_ATTACH_NUM => 1); mapi_setprops($attach, $properties); mapi_savechanges($attach); } // Test if (mapi_last_hresult() > 0) { $this->logger->warn("Error saving contact picture: " . get_mapi_error_name()); } else { $this->logger->trace("contact picture done"); } }
/** * Creates a new card * * @param mixed $addressBookId * @param string $cardUri * @param string $cardData * @return bool */ public function createCard($addressBookId, $cardUri, $cardData) { $this->logger->info("createCard - {$cardUri}\n{$cardData}"); if (READ_ONLY) { $this->logger->warn("createCard failed: read-only"); return false; } $folder = mapi_msgstore_openentry($this->bridge->getStore($addressBookId), $addressBookId); $contact = mapi_folder_createmessage($folder); if (mapi_last_hresult() != 0) { $this->logger->fatal("MAPI error - cannot create contact: " . get_mapi_error_name()); return false; } $this->logger->trace("Getting properties from vcard"); $mapiProperties = $this->bridge->vcardToMapiProperties($cardData); $mapiProperties[PR_CARDDAV_URI] = $cardUri; if (SAVE_RAW_VCARD) { // Save RAW vCard $this->logger->debug("Saving raw vcard"); $mapiProperties[PR_CARDDAV_RAW_DATA] = $cardData; $mapiProperties[PR_CARDDAV_RAW_DATA_GENERATION_TIME] = time(); } // Handle contact picture $contactPicture = NULL; if (isset($mapiProperties['ContactPicture'])) { $this->logger->debug("Contact picture detected"); $contactPicture = $mapiProperties['ContactPicture']; unset($mapiProperties['ContactPicture']); $this->bridge->setContactPicture($contact, $contactPicture); } // Do not set empty properties $this->logger->trace("Removing empty properties"); foreach ($mapiProperties as $p => $v) { if (empty($v)) { unset($mapiProperties[$p]); } } // Add missing properties for new contacts $this->logger->trace("Adding missing properties for new contacts"); $p = $this->bridge->getExtendedProperties(); $mapiProperties[$p["icon_index"]] = "512"; $mapiProperties[$p["message_class"]] = 'IPM.Contact'; $mapiProperties[PR_LAST_MODIFICATION_TIME] = time(); // message flags ? mapi_setprops($contact, $mapiProperties); mapi_savechanges($contact); return mapi_last_hresult() == 0; }