Back to index

d-push  2.0
mapiutils.php
Go to the documentation of this file.
00001 <?php
00002 /***********************************************
00003 * File      :   mapiutils.php
00004 * Project   :   Z-Push
00005 * Descr     :
00006 *
00007 * Created   :   14.02.2011
00008 *
00009 * Copyright 2007 - 2011 Zarafa Deutschland GmbH
00010 *
00011 * This program is free software: you can redistribute it and/or modify
00012 * it under the terms of the GNU Affero General Public License, version 3,
00013 * as published by the Free Software Foundation with the following additional
00014 * term according to sec. 7:
00015 *
00016 * According to sec. 7 of the GNU Affero General Public License, version 3,
00017 * the terms of the AGPL are supplemented with the following terms:
00018 *
00019 * "Zarafa" is a registered trademark of Zarafa B.V.
00020 * "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
00021 * The licensing of the Program under the AGPL does not imply a trademark license.
00022 * Therefore any rights, title and interest in our trademarks remain entirely with us.
00023 *
00024 * However, if you propagate an unmodified version of the Program you are
00025 * allowed to use the term "Z-Push" to indicate that you distribute the Program.
00026 * Furthermore you may use our trademarks where it is necessary to indicate
00027 * the intended purpose of a product or service provided you use it in accordance
00028 * with honest practices in industrial or commercial matters.
00029 * If you want to propagate modified versions of the Program under the name "Z-Push",
00030 * you may only do so if you have a written permission by Zarafa Deutschland GmbH
00031 * (to acquire a permission please contact Zarafa at trademark@zarafa.com).
00032 *
00033 * This program is distributed in the hope that it will be useful,
00034 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00035 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00036 * GNU Affero General Public License for more details.
00037 *
00038 * You should have received a copy of the GNU Affero General Public License
00039 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00040 *
00041 * Consult LICENSE file for details
00042 ************************************************/
00043 
00050 class MAPIUtils {
00051 
00061     public static function GetEmailRestriction($timestamp) {
00062         $restriction = array ( RES_PROPERTY,
00063                           array (   RELOP => RELOP_GE,
00064                                     ULPROPTAG => PR_MESSAGE_DELIVERY_TIME,
00065                                     VALUE => $timestamp
00066                           )
00067                       );
00068 
00069         return $restriction;
00070     }
00071 
00072 
00082     //TODO getting named properties
00083     public static function GetCalendarRestriction($store, $timestamp) {
00084         // This is our viewing window
00085         $start = $timestamp;
00086         $end = 0x7fffffff; // infinite end
00087 
00088         $props = MAPIMapping::GetAppointmentProperties();
00089         $props = getPropIdsFromStrings($store, $props);
00090 
00091         $restriction = Array(RES_OR,
00092              Array(
00093                    // OR
00094                    // item.end > window.start && item.start < window.end
00095                    Array(RES_AND,
00096                          Array(
00097                                Array(RES_PROPERTY,
00098                                      Array(RELOP => RELOP_LE,
00099                                            ULPROPTAG => $props["starttime"],
00100                                            VALUE => $end
00101                                            )
00102                                      ),
00103                                Array(RES_PROPERTY,
00104                                      Array(RELOP => RELOP_GE,
00105                                            ULPROPTAG => $props["endtime"],
00106                                            VALUE => $start
00107                                            )
00108                                      )
00109                                )
00110                          ),
00111                    // OR
00112                    Array(RES_OR,
00113                          Array(
00114                                // OR
00115                                // (EXIST(recurrence_enddate_property) && item[isRecurring] == true && item[end] >= start)
00116                                Array(RES_AND,
00117                                      Array(
00118                                            Array(RES_EXIST,
00119                                                  Array(ULPROPTAG => $props["recurrenceend"],
00120                                                        )
00121                                                  ),
00122                                            Array(RES_PROPERTY,
00123                                                  Array(RELOP => RELOP_EQ,
00124                                                        ULPROPTAG => $props["isrecurring"],
00125                                                        VALUE => true
00126                                                        )
00127                                                  ),
00128                                            Array(RES_PROPERTY,
00129                                                  Array(RELOP => RELOP_GE,
00130                                                        ULPROPTAG => $props["recurrenceend"],
00131                                                        VALUE => $start
00132                                                        )
00133                                                  )
00134                                            )
00135                                      ),
00136                                // OR
00137                                // (!EXIST(recurrence_enddate_property) && item[isRecurring] == true && item[start] <= end)
00138                                Array(RES_AND,
00139                                      Array(
00140                                            Array(RES_NOT,
00141                                                  Array(
00142                                                        Array(RES_EXIST,
00143                                                              Array(ULPROPTAG => $props["recurrenceend"]
00144                                                                    )
00145                                                              )
00146                                                        )
00147                                                  ),
00148                                            Array(RES_PROPERTY,
00149                                                  Array(RELOP => RELOP_LE,
00150                                                        ULPROPTAG => $props["starttime"],
00151                                                        VALUE => $end
00152                                                        )
00153                                                  ),
00154                                            Array(RES_PROPERTY,
00155                                                  Array(RELOP => RELOP_EQ,
00156                                                        ULPROPTAG => $props["isrecurring"],
00157                                                        VALUE => true
00158                                                        )
00159                                                  )
00160                                            )
00161                                      )
00162                                )
00163                          ) // EXISTS OR
00164                    )
00165              );        // global OR
00166 
00167         return $restriction;
00168     }
00169 
00170 
00177     public static function GetContactPicRestriction() {
00178         return array ( RES_PROPERTY,
00179                         array (
00180                             RELOP => RELOP_EQ,
00181                             ULPROPTAG => mapi_prop_tag(PT_BOOLEAN, 0x7FFF),
00182                             VALUE => true
00183                         )
00184         );
00185     }
00186 
00187 
00196     public static function GetSearchRestriction($query) {
00197         return array(RES_AND,
00198                     array(
00199                         array(RES_OR,
00200                             array(
00201                                 array(RES_CONTENT, array(FUZZYLEVEL => FL_SUBSTRING | FL_IGNORECASE, ULPROPTAG => PR_DISPLAY_NAME, VALUE => $query)),
00202                                 array(RES_CONTENT, array(FUZZYLEVEL => FL_SUBSTRING | FL_IGNORECASE, ULPROPTAG => PR_ACCOUNT, VALUE => $query)),
00203                             ), // RES_OR
00204                         ),
00205                         array(
00206                             RES_PROPERTY,
00207                             array(RELOP => RELOP_EQ, ULPROPTAG => PR_OBJECT_TYPE, VALUE => MAPI_MAILUSER)
00208                         )
00209                     ) // RES_AND
00210         );
00211     }
00212 
00213 
00222     public static function handleRecurringItem(&$mapiprops, &$props) {
00223         $mapiprops[$props["isrecurringtag"]] = true;
00224         $mapiprops[$props["sideeffects"]] = 369;
00225         //both goids have the same value
00226         $mapiprops[$props["goid2tag"]] = $mapiprops[$props["goidtag"]];
00227         $mapiprops[$props["type"]] = "IPM.Appointment";
00228         $mapiprops[$props["busystatus"]] = 1; //tentative
00229         $mapiprops[PR_RESPONSE_REQUESTED] = true;
00230         $mapiprops[PR_ICON_INDEX] = 1027;
00231         $mapiprops[$props["meetingstatus"]] = olMeetingReceived; // The recipient is receiving the request
00232         $mapiprops[$props["responsestatus"]] = olResponseNotResponded;
00233         $mapiprops[$props["usetnef"]] = true;
00234     }
00235 
00236 
00246     public static function readPropStream($message, $prop) {
00247         $stream = mapi_openproperty($message, $prop, IID_IStream, 0, 0);
00248         $data = "";
00249         $string = "";
00250         while(1) {
00251             $data = mapi_stream_read($stream, 1024);
00252             if(strlen($data) == 0)
00253                 break;
00254             $string .= $data;
00255         }
00256 
00257         return $string;
00258     }
00259 
00260 
00267     public static function IsUnicodeStore($store) {
00268         $supportmask = mapi_getprops($store, array(PR_STORE_SUPPORT_MASK));
00269         if (isset($supportmask[PR_STORE_SUPPORT_MASK]) && ($supportmask[PR_STORE_SUPPORT_MASK] & STORE_UNICODE_OK)) {
00270             ZLog::Write(LOGLEVEL_DEBUG, "Store supports properties containing Unicode characters.");
00271             define('STORE_SUPPORTS_UNICODE', true);
00272             //setlocale to UTF-8 in order to support properties containing Unicode characters
00273             setlocale(LC_CTYPE, "en_US.UTF-8");
00274             define('STORE_INTERNET_CPID', INTERNET_CPID_UTF8);
00275         }
00276     }
00277 
00287     public static function StoreAttachment($mapimessage, $part) {
00288         // attachment
00289         $attach = mapi_message_createattach($mapimessage);
00290 
00291         $filename = "";
00292         // Filename is present in both Content-Type: name=.. and in Content-Disposition: filename=
00293         if(isset($part->ctype_parameters["name"]))
00294             $filename = $part->ctype_parameters["name"];
00295         else if(isset($part->d_parameters["name"]))
00296             $filename = $part->d_parameters["filename"];
00297         else if (isset($part->d_parameters["filename"])) // sending appointment with nokia & android only filename is set
00298             $filename = $part->d_parameters["filename"];
00299         // filenames with more than 63 chars as splitted several strings
00300         else if (isset($part->d_parameters["filename*0"])) {
00301             for ($i=0; $i< count($part->d_parameters); $i++)
00302                if (isset($part->d_parameters["filename*".$i]))
00303                    $filename .= $part->d_parameters["filename*".$i];
00304         }
00305         else
00306             $filename = "untitled";
00307 
00308         // Android just doesn't send content-type, so mimeDecode doesn't performs base64 decoding
00309         // on meeting requests text/calendar somewhere inside content-transfer-encoding
00310         if (isset($part->headers['content-transfer-encoding']) && strpos($part->headers['content-transfer-encoding'], 'base64')) {
00311             if (strpos($part->headers['content-transfer-encoding'], 'text/calendar') !== false) {
00312                 $part->ctype_primary = 'text';
00313                 $part->ctype_secondary = 'calendar';
00314             }
00315             if (!isset($part->headers['content-type']))
00316                 $part->body = base64_decode($part->body);
00317         }
00318 
00319         mapi_setprops($attach, array(
00320             // Set filename and attachment type
00321             PR_ATTACH_LONG_FILENAME => u2wi($filename),
00322             PR_ATTACH_METHOD => ATTACH_BY_VALUE,
00323             // Set attachment data
00324             PR_ATTACH_DATA_BIN => $part->body,
00325             // Set MIME type
00326             PR_ATTACH_MIME_TAG => $part->ctype_primary . "/" . $part->ctype_secondary));
00327 
00328         ZLog::Write(LOGLEVEL_DEBUG, sprintf("Utils::StoreAttachment: Attachment '%s' with %d bytes saved", $filename, strlen($part->body)));
00329         return mapi_savechanges($attach);
00330     }
00331 
00340     public static function GetContainerClassFromFolderType($foldertype) {
00341         switch ($foldertype) {
00342             case SYNC_FOLDER_TYPE_TASK:
00343             case SYNC_FOLDER_TYPE_USER_TASK:
00344                 return "IPF.Task";
00345                 break;
00346 
00347             case SYNC_FOLDER_TYPE_APPOINTMENT:
00348             case SYNC_FOLDER_TYPE_USER_APPOINTMENT:
00349                 return "IPF.Appointment";
00350                 break;
00351 
00352             case SYNC_FOLDER_TYPE_CONTACT:
00353             case SYNC_FOLDER_TYPE_USER_CONTACT:
00354                 return "IPF.Contact";
00355                 break;
00356 
00357             case SYNC_FOLDER_TYPE_NOTE:
00358             case SYNC_FOLDER_TYPE_USER_NOTE:
00359                 return "IPF.StickyNote";
00360                 break;
00361 
00362             case SYNC_FOLDER_TYPE_JOURNAL:
00363             case SYNC_FOLDER_TYPE_USER_JOURNAL:
00364                 return "IPF.Journal";
00365                 break;
00366 
00367             case SYNC_FOLDER_TYPE_INBOX:
00368             case SYNC_FOLDER_TYPE_DRAFTS:
00369             case SYNC_FOLDER_TYPE_WASTEBASKET:
00370             case SYNC_FOLDER_TYPE_SENTMAIL:
00371             case SYNC_FOLDER_TYPE_OUTBOX:
00372             case SYNC_FOLDER_TYPE_USER_MAIL:
00373             case SYNC_FOLDER_TYPE_OTHER:
00374             case SYNC_FOLDER_TYPE_UNKNOWN:
00375             default:
00376                 return "IPF.Note";
00377                 break;
00378         }
00379     }
00380 
00381 }
00382 
00383 ?>