1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/z-push_ynh.git synced 2024-09-03 18:05:58 +02:00
z-push_ynh/sources/lib/request/search.php
2014-12-18 18:08:26 +01:00

448 lines
No EOL
21 KiB
PHP

<?php
/***********************************************
* File : search.php
* Project : Z-Push
* Descr : Provides the SEARCH command
*
* Created : 16.02.2012
*
* Copyright 2007 - 2013 Zarafa Deutschland GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation with the following additional
* term according to sec. 7:
*
* According to sec. 7 of the GNU Affero General Public License, version 3,
* the terms of the AGPL are supplemented with the following terms:
*
* "Zarafa" is a registered trademark of Zarafa B.V.
* "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
* The licensing of the Program under the AGPL does not imply a trademark license.
* Therefore any rights, title and interest in our trademarks remain entirely with us.
*
* However, if you propagate an unmodified version of the Program you are
* allowed to use the term "Z-Push" to indicate that you distribute the Program.
* Furthermore you may use our trademarks where it is necessary to indicate
* the intended purpose of a product or service provided you use it in accordance
* with honest practices in industrial or commercial matters.
* If you want to propagate modified versions of the Program under the name "Z-Push",
* you may only do so if you have a written permission by Zarafa Deutschland GmbH
* (to acquire a permission please contact Zarafa at trademark@zarafa.com).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Consult LICENSE file for details
************************************************/
class Search extends RequestProcessor {
/**
* 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) {
if (is_array($rows) && !empty($rows)) {
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;
}
}
?>