/** * Handles the Search command * * @param int $commandCode * * @access public * @return boolean */ public function Handle($commandCode) { $searchrange = '0'; $cpo = new ContentParameters(); if (!self::$decoder->getElementStartTag(SYNC_SEARCH_SEARCH)) { return false; } // TODO check: possible to search in other stores? if (!self::$decoder->getElementStartTag(SYNC_SEARCH_STORE)) { return false; } if (!self::$decoder->getElementStartTag(SYNC_SEARCH_NAME)) { return false; } $searchname = strtoupper(self::$decoder->getElementContent()); if (!self::$decoder->getElementEndTag()) { return false; } if (!self::$decoder->getElementStartTag(SYNC_SEARCH_QUERY)) { return false; } // check if it is a content of an element (= GAL search) // or a starttag (= mailbox or documentlibrary search) $searchquery = self::$decoder->getElementContent(); if ($searchquery && !self::$decoder->getElementEndTag()) { return false; } if ($searchquery === false) { $cpo->SetSearchName($searchname); if (self::$decoder->getElementStartTag(SYNC_SEARCH_AND)) { if (self::$decoder->getElementStartTag(SYNC_FOLDERID)) { $searchfolderid = self::$decoder->getElementContent(); $cpo->SetSearchFolderid($searchfolderid); if (!self::$decoder->getElementEndTag()) { // SYNC_FOLDERTYPE return false; } } if (self::$decoder->getElementStartTag(SYNC_FOLDERTYPE)) { $searchclass = self::$decoder->getElementContent(); $cpo->SetSearchClass($searchclass); if (!self::$decoder->getElementEndTag()) { // SYNC_FOLDERTYPE return false; } } if (self::$decoder->getElementStartTag(SYNC_FOLDERID)) { $searchfolderid = self::$decoder->getElementContent(); $cpo->SetSearchFolderid($searchfolderid); if (!self::$decoder->getElementEndTag()) { // SYNC_FOLDERTYPE return false; } } if (self::$decoder->getElementStartTag(SYNC_SEARCH_FREETEXT)) { $searchfreetext = self::$decoder->getElementContent(); $cpo->SetSearchFreeText($searchfreetext); if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_FREETEXT return false; } } //TODO - review if (self::$decoder->getElementStartTag(SYNC_SEARCH_GREATERTHAN)) { if (self::$decoder->getElementStartTag(SYNC_POOMMAIL_DATERECEIVED)) { $datereceivedgreater = true; if (($dam = self::$decoder->getElementContent()) !== false) { $datereceivedgreater = true; if (!self::$decoder->getElementEndTag()) { return false; } } $cpo->SetSearchDateReceivedGreater($datereceivedgreater); } if (self::$decoder->getElementStartTag(SYNC_SEARCH_VALUE)) { $searchvalue = self::$decoder->getElementContent(); $cpo->SetSearchValueGreater($searchvalue); if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_VALUE return false; } } if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_GREATERTHAN return false; } } if (self::$decoder->getElementStartTag(SYNC_SEARCH_LESSTHAN)) { if (self::$decoder->getElementStartTag(SYNC_POOMMAIL_DATERECEIVED)) { $datereceivedless = true; if (($dam = self::$decoder->getElementContent()) !== false) { $datereceivedless = true; if (!self::$decoder->getElementEndTag()) { return false; } } $cpo->SetSearchDateReceivedLess($datereceivedless); } if (self::$decoder->getElementStartTag(SYNC_SEARCH_VALUE)) { $searchvalue = self::$decoder->getElementContent(); $cpo->SetSearchValueLess($searchvalue); if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_VALUE return false; } } if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_LESSTHAN return false; } } if (self::$decoder->getElementStartTag(SYNC_SEARCH_FREETEXT)) { $searchfreetext = self::$decoder->getElementContent(); $cpo->SetSearchFreeText($searchfreetext); if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_FREETEXT return false; } } if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_AND return false; } } elseif (self::$decoder->getElementStartTag(SYNC_SEARCH_EQUALTO)) { // linkid can be an empty tag as well as have value if (self::$decoder->getElementStartTag(SYNC_DOCUMENTLIBRARY_LINKID)) { if (($linkId = self::$decoder->getElementContent()) !== false) { $cpo->SetLinkId($linkId); if (!self::$decoder->getElementEndTag()) { // SYNC_DOCUMENTLIBRARY_LINKID return false; } } } if (self::$decoder->getElementStartTag(SYNC_SEARCH_VALUE)) { $searchvalue = self::$decoder->getElementContent(); $cpo->SetSearchValueLess($searchvalue); if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_VALUE return false; } } if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_EQUALTO return false; } } if (!self::$decoder->getElementEndTag()) { // SYNC_SEARCH_QUERY return false; } } if (self::$decoder->getElementStartTag(SYNC_SEARCH_OPTIONS)) { while (1) { if (self::$decoder->getElementStartTag(SYNC_SEARCH_RANGE)) { $searchrange = self::$decoder->getElementContent(); $cpo->SetSearchRange($searchrange); if (!self::$decoder->getElementEndTag()) { return false; } } if (self::$decoder->getElementStartTag(SYNC_SEARCH_REBUILDRESULTS)) { $rebuildresults = true; if (($dam = self::$decoder->getElementContent()) !== false) { $rebuildresults = true; if (!self::$decoder->getElementEndTag()) { return false; } } $cpo->SetSearchRebuildResults($rebuildresults); } if (self::$decoder->getElementStartTag(SYNC_SEARCH_DEEPTRAVERSAL)) { $deeptraversal = true; if (($dam = self::$decoder->getElementContent()) !== false) { $deeptraversal = true; if (!self::$decoder->getElementEndTag()) { return false; } } $cpo->SetSearchDeepTraversal($deeptraversal); } if (self::$decoder->getElementStartTag(SYNC_MIMESUPPORT)) { $cpo->SetMimeSupport(self::$decoder->getElementContent()); if (!self::$decoder->getElementEndTag()) { return false; } } //TODO body preferences while (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_BODYPREFERENCE)) { if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TYPE)) { $bptype = self::$decoder->getElementContent(); $cpo->BodyPreference($bptype); if (!self::$decoder->getElementEndTag()) { return false; } } if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TRUNCATIONSIZE)) { $cpo->BodyPreference($bptype)->SetTruncationSize(self::$decoder->getElementContent()); if (!self::$decoder->getElementEndTag()) { return false; } } if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_ALLORNONE)) { $cpo->BodyPreference($bptype)->SetAllOrNone(self::$decoder->getElementContent()); if (!self::$decoder->getElementEndTag()) { return false; } } if (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_PREVIEW)) { $cpo->BodyPreference($bptype)->SetPreview(self::$decoder->getElementContent()); if (!self::$decoder->getElementEndTag()) { return false; } } if (!self::$decoder->getElementEndTag()) { return false; } } $e = self::$decoder->peek(); if ($e[EN_TYPE] == EN_TYPE_ENDTAG) { self::$decoder->getElementEndTag(); break; } } } if (!self::$decoder->getElementEndTag()) { //store return false; } if (!self::$decoder->getElementEndTag()) { //search return false; } // get SearchProvider $searchprovider = ZPush::GetSearchProvider(); $status = SYNC_SEARCHSTATUS_SUCCESS; $rows = array(); // TODO support other searches if ($searchprovider->SupportsType($searchname)) { $storestatus = SYNC_SEARCHSTATUS_STORE_SUCCESS; try { if ($searchname == ISearchProvider::SEARCH_GAL) { //get search results from the searchprovider $rows = $searchprovider->GetGALSearchResults($searchquery, $searchrange); } elseif ($searchname == ISearchProvider::SEARCH_MAILBOX) { $rows = $searchprovider->GetMailboxSearchResults($cpo); } } catch (StatusException $stex) { $storestatus = $stex->getCode(); } } else { $rows = array('searchtotal' => 0); $status = SYNC_SEARCHSTATUS_SERVERERROR; ZLog::Write(LOGLEVEL_WARN, sprintf("Searchtype '%s' is not supported.", $searchname)); self::$topCollector->AnnounceInformation(sprintf("Unsupported type '%s''", $searchname), true); } $searchprovider->Disconnect(); self::$topCollector->AnnounceInformation(sprintf("'%s' search found %d results", $searchname, $rows['searchtotal']), true); self::$encoder->startWBXML(); self::$encoder->startTag(SYNC_SEARCH_SEARCH); self::$encoder->startTag(SYNC_SEARCH_STATUS); self::$encoder->content($status); self::$encoder->endTag(); if ($status == SYNC_SEARCHSTATUS_SUCCESS) { self::$encoder->startTag(SYNC_SEARCH_RESPONSE); self::$encoder->startTag(SYNC_SEARCH_STORE); self::$encoder->startTag(SYNC_SEARCH_STATUS); self::$encoder->content($storestatus); self::$encoder->endTag(); if (isset($rows['range'])) { $searchrange = $rows['range']; unset($rows['range']); } if (isset($rows['searchtotal'])) { $searchtotal = $rows['searchtotal']; unset($rows['searchtotal']); } if ($searchname == ISearchProvider::SEARCH_GAL) { if (is_array($rows) && !empty($rows)) { foreach ($rows as $u) { self::$encoder->startTag(SYNC_SEARCH_RESULT); self::$encoder->startTag(SYNC_SEARCH_PROPERTIES); self::$encoder->startTag(SYNC_GAL_DISPLAYNAME); self::$encoder->content(isset($u[SYNC_GAL_DISPLAYNAME]) ? $u[SYNC_GAL_DISPLAYNAME] : "No name"); self::$encoder->endTag(); if (isset($u[SYNC_GAL_PHONE])) { self::$encoder->startTag(SYNC_GAL_PHONE); self::$encoder->content($u[SYNC_GAL_PHONE]); self::$encoder->endTag(); } if (isset($u[SYNC_GAL_OFFICE])) { self::$encoder->startTag(SYNC_GAL_OFFICE); self::$encoder->content($u[SYNC_GAL_OFFICE]); self::$encoder->endTag(); } if (isset($u[SYNC_GAL_TITLE])) { self::$encoder->startTag(SYNC_GAL_TITLE); self::$encoder->content($u[SYNC_GAL_TITLE]); self::$encoder->endTag(); } if (isset($u[SYNC_GAL_COMPANY])) { self::$encoder->startTag(SYNC_GAL_COMPANY); self::$encoder->content($u[SYNC_GAL_COMPANY]); self::$encoder->endTag(); } if (isset($u[SYNC_GAL_ALIAS])) { self::$encoder->startTag(SYNC_GAL_ALIAS); self::$encoder->content($u[SYNC_GAL_ALIAS]); self::$encoder->endTag(); } // Always send the firstname, even empty. Nokia needs this to display the entry self::$encoder->startTag(SYNC_GAL_FIRSTNAME); self::$encoder->content(isset($u[SYNC_GAL_FIRSTNAME]) ? $u[SYNC_GAL_FIRSTNAME] : ""); self::$encoder->endTag(); self::$encoder->startTag(SYNC_GAL_LASTNAME); self::$encoder->content(isset($u[SYNC_GAL_LASTNAME]) ? $u[SYNC_GAL_LASTNAME] : "No name"); self::$encoder->endTag(); if (isset($u[SYNC_GAL_HOMEPHONE])) { self::$encoder->startTag(SYNC_GAL_HOMEPHONE); self::$encoder->content($u[SYNC_GAL_HOMEPHONE]); self::$encoder->endTag(); } if (isset($u[SYNC_GAL_MOBILEPHONE])) { self::$encoder->startTag(SYNC_GAL_MOBILEPHONE); self::$encoder->content($u[SYNC_GAL_MOBILEPHONE]); self::$encoder->endTag(); } self::$encoder->startTag(SYNC_GAL_EMAILADDRESS); self::$encoder->content(isset($u[SYNC_GAL_EMAILADDRESS]) ? $u[SYNC_GAL_EMAILADDRESS] : ""); self::$encoder->endTag(); self::$encoder->endTag(); //result self::$encoder->endTag(); //properties } } } elseif ($searchname == ISearchProvider::SEARCH_MAILBOX) { foreach ($rows as $u) { self::$encoder->startTag(SYNC_SEARCH_RESULT); self::$encoder->startTag(SYNC_FOLDERTYPE); self::$encoder->content($u['class']); self::$encoder->endTag(); self::$encoder->startTag(SYNC_SEARCH_LONGID); self::$encoder->content($u['longid']); self::$encoder->endTag(); self::$encoder->startTag(SYNC_FOLDERID); self::$encoder->content($u['folderid']); self::$encoder->endTag(); self::$encoder->startTag(SYNC_SEARCH_PROPERTIES); $tmp = explode(":", $u['longid']); $message = self::$backend->Fetch($u['folderid'], $tmp[1], $cpo); $message->Encode(self::$encoder); self::$encoder->endTag(); //result self::$encoder->endTag(); //properties } } // it seems that android 4 requires range and searchtotal // or it won't display the search results if (isset($searchrange)) { self::$encoder->startTag(SYNC_SEARCH_RANGE); self::$encoder->content($searchrange); self::$encoder->endTag(); } if (isset($searchtotal) && $searchtotal > 0) { self::$encoder->startTag(SYNC_SEARCH_TOTAL); self::$encoder->content($searchtotal); self::$encoder->endTag(); } self::$encoder->endTag(); //store self::$encoder->endTag(); //response } self::$encoder->endTag(); //search return true; }