source: trunk/zpush/lib/request/search.php @ 7589

Revision 7589, 19.7 KB checked in by douglas, 11 years ago (diff)

Ticket #3209 - Integrar módulo de sincronização Z-push ao Expresso

Line 
1<?php
2/***********************************************
3* File      :   search.php
4* Project   :   Z-Push
5* Descr     :   Provides the SEARCH command
6*
7* Created   :   16.02.2012
8*
9* Copyright 2007 - 2012 Zarafa Deutschland GmbH
10*
11* This program is free software: you can redistribute it and/or modify
12* it under the terms of the GNU Affero General Public License, version 3,
13* as published by the Free Software Foundation with the following additional
14* term according to sec. 7:
15*
16* According to sec. 7 of the GNU Affero General Public License, version 3,
17* the terms of the AGPL are supplemented with the following terms:
18*
19* "Zarafa" is a registered trademark of Zarafa B.V.
20* "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
21* The licensing of the Program under the AGPL does not imply a trademark license.
22* Therefore any rights, title and interest in our trademarks remain entirely with us.
23*
24* However, if you propagate an unmodified version of the Program you are
25* allowed to use the term "Z-Push" to indicate that you distribute the Program.
26* Furthermore you may use our trademarks where it is necessary to indicate
27* the intended purpose of a product or service provided you use it in accordance
28* with honest practices in industrial or commercial matters.
29* If you want to propagate modified versions of the Program under the name "Z-Push",
30* you may only do so if you have a written permission by Zarafa Deutschland GmbH
31* (to acquire a permission please contact Zarafa at trademark@zarafa.com).
32*
33* This program is distributed in the hope that it will be useful,
34* but WITHOUT ANY WARRANTY; without even the implied warranty of
35* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36* GNU Affero General Public License for more details.
37*
38* You should have received a copy of the GNU Affero General Public License
39* along with this program.  If not, see <http://www.gnu.org/licenses/>.
40*
41* Consult LICENSE file for details
42************************************************/
43
44class Search extends RequestProcessor {
45
46    /**
47     * Handles the Search command
48     *
49     * @param int       $commandCode
50     *
51     * @access public
52     * @return boolean
53     */
54    public function Handle($commandCode) {
55        $searchrange = '0';
56        $cpo = new ContentParameters();
57
58        if(!self::$decoder->getElementStartTag(SYNC_SEARCH_SEARCH))
59            return false;
60
61        // TODO check: possible to search in other stores?
62        if(!self::$decoder->getElementStartTag(SYNC_SEARCH_STORE))
63            return false;
64
65        if(!self::$decoder->getElementStartTag(SYNC_SEARCH_NAME))
66            return false;
67        $searchname = strtoupper(self::$decoder->getElementContent());
68        if(!self::$decoder->getElementEndTag())
69            return false;
70
71        if(!self::$decoder->getElementStartTag(SYNC_SEARCH_QUERY))
72            return false;
73
74        // check if it is a content of an element (= GAL search)
75        // or a starttag (= mailbox or documentlibrary search)
76        $searchquery = self::$decoder->getElementContent();
77        if($searchquery && !self::$decoder->getElementEndTag())
78            return false;
79
80        if ($searchquery === false) {
81            $cpo->SetSearchName($searchname);
82            if (self::$decoder->getElementStartTag(SYNC_SEARCH_AND)) {
83                if (self::$decoder->getElementStartTag(SYNC_FOLDERID)) {
84                    $searchfolderid = self::$decoder->getElementContent();
85                    $cpo->SetSearchFolderid($searchfolderid);
86                    if(!self::$decoder->getElementEndTag()) // SYNC_FOLDERTYPE
87                    return false;
88                }
89
90
91                if (self::$decoder->getElementStartTag(SYNC_FOLDERTYPE)) {
92                    $searchclass = self::$decoder->getElementContent();
93                    $cpo->SetSearchClass($searchclass);
94                    if(!self::$decoder->getElementEndTag()) // SYNC_FOLDERTYPE
95                        return false;
96                }
97
98                if (self::$decoder->getElementStartTag(SYNC_FOLDERID)) {
99                    $searchfolderid = self::$decoder->getElementContent();
100                    $cpo->SetSearchFolderid($searchfolderid);
101                    if(!self::$decoder->getElementEndTag()) // SYNC_FOLDERTYPE
102                    return false;
103                }
104
105                if (self::$decoder->getElementStartTag(SYNC_SEARCH_FREETEXT)) {
106                    $searchfreetext = self::$decoder->getElementContent();
107                    $cpo->SetSearchFreeText($searchfreetext);
108                    if(!self::$decoder->getElementEndTag()) // SYNC_SEARCH_FREETEXT
109                    return false;
110                }
111
112                //TODO - review
113                if (self::$decoder->getElementStartTag(SYNC_SEARCH_GREATERTHAN)) {
114                    if(self::$decoder->getElementStartTag(SYNC_POOMMAIL_DATERECEIVED)) {
115                        $datereceivedgreater = true;
116                        if (($dam = self::$decoder->getElementContent()) !== false) {
117                            $datereceivedgreater = true;
118                            if(!self::$decoder->getElementEndTag()) {
119                                return false;
120                            }
121                        }
122                        $cpo->SetSearchDateReceivedGreater($datereceivedgreater);
123                    }
124
125                    if(self::$decoder->getElementStartTag(SYNC_SEARCH_VALUE)) {
126                        $searchvalue = self::$decoder->getElementContent();
127                        $cpo->SetSearchValueGreater($searchvalue);
128                        if(!self::$decoder->getElementEndTag()) // SYNC_SEARCH_VALUE
129                            return false;
130                    }
131
132                    if(!self::$decoder->getElementEndTag()) // SYNC_SEARCH_GREATERTHAN
133                        return false;
134                }
135
136                if (self::$decoder->getElementStartTag(SYNC_SEARCH_LESSTHAN)) {
137                    if(self::$decoder->getElementStartTag(SYNC_POOMMAIL_DATERECEIVED)) {
138                        $datereceivedless = true;
139                        if (($dam = self::$decoder->getElementContent()) !== false) {
140                            $datereceivedless = true;
141                            if(!self::$decoder->getElementEndTag()) {
142                                return false;
143                            }
144                        }
145                        $cpo->SetSearchDateReceivedLess($datereceivedless);
146                    }
147
148                    if(self::$decoder->getElementStartTag(SYNC_SEARCH_VALUE)) {
149                        $searchvalue = self::$decoder->getElementContent();
150                        $cpo->SetSearchValueLess($searchvalue);
151                        if(!self::$decoder->getElementEndTag()) // SYNC_SEARCH_VALUE
152                         return false;
153                    }
154
155                    if(!self::$decoder->getElementEndTag()) // SYNC_SEARCH_LESSTHAN
156                        return false;
157                }
158
159                if (self::$decoder->getElementStartTag(SYNC_SEARCH_FREETEXT)) {
160                    $searchfreetext = self::$decoder->getElementContent();
161                    $cpo->SetSearchFreeText($searchfreetext);
162                    if(!self::$decoder->getElementEndTag()) // SYNC_SEARCH_FREETEXT
163                    return false;
164                }
165
166                if(!self::$decoder->getElementEndTag()) // SYNC_SEARCH_AND
167                    return false;
168            }
169
170            if(!self::$decoder->getElementEndTag()) // SYNC_SEARCH_QUERY
171                return false;
172
173        }
174
175        if(self::$decoder->getElementStartTag(SYNC_SEARCH_OPTIONS)) {
176            while(1) {
177                if(self::$decoder->getElementStartTag(SYNC_SEARCH_RANGE)) {
178                    $searchrange = self::$decoder->getElementContent();
179                    $cpo->SetSearchRange($searchrange);
180                    if(!self::$decoder->getElementEndTag())
181                        return false;
182                }
183
184
185                if(self::$decoder->getElementStartTag(SYNC_SEARCH_REBUILDRESULTS)) {
186                    $rebuildresults = true;
187                    if (($dam = self::$decoder->getElementContent()) !== false) {
188                        $rebuildresults = true;
189                        if(!self::$decoder->getElementEndTag()) {
190                            return false;
191                        }
192                    }
193                    $cpo->SetSearchRebuildResults($rebuildresults);
194                }
195
196                if(self::$decoder->getElementStartTag(SYNC_SEARCH_DEEPTRAVERSAL)) {
197                    $deeptraversal = true;
198                    if (($dam = self::$decoder->getElementContent()) !== false) {
199                        $deeptraversal = true;
200                        if(!self::$decoder->getElementEndTag()) {
201                            return false;
202                        }
203                    }
204                    $cpo->SetSearchDeepTraversal($deeptraversal);
205                }
206
207                if(self::$decoder->getElementStartTag(SYNC_MIMESUPPORT)) {
208                    $cpo->SetMimeSupport(self::$decoder->getElementContent());
209                    if(!self::$decoder->getElementEndTag())
210                    return false;
211                }
212
213                //TODO body preferences
214                while (self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_BODYPREFERENCE)) {
215                    if(self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TYPE)) {
216                        $bptype = self::$decoder->getElementContent();
217                        $cpo->BodyPreference($bptype);
218                        if(!self::$decoder->getElementEndTag()) {
219                            return false;
220                        }
221                    }
222
223                    if(self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_TRUNCATIONSIZE)) {
224                        $cpo->BodyPreference($bptype)->SetTruncationSize(self::$decoder->getElementContent());
225                        if(!self::$decoder->getElementEndTag())
226                            return false;
227                    }
228
229                    if(self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_ALLORNONE)) {
230                        $cpo->BodyPreference($bptype)->SetAllOrNone(self::$decoder->getElementContent());
231                        if(!self::$decoder->getElementEndTag())
232                            return false;
233                    }
234
235                    if(self::$decoder->getElementStartTag(SYNC_AIRSYNCBASE_PREVIEW)) {
236                        $cpo->BodyPreference($bptype)->SetPreview(self::$decoder->getElementContent());
237                        if(!self::$decoder->getElementEndTag())
238                            return false;
239                    }
240
241                    if(!self::$decoder->getElementEndTag())
242                        return false;
243                }
244
245                $e = self::$decoder->peek();
246                if($e[EN_TYPE] == EN_TYPE_ENDTAG) {
247                    self::$decoder->getElementEndTag();
248                    break;
249                }
250            }
251        }
252        if(!self::$decoder->getElementEndTag()) //store
253            return false;
254
255        if(!self::$decoder->getElementEndTag()) //search
256            return false;
257
258        // get SearchProvider
259        $searchprovider = ZPush::GetSearchProvider();
260        $status = SYNC_SEARCHSTATUS_SUCCESS;
261        $rows = array();
262
263        // TODO support other searches
264        if ($searchprovider->SupportsType($searchname)) {
265            $storestatus = SYNC_SEARCHSTATUS_STORE_SUCCESS;
266            try {
267                if ($searchname == ISearchProvider::SEARCH_GAL) {
268                    //get search results from the searchprovider
269                    $rows = $searchprovider->GetGALSearchResults($searchquery, $searchrange);
270                }
271                elseif ($searchname == ISearchProvider::SEARCH_MAILBOX) {
272                    $rows = $searchprovider->GetMailboxSearchResults($cpo);
273                }
274            }
275            catch (StatusException $stex) {
276                $storestatus = $stex->getCode();
277            }
278        }
279        else {
280            $rows = array('searchtotal' => 0);
281            $status = SYNC_SEARCHSTATUS_SERVERERROR;
282            ZLog::Write(LOGLEVEL_WARN, sprintf("Searchtype '%s' is not supported.", $searchname));
283            self::$topCollector->AnnounceInformation(sprintf("Unsupported type '%s''", $searchname), true);
284        }
285        $searchprovider->Disconnect();
286
287        self::$topCollector->AnnounceInformation(sprintf("'%s' search found %d results", $searchname, $rows['searchtotal']), true);
288
289        self::$encoder->startWBXML();
290        self::$encoder->startTag(SYNC_SEARCH_SEARCH);
291
292            self::$encoder->startTag(SYNC_SEARCH_STATUS);
293            self::$encoder->content($status);
294            self::$encoder->endTag();
295
296            if ($status == SYNC_SEARCHSTATUS_SUCCESS) {
297                self::$encoder->startTag(SYNC_SEARCH_RESPONSE);
298                self::$encoder->startTag(SYNC_SEARCH_STORE);
299
300                    self::$encoder->startTag(SYNC_SEARCH_STATUS);
301                    self::$encoder->content($storestatus);
302                    self::$encoder->endTag();
303
304                    if (isset($rows['range'])) {
305                        $searchrange = $rows['range'];
306                        unset($rows['range']);
307                    }
308                    if (isset($rows['searchtotal'])) {
309                        $searchtotal = $rows['searchtotal'];
310                        unset($rows['searchtotal']);
311                    }
312                    if ($searchname == ISearchProvider::SEARCH_GAL) {
313                        if (is_array($rows) && !empty($rows)) {
314                            foreach ($rows as $u) {
315                                self::$encoder->startTag(SYNC_SEARCH_RESULT);
316                                    self::$encoder->startTag(SYNC_SEARCH_PROPERTIES);
317
318                                        self::$encoder->startTag(SYNC_GAL_DISPLAYNAME);
319                                        self::$encoder->content((isset($u[SYNC_GAL_DISPLAYNAME]))?$u[SYNC_GAL_DISPLAYNAME]:"No name");
320                                        self::$encoder->endTag();
321
322                                        if (isset($u[SYNC_GAL_PHONE])) {
323                                            self::$encoder->startTag(SYNC_GAL_PHONE);
324                                            self::$encoder->content($u[SYNC_GAL_PHONE]);
325                                            self::$encoder->endTag();
326                                        }
327
328                                        if (isset($u[SYNC_GAL_OFFICE])) {
329                                            self::$encoder->startTag(SYNC_GAL_OFFICE);
330                                            self::$encoder->content($u[SYNC_GAL_OFFICE]);
331                                            self::$encoder->endTag();
332                                        }
333
334                                        if (isset($u[SYNC_GAL_TITLE])) {
335                                            self::$encoder->startTag(SYNC_GAL_TITLE);
336                                            self::$encoder->content($u[SYNC_GAL_TITLE]);
337                                            self::$encoder->endTag();
338                                        }
339
340                                        if (isset($u[SYNC_GAL_COMPANY])) {
341                                            self::$encoder->startTag(SYNC_GAL_COMPANY);
342                                            self::$encoder->content($u[SYNC_GAL_COMPANY]);
343                                            self::$encoder->endTag();
344                                        }
345
346                                        if (isset($u[SYNC_GAL_ALIAS])) {
347                                            self::$encoder->startTag(SYNC_GAL_ALIAS);
348                                            self::$encoder->content($u[SYNC_GAL_ALIAS]);
349                                            self::$encoder->endTag();
350                                        }
351
352                                        // Always send the firstname, even empty. Nokia needs this to display the entry
353                                        self::$encoder->startTag(SYNC_GAL_FIRSTNAME);
354                                        self::$encoder->content((isset($u[SYNC_GAL_FIRSTNAME]))?$u[SYNC_GAL_FIRSTNAME]:"");
355                                        self::$encoder->endTag();
356
357                                        self::$encoder->startTag(SYNC_GAL_LASTNAME);
358                                        self::$encoder->content((isset($u[SYNC_GAL_LASTNAME]))?$u[SYNC_GAL_LASTNAME]:"No name");
359                                        self::$encoder->endTag();
360
361                                        if (isset($u[SYNC_GAL_HOMEPHONE])) {
362                                            self::$encoder->startTag(SYNC_GAL_HOMEPHONE);
363                                            self::$encoder->content($u[SYNC_GAL_HOMEPHONE]);
364                                            self::$encoder->endTag();
365                                        }
366
367                                        if (isset($u[SYNC_GAL_MOBILEPHONE])) {
368                                            self::$encoder->startTag(SYNC_GAL_MOBILEPHONE);
369                                            self::$encoder->content($u[SYNC_GAL_MOBILEPHONE]);
370                                            self::$encoder->endTag();
371                                        }
372
373                                        self::$encoder->startTag(SYNC_GAL_EMAILADDRESS);
374                                        self::$encoder->content((isset($u[SYNC_GAL_EMAILADDRESS]))?$u[SYNC_GAL_EMAILADDRESS]:"");
375                                        self::$encoder->endTag();
376
377                                    self::$encoder->endTag();//result
378                                self::$encoder->endTag();//properties
379                            }
380                        }
381                    }
382                    elseif ($searchname == ISearchProvider::SEARCH_MAILBOX) {
383                        foreach ($rows as $u) {
384                            self::$encoder->startTag(SYNC_SEARCH_RESULT);
385                                self::$encoder->startTag(SYNC_FOLDERTYPE);
386                                self::$encoder->content($u['class']);
387                                self::$encoder->endTag();
388                                self::$encoder->startTag(SYNC_SEARCH_LONGID);
389                                self::$encoder->content($u['longid']);
390                                self::$encoder->endTag();
391                                self::$encoder->startTag(SYNC_FOLDERID);
392                                self::$encoder->content($u['folderid']);
393                                self::$encoder->endTag();
394
395                                self::$encoder->startTag(SYNC_SEARCH_PROPERTIES);
396                                    $tmp = explode(":", $u['longid']);
397                                    $message = self::$backend->Fetch($u['folderid'], $tmp[1], $cpo);
398                                    $message->Encode(self::$encoder);
399
400                                self::$encoder->endTag();//result
401                            self::$encoder->endTag();//properties
402                        }
403                    }
404                    // it seems that android 4 requires range and searchtotal
405                    // or it won't display the search results
406                    if (isset($searchrange)) {
407                        self::$encoder->startTag(SYNC_SEARCH_RANGE);
408                        self::$encoder->content($searchrange);
409                        self::$encoder->endTag();
410                    }
411                    if (isset($searchtotal) && $searchtotal > 0) {
412                        self::$encoder->startTag(SYNC_SEARCH_TOTAL);
413                        self::$encoder->content($searchtotal);
414                        self::$encoder->endTag();
415                    }
416
417                self::$encoder->endTag();//store
418                self::$encoder->endTag();//response
419            }
420        self::$encoder->endTag();//search
421
422        return true;
423    }
424}
425?>
Note: See TracBrowser for help on using the repository browser.