Back to index

d-push  2.0
search.php
Go to the documentation of this file.
00001 <?php
00002 /***********************************************
00003 * File      :   search.php
00004 * Project   :   Z-Push
00005 * Descr     :   Provides the SEARCH command
00006 *
00007 * Created   :   16.02.2012
00008 *
00009 * Copyright 2007 - 2012 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 
00044 class Search extends RequestProcessor {
00045 
00054     public function Handle($commandCode) {
00055         $searchrange = '0';
00056         $cpo = new ContentParameters();
00057 
00058         if(!self::$decoder->getElementStartTag(SYNC_SEARCH_SEARCH))
00059             return false;
00060 
00061         // TODO check: possible to search in other stores?
00062         if(!self::$decoder->getElementStartTag(SYNC_SEARCH_STORE))
00063             return false;
00064 
00065         if(!self::$decoder->getElementStartTag(SYNC_SEARCH_NAME))
00066             return false;
00067         $searchname = strtoupper(self::$decoder->getElementContent());
00068         if(!self::$decoder->getElementEndTag())
00069             return false;
00070 
00071         if(!self::$decoder->getElementStartTag(SYNC_SEARCH_QUERY))
00072             return false;
00073 
00074         // check if it is a content of an element (= GAL search)
00075         // or a starttag (= mailbox or documentlibrary search)
00076         $searchquery = self::$decoder->getElementContent();
00077         if($searchquery && !self::$decoder->getElementEndTag())
00078             return false;
00079 
00080         if ($searchquery === false) {
00081             $cpo->SetSearchName($searchname);
00082             if (self::$decoder->getElementStartTag(SYNC_SEARCH_AND)) {
00083                 if (self::$decoder->getElementStartTag(SYNC_FOLDERID)) {
00084                     $searchfolderid = self::$decoder->getElementContent();
00085                     $cpo->SetSearchFolderid($searchfolderid);
00086                     if(!self::$decoder->getElementEndTag()) // SYNC_FOLDERTYPE
00087                     return false;
00088                 }
00089 
00090 
00091                 if (self::$decoder->getElementStartTag(SYNC_FOLDERTYPE)) {
00092                     $searchclass = self::$decoder->getElementContent();
00093                     $cpo->SetSearchClass($searchclass);
00094                     if(!self::$decoder->getElementEndTag()) // SYNC_FOLDERTYPE
00095                         return false;
00096                 }
00097 
00098                 if (self::$decoder->getElementStartTag(SYNC_FOLDERID)) {
00099                     $searchfolderid = self::$decoder->getElementContent();
00100                     $cpo->SetSearchFolderid($searchfolderid);
00101                     if(!self::$decoder->getElementEndTag()) // SYNC_FOLDERTYPE
00102                     return false;
00103                 }
00104 
00105                 if (self::$decoder->getElementStartTag(SYNC_SEARCH_FREETEXT)) {
00106                     $searchfreetext = self::$decoder->getElementContent();
00107                     $cpo->SetSearchFreeText($searchfreetext);
00108                     if(!self::$decoder->getElementEndTag()) // SYNC_SEARCH_FREETEXT
00109                     return false;
00110                 }
00111 
00112                 //TODO - review
00113                 if (self::$decoder->getElementStartTag(SYNC_SEARCH_GREATERTHAN)) {
00114                     if(self::$decoder->getElementStartTag(SYNC_POOMMAIL_DATERECEIVED)) {
00115                         $datereceivedgreater = true;
00116                         if (($dam = self::$decoder->getElementContent()) !== false) {
00117                             $datereceivedgreater = true;
00118                             if(!self::$decoder->getElementEndTag()) {
00119                                 return false;
00120                             }
00121                         }
00122                         $cpo->SetSearchDateReceivedGreater($datereceivedgreater);
00123                     }
00124 
00125                     if(self::$decoder->getElementStartTag(SYNC_SEARCH_VALUE)) {
00126                         $searchvalue = self::$decoder->getElementContent();
00127                         $cpo->SetSearchValueGreater($searchvalue);
00128                         if(!self::$decoder->getElementEndTag()) // SYNC_SEARCH_VALUE
00129                             return false;
00130                     }
00131 
00132                     if(!self::$decoder->getElementEndTag()) // SYNC_SEARCH_GREATERTHAN
00133                         return false;
00134                 }
00135 
00136                 if (self::$decoder->getElementStartTag(SYNC_SEARCH_LESSTHAN)) {
00137                     if(self::$decoder->getElementStartTag(SYNC_POOMMAIL_DATERECEIVED)) {
00138                         $datereceivedless = true;
00139                         if (($dam = self::$decoder->getElementContent()) !== false) {
00140                             $datereceivedless = true;
00141                             if(!self::$decoder->getElementEndTag()) {
00142                                 return false;
00143                             }
00144                         }
00145                         $cpo->SetSearchDateReceivedLess($datereceivedless);
00146                     }
00147 
00148                     if(self::$decoder->getElementStartTag(SYNC_SEARCH_VALUE)) {
00149                         $searchvalue = self::$decoder->getElementContent();
00150                         $cpo->SetSearchValueLess($searchvalue);
00151                         if(!self::$decoder->getElementEndTag()) // SYNC_SEARCH_VALUE
00152                          return false;
00153                     }
00154 
00155                     if(!self::$decoder->getElementEndTag()) // SYNC_SEARCH_LESSTHAN
00156                         return false;
00157                 }
00158 
00159                 if (self::$decoder->getElementStartTag(SYNC_SEARCH_FREETEXT)) {
00160                     $searchfreetext = self::$decoder->getElementContent();
00161                     $cpo->SetSearchFreeText($searchfreetext);
00162                     if(!self::$decoder->getElementEndTag()) // SYNC_SEARCH_FREETEXT
00163                     return false;
00164                 }
00165 
00166                 if(!self::$decoder->getElementEndTag()) // SYNC_SEARCH_AND
00167                     return false;
00168             }
00169 
00170             if(!self::$decoder->getElementEndTag()) // SYNC_SEARCH_QUERY
00171                 return false;
00172 
00173         }
00174 
00175         if(self::$decoder->getElementStartTag(SYNC_SEARCH_OPTIONS)) {
00176             while(1) {
00177                 if(self::$decoder->getElementStartTag(SYNC_SEARCH_RANGE)) {
00178                     $searchrange = self::$decoder->getElementContent();
00179                     $cpo->SetSearchRange($searchrange);
00180                     if(!self::$decoder->getElementEndTag())
00181                         return false;
00182                 }
00183 
00184 
00185                 if(self::$decoder->getElementStartTag(SYNC_SEARCH_REBUILDRESULTS)) {
00186                     $rebuildresults = true;
00187                     if (($dam = self::$decoder->getElementContent()) !== false) {
00188                         $rebuildresults = true;
00189                         if(!self::$decoder->getElementEndTag()) {
00190                             return false;
00191                         }
00192                     }
00193                     $cpo->SetSearchRebuildResults($rebuildresults);
00194                 }
00195 
00196                 if(self::$decoder->getElementStartTag(SYNC_SEARCH_DEEPTRAVERSAL)) {
00197                     $deeptraversal = true;
00198                     if (($dam = self::$decoder->getElementContent()) !== false) {
00199                         $deeptraversal = true;
00200                         if(!self::$decoder->getElementEndTag()) {
00201                             return false;
00202                         }
00203                     }
00204                     $cpo->SetSearchDeepTraversal($deeptraversal);
00205                 }
00206 
00207                 if(self::$decoder->getElementStartTag(SYNC_MIMESUPPORT)) {
00208                     $cpo->SetMimeSupport(self::$decoder->getElementContent());
00209                     if(!self::$decoder->getElementEndTag())
00210                     return false;
00211                 }
00212 
00213                 //TODO body preferences
00214                 while (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_BODYPREFERENCE)) {
00215                     if(self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TYPE)) {
00216                         $bptype = self::$decoder->getElementContent();
00217                         $cpo->BodyPreference($bptype);
00218                         if(!self::$decoder->getElementEndTag()) {
00219                             return false;
00220                         }
00221                     }
00222 
00223                     if(self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TRUNCATIONSIZE)) {
00224                         $cpo->BodyPreference($bptype)->SetTruncationSize(self::$decoder->getElementContent());
00225                         if(!self::$decoder->getElementEndTag())
00226                             return false;
00227                     }
00228 
00229                     if(self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_ALLORNONE)) {
00230                         $cpo->BodyPreference($bptype)->SetAllOrNone(self::$decoder->getElementContent());
00231                         if(!self::$decoder->getElementEndTag())
00232                             return false;
00233                     }
00234 
00235                     if(self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_PREVIEW)) {
00236                         $cpo->BodyPreference($bptype)->SetPreview(self::$decoder->getElementContent());
00237                         if(!self::$decoder->getElementEndTag())
00238                             return false;
00239                     }
00240 
00241                     if(!self::$decoder->getElementEndTag())
00242                         return false;
00243                 }
00244 
00245                 $e = self::$decoder->peek();
00246                 if($e[EN_TYPE] == EN_TYPE_ENDTAG) {
00247                     self::$decoder->getElementEndTag();
00248                     break;
00249                 }
00250             }
00251         }
00252         if(!self::$decoder->getElementEndTag()) //store
00253             return false;
00254 
00255         if(!self::$decoder->getElementEndTag()) //search
00256             return false;
00257 
00258         // get SearchProvider
00259         $searchprovider = ZPush::GetSearchProvider();
00260         $status = SYNC_SEARCHSTATUS_SUCCESS;
00261         $rows = array();
00262 
00263         // TODO support other searches
00264         if ($searchprovider->SupportsType($searchname)) {
00265             $storestatus = SYNC_SEARCHSTATUS_STORE_SUCCESS;
00266             try {
00267                 if ($searchname == ISearchProvider::SEARCH_GAL) {
00268                     //get search results from the searchprovider
00269                     $rows = $searchprovider->GetGALSearchResults($searchquery, $searchrange);
00270                 }
00271                 elseif ($searchname == ISearchProvider::SEARCH_MAILBOX) {
00272                     $rows = $searchprovider->GetMailboxSearchResults($cpo);
00273                 }
00274             }
00275             catch (StatusException $stex) {
00276                 $storestatus = $stex->getCode();
00277             }
00278         }
00279         else {
00280             $rows = array('searchtotal' => 0);
00281             $status = SYNC_SEARCHSTATUS_SERVERERROR;
00282             ZLog::Write(LOGLEVEL_WARN, sprintf("Searchtype '%s' is not supported.", $searchname));
00283             self::$topCollector->AnnounceInformation(sprintf("Unsupported type '%s''", $searchname), true);
00284         }
00285         $searchprovider->Disconnect();
00286 
00287         self::$topCollector->AnnounceInformation(sprintf("'%s' search found %d results", $searchname, $rows['searchtotal']), true);
00288 
00289         self::$encoder->startWBXML();
00290         self::$encoder->startTag(SYNC_SEARCH_SEARCH);
00291 
00292             self::$encoder->startTag(SYNC_SEARCH_STATUS);
00293             self::$encoder->content($status);
00294             self::$encoder->endTag();
00295 
00296             if ($status == SYNC_SEARCHSTATUS_SUCCESS) {
00297                 self::$encoder->startTag(SYNC_SEARCH_RESPONSE);
00298                 self::$encoder->startTag(SYNC_SEARCH_STORE);
00299 
00300                     self::$encoder->startTag(SYNC_SEARCH_STATUS);
00301                     self::$encoder->content($storestatus);
00302                     self::$encoder->endTag();
00303 
00304                     if (isset($rows['range'])) {
00305                         $searchrange = $rows['range'];
00306                         unset($rows['range']);
00307                     }
00308                     if (isset($rows['searchtotal'])) {
00309                         $searchtotal = $rows['searchtotal'];
00310                         unset($rows['searchtotal']);
00311                     }
00312                     if ($searchname == ISearchProvider::SEARCH_GAL) {
00313                         if (is_array($rows) && !empty($rows)) {
00314                             foreach ($rows as $u) {
00315                                 self::$encoder->startTag(SYNC_SEARCH_RESULT);
00316                                     self::$encoder->startTag(SYNC_SEARCH_PROPERTIES);
00317 
00318                                         self::$encoder->startTag(SYNC_GAL_DISPLAYNAME);
00319                                         self::$encoder->content((isset($u[SYNC_GAL_DISPLAYNAME]))?$u[SYNC_GAL_DISPLAYNAME]:"No name");
00320                                         self::$encoder->endTag();
00321 
00322                                         if (isset($u[SYNC_GAL_PHONE])) {
00323                                             self::$encoder->startTag(SYNC_GAL_PHONE);
00324                                             self::$encoder->content($u[SYNC_GAL_PHONE]);
00325                                             self::$encoder->endTag();
00326                                         }
00327 
00328                                         if (isset($u[SYNC_GAL_OFFICE])) {
00329                                             self::$encoder->startTag(SYNC_GAL_OFFICE);
00330                                             self::$encoder->content($u[SYNC_GAL_OFFICE]);
00331                                             self::$encoder->endTag();
00332                                         }
00333 
00334                                         if (isset($u[SYNC_GAL_TITLE])) {
00335                                             self::$encoder->startTag(SYNC_GAL_TITLE);
00336                                             self::$encoder->content($u[SYNC_GAL_TITLE]);
00337                                             self::$encoder->endTag();
00338                                         }
00339 
00340                                         if (isset($u[SYNC_GAL_COMPANY])) {
00341                                             self::$encoder->startTag(SYNC_GAL_COMPANY);
00342                                             self::$encoder->content($u[SYNC_GAL_COMPANY]);
00343                                             self::$encoder->endTag();
00344                                         }
00345 
00346                                         if (isset($u[SYNC_GAL_ALIAS])) {
00347                                             self::$encoder->startTag(SYNC_GAL_ALIAS);
00348                                             self::$encoder->content($u[SYNC_GAL_ALIAS]);
00349                                             self::$encoder->endTag();
00350                                         }
00351 
00352                                         // Always send the firstname, even empty. Nokia needs this to display the entry
00353                                         self::$encoder->startTag(SYNC_GAL_FIRSTNAME);
00354                                         self::$encoder->content((isset($u[SYNC_GAL_FIRSTNAME]))?$u[SYNC_GAL_FIRSTNAME]:"");
00355                                         self::$encoder->endTag();
00356 
00357                                         self::$encoder->startTag(SYNC_GAL_LASTNAME);
00358                                         self::$encoder->content((isset($u[SYNC_GAL_LASTNAME]))?$u[SYNC_GAL_LASTNAME]:"No name");
00359                                         self::$encoder->endTag();
00360 
00361                                         if (isset($u[SYNC_GAL_HOMEPHONE])) {
00362                                             self::$encoder->startTag(SYNC_GAL_HOMEPHONE);
00363                                             self::$encoder->content($u[SYNC_GAL_HOMEPHONE]);
00364                                             self::$encoder->endTag();
00365                                         }
00366 
00367                                         if (isset($u[SYNC_GAL_MOBILEPHONE])) {
00368                                             self::$encoder->startTag(SYNC_GAL_MOBILEPHONE);
00369                                             self::$encoder->content($u[SYNC_GAL_MOBILEPHONE]);
00370                                             self::$encoder->endTag();
00371                                         }
00372 
00373                                         self::$encoder->startTag(SYNC_GAL_EMAILADDRESS);
00374                                         self::$encoder->content((isset($u[SYNC_GAL_EMAILADDRESS]))?$u[SYNC_GAL_EMAILADDRESS]:"");
00375                                         self::$encoder->endTag();
00376 
00377                                     self::$encoder->endTag();//result
00378                                 self::$encoder->endTag();//properties
00379                             }
00380                         }
00381                     }
00382                     elseif ($searchname == ISearchProvider::SEARCH_MAILBOX) {
00383                         foreach ($rows as $u) {
00384                             self::$encoder->startTag(SYNC_SEARCH_RESULT);
00385                                 self::$encoder->startTag(SYNC_FOLDERTYPE);
00386                                 self::$encoder->content($u['class']);
00387                                 self::$encoder->endTag();
00388                                 self::$encoder->startTag(SYNC_SEARCH_LONGID);
00389                                 self::$encoder->content($u['longid']);
00390                                 self::$encoder->endTag();
00391                                 self::$encoder->startTag(SYNC_FOLDERID);
00392                                 self::$encoder->content($u['folderid']);
00393                                 self::$encoder->endTag();
00394 
00395                                 self::$encoder->startTag(SYNC_SEARCH_PROPERTIES);
00396                                     $tmp = explode(":", $u['longid']);
00397                                     $message = self::$backend->Fetch($u['folderid'], $tmp[1], $cpo);
00398                                     $message->Encode(self::$encoder);
00399 
00400                                 self::$encoder->endTag();//result
00401                             self::$encoder->endTag();//properties
00402                         }
00403                     }
00404                     // it seems that android 4 requires range and searchtotal
00405                     // or it won't display the search results
00406                     if (isset($searchrange)) {
00407                         self::$encoder->startTag(SYNC_SEARCH_RANGE);
00408                         self::$encoder->content($searchrange);
00409                         self::$encoder->endTag();
00410                     }
00411                     if (isset($searchtotal) && $searchtotal > 0) {
00412                         self::$encoder->startTag(SYNC_SEARCH_TOTAL);
00413                         self::$encoder->content($searchtotal);
00414                         self::$encoder->endTag();
00415                     }
00416 
00417                 self::$encoder->endTag();//store
00418                 self::$encoder->endTag();//response
00419             }
00420         self::$encoder->endTag();//search
00421 
00422         return true;
00423     }
00424 }
00425 ?>