function foldersize($store, $entryid) { $size = 0; $folder = mapi_msgstore_openentry($store, $entryid); if (!$folder) { print "Unable to open folder."; return false; } $table = mapi_folder_getcontentstable($folder); if (!$table) { print "Unable to open table."; return false; } while (1) { $rows = mapi_table_queryrows($table, array(PR_MESSAGE_SIZE), 0, 100); if (count($rows) == 0) { break; } foreach ($rows as $row) { if (isset($row[PR_MESSAGE_SIZE])) { $size += $row[PR_MESSAGE_SIZE]; } } } return $size; }
/** * Publishes the infomation * @paam timestamp $starttime Time from which to publish data (usually now) * @paam integer $length Amount of seconds from $starttime we should publish */ function publishFB($starttime, $length) { $start = $starttime; $end = $starttime + $length; // Get all the items in the calendar that we need $calendaritems = array(); $restrict = array(RES_OR, array(array(RES_AND, array(array(RES_PROPERTY, array(RELOP => RELOP_GE, ULPROPTAG => $this->proptags["startdate"], VALUE => $start)), array(RES_PROPERTY, array(RELOP => RELOP_LE, ULPROPTAG => $this->proptags["startdate"], VALUE => $end)))), array(RES_AND, array(array(RES_PROPERTY, array(RELOP => RELOP_GE, ULPROPTAG => $this->proptags["duedate"], VALUE => $start)), array(RES_PROPERTY, array(RELOP => RELOP_LE, ULPROPTAG => $this->proptags["duedate"], VALUE => $end)))), array(RES_AND, array(array(RES_PROPERTY, array(RELOP => RELOP_LT, ULPROPTAG => $this->proptags["startdate"], VALUE => $start)), array(RES_PROPERTY, array(RELOP => RELOP_GT, ULPROPTAG => $this->proptags["duedate"], VALUE => $end)))), array(RES_OR, array(array(RES_AND, array(array(RES_EXIST, array(ULPROPTAG => $this->proptags["enddate_recurring"])), array(RES_PROPERTY, array(RELOP => RELOP_EQ, ULPROPTAG => $this->proptags["recurring"], VALUE => true)), array(RES_PROPERTY, array(RELOP => RELOP_GE, ULPROPTAG => $this->proptags["enddate_recurring"], VALUE => $start)))), array(RES_AND, array(array(RES_NOT, array(array(RES_EXIST, array(ULPROPTAG => $this->proptags["enddate_recurring"])))), array(RES_PROPERTY, array(RELOP => RELOP_LE, ULPROPTAG => $this->proptags["startdate"], VALUE => $end)), array(RES_PROPERTY, array(RELOP => RELOP_EQ, ULPROPTAG => $this->proptags["recurring"], VALUE => true)))))))); // global OR $contents = mapi_folder_getcontentstable($this->calendar); mapi_table_restrict($contents, $restrict); while (1) { $rows = mapi_table_queryrows($contents, array_values($this->proptags), 0, 50); if (!is_array($rows)) { break; } if (empty($rows)) { break; } foreach ($rows as $row) { $occurrences = array(); if (isset($row[$this->proptags['recurring']]) && $row[$this->proptags['recurring']]) { $recur = new Recurrence($this->store, $row); $occurrences = $recur->getItems($starttime, $starttime + $length); } else { $occurrences[] = $row; } $calendaritems = array_merge($calendaritems, $occurrences); } } // $calendaritems now contains all the calendar items in the specified time // frame. We now need to merge these into a flat array of begin/end/status // objects. This also filters out all the 'free' items (status 0) $freebusy = $this->mergeItemsFB($calendaritems); // $freebusy now contains the start, end and status of all items, merged. // Get the FB interface try { $fbsupport = mapi_freebusysupport_open($this->session, $this->store); } catch (MAPIException $e) { if ($e->getCode() == MAPI_E_NOT_FOUND) { $e->setHandled(); if (function_exists("dump")) { dump("Error in opening freebusysupport object."); } } } // Open updater for this user if (isset($fbsupport)) { $updaters = mapi_freebusysupport_loadupdate($fbsupport, array($this->entryid)); $updater = $updaters[0]; // Send the data mapi_freebusyupdate_reset($updater); mapi_freebusyupdate_publish($updater, $freebusy); mapi_freebusyupdate_savechanges($updater, $start - 24 * 60 * 60, $end); // We're finished mapi_freebusysupport_close($fbsupport); } }
/** * Note: Static function, more like a utility function. * * Gets all the items (including recurring items) in the specified calendar in the given timeframe. Items are * included as a whole if they overlap the interval <$start, $end> (non-inclusive). This means that if the interval * is <08:00 - 14:00>, the item [6:00 - 8:00> is NOT included, nor is the item [14:00 - 16:00>. However, the item * [7:00 - 9:00> is included as a whole, and is NOT capped to [8:00 - 9:00>. * * @param $store resource The store in which the calendar resides * @param $calendar resource The calendar to get the items from * @param $viewstart int Timestamp of beginning of view window * @param $viewend int Timestamp of end of view window * @param $propsrequested array Array of properties to return * @param $rows array Array of rowdata as if they were returned directly from mapi_table_queryrows. Each recurring item is * expanded so that it seems that there are only many single appointments in the table. */ function getCalendarItems($store, $calendar, $viewstart, $viewend, $propsrequested) { $result = array(); $properties = getPropIdsFromStrings($store, array("duedate" => "PT_SYSTIME:PSETID_Appointment:0x820e", "startdate" => "PT_SYSTIME:PSETID_Appointment:0x820d", "enddate_recurring" => "PT_SYSTIME:PSETID_Appointment:0x8236", "recurring" => "PT_BOOLEAN:PSETID_Appointment:0x8223", "recurring_data" => "PT_BINARY:PSETID_Appointment:0x8216", "timezone_data" => "PT_BINARY:PSETID_Appointment:0x8233", "label" => "PT_LONG:PSETID_Appointment:0x8214")); // Create a restriction that will discard rows of appointments that are definitely not in our // requested time frame $table = mapi_folder_getcontentstable($calendar); $restriction = array(RES_OR, array(array(RES_AND, array(array(RES_PROPERTY, array(RELOP => RELOP_GT, ULPROPTAG => $properties["duedate"], VALUE => $viewstart)), array(RES_PROPERTY, array(RELOP => RELOP_LT, ULPROPTAG => $properties["startdate"], VALUE => $viewend)))), array(RES_PROPERTY, array(RELOP => RELOP_EQ, ULPROPTAG => $properties["recurring"], VALUE => true)))); // global OR // Get requested properties, plus whatever we need $proplist = array(PR_ENTRYID, $properties["recurring"], $properties["recurring_data"], $properties["timezone_data"]); $proplist = array_merge($proplist, $propsrequested); $propslist = array_unique($proplist); $rows = mapi_table_queryallrows($table, $proplist, $restriction); // $rows now contains all the items that MAY be in the window; a recurring item needs expansion before including in the output. foreach ($rows as $row) { $items = array(); if (isset($row[$properties["recurring"]]) && $row[$properties["recurring"]]) { // Recurring item $rec = new Recurrence($store, $row); // GetItems guarantees that the item overlaps the interval <$viewstart, $viewend> $occurrences = $rec->getItems($viewstart, $viewend); foreach ($occurrences as $occurrence) { // The occurrence takes all properties from the main row, but overrides some properties (like start and end obviously) $item = $occurrence + $row; array_push($items, $item); } } else { // Normal item, it matched the search criteria and therefore overlaps the interval <$viewstart, $viewend> array_push($items, $row); } $result = array_merge($result, $items); } // All items are guaranteed to overlap the interval <$viewstart, $viewend>. Note that we may be returning a few extra // properties that the caller did not request (recurring, etc). This shouldn't be a problem though. return $result; }
/** Deletes incoming task request from Inbox * * @returns array returns PR_ENTRYID, PR_STORE_ENTRYID and PR_PARENT_ENTRYID of the deleted task request */ function deleteReceivedTR() { $store = $this->getTaskFolderStore(); $inbox = mapi_msgstore_getreceivefolder($store); $storeProps = mapi_getprops($store, array(PR_IPM_WASTEBASKET_ENTRYID)); $props = mapi_getprops($this->message, array($this->props['taskglobalobjid'])); $globalobjid = $props[$this->props['taskglobalobjid']]; // Find the task by looking for the taskglobalobjid $restriction = array(RES_PROPERTY, array(RELOP => RELOP_EQ, ULPROPTAG => $this->props['taskglobalobjid'], VALUE => $globalobjid)); $contents = mapi_folder_getcontentstable($inbox); $rows = mapi_table_queryallrows($contents, array(PR_ENTRYID, PR_PARENT_ENTRYID, PR_STORE_ENTRYID), $restriction); $taskrequest = false; if (!empty($rows)) { // If there are multiple, just use the first $entryid = $rows[0][PR_ENTRYID]; $wastebasket = mapi_msgstore_openentry($store, $storeProps[PR_IPM_WASTEBASKET_ENTRYID]); mapi_folder_copymessages($inbox, array($entryid), $wastebasket, MESSAGE_MOVE); return array(PR_ENTRYID => $entryid, PR_PARENT_ENTRYID => $rows[0][PR_PARENT_ENTRYID], PR_STORE_ENTRYID => $rows[0][PR_STORE_ENTRYID]); } return false; }
function getSearchResults($searchquery, $searchrange) { // only return users from who the displayName or the username starts with $name //TODO: use PR_ANR for this restriction instead of PR_DISPLAY_NAME and PR_ACCOUNT $addrbook = mapi_openaddressbook($this->_session); $ab_entryid = mapi_ab_getdefaultdir($addrbook); $ab_dir = mapi_ab_openentry($addrbook, $ab_entryid); $table = mapi_folder_getcontentstable($ab_dir); $restriction = $this->_getSearchRestriction(u2w($searchquery)); mapi_table_restrict($table, $restriction); mapi_table_sort($table, array(PR_DISPLAY_NAME => TABLE_SORT_ASCEND)); //range for the search results, default symbian range end is 50, wm 99, //so we'll use that of nokia $rangestart = 0; $rangeend = 50; if ($searchrange != '0') { $pos = strpos($searchrange, '-'); $rangestart = substr($searchrange, 0, $pos); $rangeend = substr($searchrange, $pos + 1); } $items = array(); $querycnt = mapi_table_getrowcount($table); //do not return more results as requested in range $querylimit = $rangeend + 1 < $querycnt ? $rangeend + 1 : $querycnt; $items['range'] = $rangestart . '-' . ($querylimit - 1); $abentries = mapi_table_queryrows($table, array(PR_ACCOUNT, PR_DISPLAY_NAME, PR_SMTP_ADDRESS, PR_BUSINESS_TELEPHONE_NUMBER), $rangestart, $querylimit); for ($i = 0; $i < $querylimit; $i++) { $items[$i]["username"] = w2u($abentries[$i][PR_ACCOUNT]); $items[$i]["fullname"] = w2u($abentries[$i][PR_DISPLAY_NAME]); if (strlen(trim($items[$i]["fullname"])) == 0) { $items[$i]["fullname"] = $items[$i]["username"]; } $items[$i]["emailaddress"] = w2u($abentries[$i][PR_SMTP_ADDRESS]); $items[$i]["nameid"] = $searchquery; //check if an user has a business phone or it might produce warnings in the log $items[$i]["businessphone"] = isset($abentries[$i][PR_BUSINESS_TELEPHONE_NUMBER]) ? w2u($abentries[$i][PR_BUSINESS_TELEPHONE_NUMBER]) : ""; } return $items; }
function readResolveRecipientsfromContacts($emailaddress) { $storeprops = mapi_getprops($this->_defaultstore, array(PR_USER_ENTRYID)); $root = mapi_msgstore_openentry($this->_defaultstore); if (!$root) { return true; } $rootprops = mapi_getprops($root, array(PR_IPM_CONTACT_ENTRYID)); $contactfolder = mapi_msgstore_openentry($this->_defaultstore, $rootprops[PR_IPM_CONTACT_ENTRYID]); $contactstable = mapi_folder_getcontentstable($contactfolder); $email1address = GetPropIDFromString($this->_defaultstore, "PT_STRING8:{00062004-0000-0000-C000-000000000046}:0x8083"); $email2address = GetPropIDFromString($this->_defaultstore, "PT_STRING8:{00062004-0000-0000-C000-000000000046}:0x8093"); $email3address = GetPropIDFromString($this->_defaultstore, "PT_STRING8:{00062004-0000-0000-C000-000000000046}:0x80A3"); $internetfb = GetPropIDFromString($this->_defaultstore, "PT_STRING8:{00062004-0000-0000-C000-000000000046}:0x80D8"); $x509certs = mapi_prop_tag(PT_MV_BINARY, 0x3a70); $restriction = array(RES_OR, array(array(RES_PROPERTY, array(RELOP => RELOP_EQ, ULPROPTAG => $email1address, VALUE => array($email1address => $emailaddress))), array(RES_PROPERTY, array(RELOP => RELOP_EQ, ULPROPTAG => $email2address, VALUE => array($email2address => $emailaddress))), array(RES_PROPERTY, array(RELOP => RELOP_EQ, ULPROPTAG => $email3address, VALUE => array($email3address => $emailaddress))))); $rows = mapi_table_queryallrows($contactstable, array(PR_ENTRYID, PR_DISPLAY_NAME, $x509certs, $internetfb, $email1address, $email2address, $email3address), $restriction); return $rows; }
/** * Finds the chunk and returns a property array. * * @param ressoure $store * @param string $folderid * @param string $chunkName * * @access private * @return array */ private function findChunk($store, $folderid, $chunkName) { // search for the chunk message $folder = $this->getFolder($store, $folderid); $table = mapi_folder_getcontentstable($folder); if (!$table) { $this->Log(sprintf("Kopano->findChunk: Error, unable to read contents table to find chunk '%d': 0x%08X", $chunkId, mapi_last_hresult())); } $restriction = array(RES_PROPERTY, array(RELOP => RELOP_EQ, ULPROPTAG => PR_SUBJECT, VALUE => $chunkName)); mapi_table_restrict($table, $restriction); $entries = mapi_table_queryallrows($table, array(PR_ENTRYID, $this->mapiprops['chunkCRC'])); if (isset($entries[0])) { return $entries[0]; } return array(); }
function delete_duplicate_messages($store, $entryid) { global $total_deleted; $folder = mapi_msgstore_openentry($store, $entryid); if (!$folder) { print "Unable to open folder."; return false; } $table = mapi_folder_getcontentstable($folder); if (!$table) { print "Unable to open table."; return false; } $org_hash = null; $dup_messages = array(); $dup_count = 0; $result = mapi_table_sort($table, array(PR_SUBJECT => TABLE_SORT_ASCEND)); if ($result == false) { die("Could not sort table\n"); } while (1) { // query messages from folders content table $rows = mapi_table_queryrows($table, array(PR_MESSAGE_SIZE, PR_CLIENT_SUBMIT_TIME, PR_BODY, PR_HTML, PR_ENTRYID, PR_SUBJECT), 0, 50); if (count($rows) == 0) { break; } // we got the messages foreach ($rows as $row) { // hash message body (plaintext + html + subject) $md5_subject = md5($row[PR_SUBJECT]); $md5_body = md5($row[PR_BODY]); $md5_html = md5($row[PR_HTML]); // concat hashes, just in case there are messages with // no HTML or plaintext content. $cur_hash = $md5_body . $md5_html . $md5_subject; // when we have accumulated enough messages, perform a burst delete if ($dup_count == 50) { echo " [i] Deleting {$dup_count} duplicates..."; delete_messages($folder, $dup_messages); // reset the delete-queue $dup_messages = array(); $dup_count = 0; $total_deleted += 100; echo "done.\n"; echo "Deleted {$total_deleted} messages so far.\n\n"; } // duplicate messages are adjacent, so we push the first message with // a distinct hash and mark all following messages with this hash // for deletion. if ($org_hash != $cur_hash) { $org_hash = $cur_hash; } else { $dup_messages[] = $row[PR_ENTRYID]; $dup_count++; echo " [i] For {$org_hash} adding DUP {$md5_eid} to delete list\n"; } } } // final cleanup $dup_count = count($dup_messages); if ($dup_count) { $total_deleted += $dup_count; echo " [i] Finally deleting {$dup_count} duplicates. \n"; delete_messages($folder, $dup_messages); $dup_messages = array(); echo "Deleted {$total_deleted} messages so far.\n\n"; } }
/** * Searches for the emails on the server * * @param ContentParameter $cpo * * @return array */ public function GetMailboxSearchResults($cpo) { $searchFolder = $this->getSearchFolder(); $searchRestriction = $this->getSearchRestriction($cpo); $searchRange = explode('-', $cpo->GetSearchRange()); $searchFolderId = $cpo->GetSearchFolderid(); $searchFolders = array(); // search only in required folders if (!empty($searchFolderId)) { $searchFolderEntryId = mapi_msgstore_entryidfromsourcekey($this->store, hex2bin($searchFolderId)); $searchFolders[] = $searchFolderEntryId; } else { $tmp = mapi_getprops($this->store, array(PR_ENTRYID, PR_DISPLAY_NAME, PR_IPM_SUBTREE_ENTRYID)); $searchFolders[] = $tmp[PR_IPM_SUBTREE_ENTRYID]; } $items = array(); $flags = 0; // if subfolders are required, do a recursive search if ($cpo->GetSearchDeepTraversal()) { $flags |= SEARCH_RECURSIVE; } mapi_folder_setsearchcriteria($searchFolder, $searchRestriction, $searchFolders, $flags); $table = mapi_folder_getcontentstable($searchFolder); $searchStart = time(); // do the search and wait for all the results available while (time() - $searchStart < SEARCH_WAIT) { $searchcriteria = mapi_folder_getsearchcriteria($searchFolder); if (($searchcriteria["searchstate"] & SEARCH_REBUILD) == 0) { break; } // Search is done sleep(1); } // if the search range is set limit the result to it, otherwise return all found messages $rows = is_array($searchRange) && isset($searchRange[0]) && isset($searchRange[1]) ? mapi_table_queryrows($table, array(PR_SOURCE_KEY, PR_PARENT_SOURCE_KEY), $searchRange[0], $searchRange[1] - $searchRange[0] + 1) : mapi_table_queryrows($table, array(PR_SOURCE_KEY, PR_PARENT_SOURCE_KEY), 0, SEARCH_MAXRESULTS); $cnt = count($rows); $items['searchtotal'] = $cnt; $items["range"] = $cpo->GetSearchRange(); for ($i = 0; $i < $cnt; $i++) { $items[$i]['class'] = 'Email'; $items[$i]['longid'] = bin2hex($rows[$i][PR_PARENT_SOURCE_KEY]) . ":" . bin2hex($rows[$i][PR_SOURCE_KEY]); $items[$i]['folderid'] = bin2hex($rows[$i][PR_PARENT_SOURCE_KEY]); } return $items; }
// Either boolean or binary // Loop through returned rows for ($i = 0; $i < count($l_aTableRows); $i++) { // Check to see if this entry is the default store if (isset($l_aTableRows[$i][PR_DEFAULT_STORE]) && $l_aTableRows[$i][PR_DEFAULT_STORE] == true) { $storeEntryId = $l_aTableRows[$i][PR_ENTRYID]; break; } } // check if default root store's entry id found if ($storeEntryId) { $store = mapi_openmsgstore($l_rSession, $storeEntryId); $root = mapi_msgstore_openentry($store, null); $spamStoreProps = mapi_getprops($root, array(PR_ADDITIONAL_REN_ENTRYIDS)); $spamFolder = mapi_msgstore_openentry($store, $spamStoreProps[PR_ADDITIONAL_REN_ENTRYIDS][4]); $table = mapi_folder_getcontentstable($spamFolder); $spamRows = mapi_table_queryallrows($table, array(PR_ENTRYID, PR_CREATION_TIME)); echo (mapi_last_hresult() == 0 ? "Fetching messages from Junk Folder..." : "Some error in fetching...") . "\n"; if (count($spamRows) > 0) { $spamEntryIds = array(); echo "\nTotal messages in Junk folder found are : " . count($spamRows) . "\n"; for ($i = 0; $i < count($spamRows); $i++) { if (greaterDate(date("Y-m-d G:i:s", $spamRows[$i][PR_CREATION_TIME]), $daysBeforeDeleted)) { array_push($spamEntryIds, $spamRows[$i][PR_ENTRYID]); } } if (count($spamEntryIds) > 0) { echo "\nDeleting all " . count($spamEntryIds) . " message(s)...\n"; mapi_folder_deletemessages($spamFolder, $spamEntryIds); echo "" . (mapi_last_hresult() == 0 ? "\nHooray! there is no spam." : "Some error in deleting... There are still some spam messages.") . "\n"; } else {
/** * Returns contacts matching given email address from a folder. * * @param MAPIStore $store * @param binary $folderEntryid * @param string $email * * @return array|boolean */ private function getContactsFromFolder($store, $folderEntryid, $email) { $folder = mapi_msgstore_openentry($store, $folderEntryid); $folderContent = mapi_folder_getcontentstable($folder); mapi_table_restrict($folderContent, MAPIUtils::GetEmailAddressRestriction($store, $email)); // TODO max limit if (mapi_table_getrowcount($folderContent) > 0) { return mapi_table_queryallrows($folderContent, array(PR_DISPLAY_NAME, PR_USER_X509_CERTIFICATE)); } return false; }
/** * Build user list of adress books * Recursively find folders in Zarafa */ private function buildAdressBooks($store, $prefix, $folder, $parentFolderId) { $this->logger->trace("buildAdressBooks"); $folderProperties = mapi_getprops($folder); $currentFolderName = $this->to_charset($folderProperties[PR_DISPLAY_NAME]); // Compute CTag - issue 8: ctag should be the max of PR_LAST_MODIFICATION_TIME of contacts // of the folder. $this->logger->trace("Computing CTag for address book " . $folderProperties[PR_DISPLAY_NAME]); $ctag = $folderProperties[PR_LAST_MODIFICATION_TIME]; $contactsTable = mapi_folder_getcontentstable($folder); $contacts = mapi_table_queryallrows($contactsTable, array(PR_LAST_MODIFICATION_TIME)); // Contact count $contactCount = mapi_table_getrowcount($contactsTable); $storedContactCount = isset($folderProperties[PR_CARDDAV_AB_CONTACT_COUNT]) ? $folderProperties[PR_CARDDAV_AB_CONTACT_COUNT] : 0; $this->logger->trace("Contact count: {$contactCount}"); $this->logger->trace("Stored contact count: {$storedContactCount}"); if ($contactCount != $storedContactCount) { $this->logger->trace("Contact count != stored contact count"); $ctag = time(); mapi_setprops($folder, array(PR_CARDDAV_AB_CONTACT_COUNT => $contactCount, PR_LAST_MODIFICATION_TIME => $ctag)); mapi_savechanges($folder); } else { foreach ($contacts as $c) { if ($c[PR_LAST_MODIFICATION_TIME] > $ctag) { $ctag = $c[PR_LAST_MODIFICATION_TIME]; $this->logger->trace("Found new ctag: {$ctag}"); } } } // Add address book $displayPrefix = ""; if ($store === $this->pubStore) { $displayPrefix = "Public "; } $this->adressBooks[$folderProperties[PR_ENTRYID]] = array('id' => $folderProperties[PR_ENTRYID], 'displayname' => $displayPrefix . $folderProperties[PR_DISPLAY_NAME], 'prefix' => $prefix, 'description' => isset($folderProperties[805568542]) ? $folderProperties[805568542] : '', 'ctag' => $ctag, 'parentId' => $parentFolderId); // Get subfolders $foldersTable = mapi_folder_gethierarchytable($folder); $folders = mapi_table_queryallrows($foldersTable); foreach ($folders as $f) { $subFold = mapi_msgstore_openentry($store, $f[PR_ENTRYID]); $this->buildAdressBooks($store, $prefix . $currentFolderName . "/", $subFold, $folderProperties[PR_ENTRYID]); } }
/** * open_zarafa * * @param descriptor An open Zarafa session id. * @return array Array with session and store information. */ function open_zarafa($session) { $ret = array("root" => "/"); $storesTable = mapi_getmsgstorestable($session); $stores = mapi_table_queryallrows($storesTable, array(PR_ENTRYID, PR_MDB_PROVIDER)); for ($i = 0; $i < count($stores); $i++) { if ($stores[$i][PR_MDB_PROVIDER] == ZARAFA_SERVICE_GUID) { $storeEntryid = $stores[$i][PR_ENTRYID]; break; } } if (!isset($storeEntryid)) { trigger_error("Default store not found", PR_USER_ERROR); } $store = mapi_openmsgstore($session, $storeEntryid); $root = mapi_msgstore_openentry($store, null); $rootProps = mapi_getprops($root, array(PR_IPM_CONTACT_ENTRYID)); $folder = mapi_msgstore_openentry($store, $rootProps[PR_IPM_CONTACT_ENTRYID]); $table = mapi_folder_getcontentstable($folder); $contacts = mapi_table_queryallrows($table); $ret["session"] = $session; $ret["store"] = $store; $ret["contacts"] = $contacts; // ZCP 7 and up know unicode... $supportmask = mapi_getprops($store, array(PR_STORE_SUPPORT_MASK)); if (isset($supportmask[PR_STORE_SUPPORT_MASK]) && $supportmask[PR_STORE_SUPPORT_MASK] & STORE_UNICODE_OK) { $ret["unicode_store"] = true; setlocale(LC_CTYPE, 'en_US.utf-8'); } // END ZCP7 and up know unicode return $ret; }
function export($store, $csv_file) { $folder = getContactsFolder($store); // open the csv file and start reading $fh = fopen($csv_file, "w"); if (!$fh) { trigger_error("Can't write CSV file \"" . $csv_file . "\".", E_USER_ERROR); } $properties = getProperties(); $properties = replaceStringPropertyTags($store, $properties); $table = mapi_folder_getcontentstable($folder); $list = mapi_table_queryallrows($table, $properties); $special_properties = array(); // currently no special values, thus empty array. $csv_mapping = getMapping(); $csv_mapping = convertToGaplessMapping($csv_mapping); fputcsv($fh, array_keys($csv_mapping), CSV_DELIMITER, CSV_ENCLOSURE); foreach ($list as $item) { printf("Contact read: \"%s\".\n", $item[$properties["display_name"]]); $attributeValues = array(); foreach ($csv_mapping as $property => $cnt) { $attributeValue = "?????"; if (substr($property, 0, 3) == "N/A") { $attributeValue = ""; } else { if (!in_array($property, $special_properties)) { $attributeValue = array_key_exists($properties[$property], $item) ? $item[$properties[$property]] : ""; if (is_array($attributeValue)) { $attributeValue = implode(";", $attributeValue); } } else { $attributeValue = "Special value."; } } $attributeValues[] = $attributeValue; } fputcsv($fh, $attributeValues, CSV_DELIMITER, CSV_ENCLOSURE); } fclose($fh); }
/** * Translate ($addressBookId, $cardUri) to entry id * @param $addressBookId address book to search contact in * @param $cardUri name of contact card to retrieve */ protected function getContactEntryId($addressBookId, $cardUri) { // Update object properties $this->logger->trace("getContactEntryId({$cardUri})"); $folder = mapi_msgstore_openentry($this->bridge->getStore($addressBookId), $addressBookId); $contactsTable = mapi_folder_getcontentstable($folder); $contacts = mapi_table_queryallrows($contactsTable, array(PR_ENTRYID, PR_CARDDAV_URI, PR_SUBJECT)); $entryId = 0; foreach ($contacts as $c) { if (isset($c[PR_CARDDAV_URI])) { if ($c[PR_CARDDAV_URI] == $cardUri) { $entryId = $c[PR_ENTRYID]; break; } } else { // CardURI can be PR_ENTRYID .vcf if ($this->bridge->entryIdToStr($c[PR_ENTRYID]) == substr($cardUri, 0, -4)) { $entryId = $c[PR_ENTRYID]; break; } } } return $entryId; }
function getgabfolder() { $this->gabtable = mapi_folder_getcontentstable($this->globaladdressbook); if (!$this->gabtable) { print "Unable to get GAB table\n"; exit(1); } }
function getSearchResults($searchquery, $searchrange) { // only return users from who the displayName or the username starts with $name //TODO: use PR_ANR for this restriction instead of PR_DISPLAY_NAME and PR_ACCOUNT $addrbook = mapi_openaddressbook($this->_session); $ab_entryid = mapi_ab_getdefaultdir($addrbook); $ab_dir = mapi_ab_openentry($addrbook, $ab_entryid); $table = mapi_folder_getcontentstable($ab_dir); $restriction = $this->_getSearchRestriction(u2w($searchquery)); mapi_table_restrict($table, $restriction); mapi_table_sort($table, array(PR_DISPLAY_NAME => TABLE_SORT_ASCEND)); //range for the search results, default symbian range end is 50, wm 99, //so we'll use that of nokia $rangestart = 0; $rangeend = 50; if ($searchrange != '0') { $pos = strpos($searchrange, '-'); $rangestart = substr($searchrange, 0, $pos); $rangeend = substr($searchrange, $pos + 1); } $items = array(); $querycnt = mapi_table_getrowcount($table); //do not return more results as requested in range $querylimit = $rangeend + 1 < $querycnt ? $rangeend + 1 : $querycnt; $items['range'] = $rangestart . '-' . ($querylimit - 1); $items['searchtotal'] = $querycnt; if ($querycnt > 0) { $abentries = mapi_table_queryrows($table, array(PR_ACCOUNT, PR_DISPLAY_NAME, PR_SMTP_ADDRESS, PR_BUSINESS_TELEPHONE_NUMBER, PR_GIVEN_NAME, PR_SURNAME, PR_MOBILE_TELEPHONE_NUMBER, PR_HOME_TELEPHONE_NUMBER, PR_TITLE, PR_COMPANY_NAME, PR_OFFICE_LOCATION), $rangestart, $querylimit); } for ($i = 0; $i < $querylimit; $i++) { $items[$i][SYNC_GAL_DISPLAYNAME] = w2u($abentries[$i][PR_DISPLAY_NAME]); if (strlen(trim($items[$i][SYNC_GAL_DISPLAYNAME])) == 0) { $items[$i][SYNC_GAL_DISPLAYNAME] = w2u($abentries[$i][PR_ACCOUNT]); } $items[$i][SYNC_GAL_ALIAS] = w2u($abentries[$i][PR_ACCOUNT]); //it's not possible not get first and last name of an user //from the gab and user functions, so we just set lastname //to displayname and leave firstname unset //this was changed in Zarafa 6.40, so we try to get first and //last name and fall back to the old behaviour if these values are not set if (isset($abentries[$i][PR_GIVEN_NAME])) { $items[$i][SYNC_GAL_FIRSTNAME] = w2u($abentries[$i][PR_GIVEN_NAME]); } if (isset($abentries[$i][PR_SURNAME])) { $items[$i][SYNC_GAL_LASTNAME] = w2u($abentries[$i][PR_SURNAME]); } if (!isset($items[$i][SYNC_GAL_LASTNAME])) { $items[$i][SYNC_GAL_LASTNAME] = $items[$i][SYNC_GAL_DISPLAYNAME]; } $items[$i][SYNC_GAL_EMAILADDRESS] = w2u($abentries[$i][PR_SMTP_ADDRESS]); //check if an user has an office number or it might produce warnings in the log if (isset($abentries[$i][PR_BUSINESS_TELEPHONE_NUMBER])) { $items[$i][SYNC_GAL_PHONE] = w2u($abentries[$i][PR_BUSINESS_TELEPHONE_NUMBER]); } //check if an user has a mobile number or it might produce warnings in the log if (isset($abentries[$i][PR_MOBILE_TELEPHONE_NUMBER])) { $items[$i][SYNC_GAL_MOBILEPHONE] = w2u($abentries[$i][PR_MOBILE_TELEPHONE_NUMBER]); } //check if an user has a home number or it might produce warnings in the log if (isset($abentries[$i][PR_HOME_TELEPHONE_NUMBER])) { $items[$i][SYNC_GAL_HOMEPHONE] = w2u($abentries[$i][PR_HOME_TELEPHONE_NUMBER]); } if (isset($abentries[$i][PR_COMPANY_NAME])) { $items[$i][SYNC_GAL_COMPANY] = w2u($abentries[$i][PR_COMPANY_NAME]); } if (isset($abentries[$i][PR_TITLE])) { $items[$i][SYNC_GAL_TITLE] = w2u($abentries[$i][PR_TITLE]); } if (isset($abentries[$i][PR_OFFICE_LOCATION])) { $items[$i][SYNC_GAL_OFFICE] = w2u($abentries[$i][PR_OFFICE_LOCATION]); } } return $items; }
$l_bbnEntryID = $l_aTableRows[$i][PR_ENTRYID]; break; } } // check if default root store's entry id found if ($l_bbnEntryID) { // Open msg store by using the entryID $l_rDefaultStore = mapi_openmsgstore($l_rSession, $l_bbnEntryID); echo 'Opening default store result (0=success): ' . mapi_last_hresult() . "\n"; // Get inbox $l_rInbox = mapi_msgstore_getreceivefolder($l_rDefaultStore); echo 'Getting entryID of inbox folder result (0=success): ' . mapi_last_hresult() . "\n"; // Check if folder has been opened if ($l_rInbox) { // Open contents table $l_rInboxTable = mapi_folder_getcontentstable($l_rInbox); echo 'Opening contents table result (0=success): ' . mapi_last_hresult() . "\n"; // Find the item by restricting all items to the correct ID $restrict = array(RES_AND, array(array(RES_PROPERTY, array(RELOP => RELOP_NE, ULPROPTAG => PR_PROCESSED, VALUE => array(PR_PROCESSED => true))), array(RES_CONTENT, array(FUZZYLEVEL => FL_PREFIX, ULPROPTAG => PR_MESSAGE_CLASS, VALUE => array(PR_SUBJECT => 'IPM.Schedule.Meeting'))), array(RES_BITMASK, array(ULTYPE => BMR_EQZ, ULMASK => MSGFLAG_READ, ULPROPTAG => PR_MESSAGE_FLAGS)))); // Just get all items from table $l_aRows = mapi_table_queryallrows($l_rInboxTable, array(PR_ENTRYID, PR_MESSAGE_CLASS, PR_SUBJECT, PR_PROCESSED), $restrict); echo 'Querying contents table result (0=success): ' . mapi_last_hresult() . "\n"; //print_r(count($l_aRows)); //exit; echo 'Processing messages' . "\n"; $l_iCounter = 0; for ($i = 0; $i < count($l_aRows); $i++) { $l_sMsgClassSearch = 'IPM.Schedule.Meeting'; $l_rMessage = mapi_msgstore_openentry($l_rDefaultStore, $l_aRows[$i][PR_ENTRYID]); $req = new Meetingrequest($l_rDefaultStore, $l_rMessage, $l_rSession); if ($req->isMeetingRequest() && !$req->isLocalOrganiser()) {
/** * Get all public contact folders */ function getPublicContactFolders($session, $publicstore) { $pub_folder = mapi_msgstore_openentry($publicstore); $h_table = mapi_folder_gethierarchytable($pub_folder, CONVENIENT_DEPTH); $contact_properties = getContactProperties($publicstore); $subfolders = mapi_table_queryallrows($h_table, array(PR_ENTRYID, PR_DISPLAY_NAME, PR_DISPLAY_TYPE, PR_CONTAINER_CLASS, PR_SUBFOLDERS)); $pub_list2 = array(); $contacts = array(); foreach ($subfolders as $folder) { // check if folder contains PR_CONTAINER_CLASS and if its a contact if (isset($folder[907214878]) && $folder[907214878] == "IPF.Contact" && $folder[805371934] != "Kontakte") { $entryid = $folder[268370178]; $pub_folder2 = mapi_msgstore_openentry($publicstore, $entryid); $pub_table2 = mapi_folder_getcontentstable($pub_folder2); $pub_list2 = mapi_table_queryallrows($pub_table2, $contact_properties); for ($j = 0; $j < sizeof($pub_list2); $j++) { $pub_list2[$j][268370178] = md5($pub_list2[$j][268370178]); } for ($k = 0; $k < sizeof($pub_list2); $k++) { foreach ($pub_list2[$k] as $key => $value) { $attribute = mapKey($key); if ($attribute != "") { $contacts[$k][$attribute] = $value; } } } //$contactFolders[$folder[805371934]] = $pub_list2; $contactFolders[] = array("foldername" => $folder[805371934], "contacts" => $contacts); } } //print_r($contactFolders); return $contactFolders; }
$l_bbnEntryID = false; // Either boolean or binary // Loop through returned rows for ($i = 0; $i < count($l_aTableRows); $i++) { // Check to see if this entry is the default store if (isset($l_aTableRows[$i][PR_DEFAULT_STORE]) && $l_aTableRows[$i][PR_DEFAULT_STORE] == true) { $storeEntryId = $l_aTableRows[$i][PR_ENTRYID]; break; } } // check if default root store's entry id found if ($storeEntryId) { $store = mapi_openmsgstore($l_rSession, $storeEntryId); $delStoreProps = mapi_getprops($store, array(PR_IPM_WASTEBASKET_ENTRYID)); $deletedFolder = mapi_msgstore_openentry($store, $delStoreProps[PR_IPM_WASTEBASKET_ENTRYID]); $table = mapi_folder_getcontentstable($deletedFolder); $delRows = mapi_table_queryallrows($table, array(PR_ENTRYID, PR_CREATION_TIME)); echo (mapi_last_hresult() == 0 ? "Fetching messages from Deleted Folder..." : "Some error in fetching...") . "\n"; if (count($delRows) > 0) { $delEntryIds = array(); echo 'Total messages in deleted folder found are : ' . count($delRows) . "\n"; for ($i = 0; $i < count($delRows); $i++) { if (greaterDate(date("Y-m-d G:i:s", $delRows[$i][PR_CREATION_TIME]), $daysBeforeDeleted)) { array_push($delEntryIds, $delRows[$i][PR_ENTRYID]); } } if (count($delEntryIds) > 0) { echo "\nDeleting all " . count($delEntryIds) . " messages...\n"; mapi_folder_deletemessages($deletedFolder, $delEntryIds); echo "" . (mapi_last_hresult() == 0 ? "Successfully deleted all messages" : "Some error in deleting... please try again later") . "\n"; } else {
/** * Function which finds items in calendar based on specified parameters. *@param binary $goid GlobalID(0x3) of item *@param resource $calendar MAPI_folder of user *@param boolean $use_cleanGlobalID if true then search should be performed on cleanGlobalID(0x23) else globalID(0x3) */ function findCalendarItems($goid, $calendar = false, $use_cleanGlobalID = false) { if (!$calendar) { // Open the Calendar $calendar = $this->openDefaultCalendar(); } // Find the item by restricting all items to the correct ID $restrict = array(RES_AND, array()); array_push($restrict[1], array(RES_PROPERTY, array(RELOP => RELOP_EQ, ULPROPTAG => $use_cleanGlobalID ? $this->proptags['goid2'] : $this->proptags['goid'], VALUE => $goid))); $calendarcontents = mapi_folder_getcontentstable($calendar); $rows = mapi_table_queryallrows($calendarcontents, array(PR_ENTRYID), $restrict); if (empty($rows)) { return; } $calendaritems = array(); // In principle, there should only be one row, but we'll handle them all just in case foreach ($rows as $row) { $calendaritems[] = $row[PR_ENTRYID]; } return $calendaritems; }
function getSearchResultsGAL($searchquery) { // only return users from who the displayName or the username starts with $name //TODO: use PR_ANR for this restriction instead of PR_DISPLAY_NAME and PR_ACCOUNT $addrbook = mapi_openaddressbook($this->_session); $ab_entryid = mapi_ab_getdefaultdir($addrbook); $ab_dir = mapi_ab_openentry($addrbook, $ab_entryid); $table = mapi_folder_getcontentstable($ab_dir); $restriction = $this->_getSearchRestriction(u2w($searchquery)); mapi_table_restrict($table, $restriction); mapi_table_sort($table, array(PR_DISPLAY_NAME => TABLE_SORT_ASCEND)); // CHANGED dw2412 AS V12.0 Support (to menetain single return way... $items['rows'] = array(); for ($i = 0; $i < mapi_table_getrowcount($table); $i++) { $user_data = mapi_table_queryrows($table, array(PR_ACCOUNT, PR_DISPLAY_NAME, PR_SMTP_ADDRESS, PR_BUSINESS_TELEPHONE_NUMBER), $i, 1); $item = array(); $item["username"] = w2u($user_data[0][PR_ACCOUNT]); $item["fullname"] = w2u($user_data[0][PR_DISPLAY_NAME]); if (strlen(trim($item["fullname"])) == 0) { $item["fullname"] = $item["username"]; } $item["emailaddress"] = w2u($user_data[0][PR_SMTP_ADDRESS]); $item["nameid"] = $searchquery; $item["businessphone"] = isset($user_data[0][PR_BUSINESS_TELEPHONE_NUMBER]) ? w2u($user_data[0][PR_BUSINESS_TELEPHONE_NUMBER]) : ""; //do not return users without email if (strlen(trim($item["emailaddress"])) == 0) { continue; } // CHANGED dw2412 AS V12.0 Support (to menetain single return way... array_push($items['rows'], $item); } $items['status'] = 1; return $items; }