Overview

Packages

  • ActiveSync
  • None

Classes

  • Horde_ActiveSync
  • Horde_ActiveSync_Connector_Exporter
  • Horde_ActiveSync_Connector_Importer
  • Horde_ActiveSync_Driver_Base
  • Horde_ActiveSync_Exception
  • Horde_ActiveSync_Exception_InvalidRequest
  • Horde_ActiveSync_Exception_StateGone
  • Horde_ActiveSync_Message_Base
  • Horde_ActiveSync_Request_Base
  • Horde_ActiveSync_Request_FolderCreate
  • Horde_ActiveSync_Request_FolderSync
  • Horde_ActiveSync_Request_GetHierarchy
  • Horde_ActiveSync_Request_GetItemEstimate
  • Horde_ActiveSync_Request_MeetingResponse
  • Horde_ActiveSync_Request_MoveItems
  • Horde_ActiveSync_Request_Notify
  • Horde_ActiveSync_Request_Ping
  • Horde_ActiveSync_Request_Provision
  • Horde_ActiveSync_Request_Search
  • Horde_ActiveSync_Request_SendMail
  • Horde_ActiveSync_Request_SmartForward
  • Horde_ActiveSync_Request_SmartReply
  • Horde_ActiveSync_Request_Sync
  • Horde_ActiveSync_State_File
  • Horde_ActiveSync_Sync
  • Horde_ActiveSync_Wbxml
  • Horde_ActiveSync_Wbxml_Decoder
  • Horde_ActiveSync_Wbxml_Encoder
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * ActiveSync Handler for Search requests
  4:  *
  5:  * Copyright 2009-2012 Horde LLC (http://www.horde.org/)
  6:  *
  7:  * @author Michael J. Rubinsky <mrubinsk@horde.org>
  8:  * @package ActiveSync
  9:  */
 10: /**
 11:  * Zarafa Deutschland GmbH, www.zarafaserver.de
 12:  * This file is distributed under GPL-2.0.
 13:  * Consult COPYING file for details
 14:  */
 15: class Horde_ActiveSync_Request_Search extends Horde_ActiveSync_Request_Base
 16: {
 17: 
 18:     /** Search code page **/
 19:     const SEARCH_SEARCH = 'Search:Search';
 20:     const SEARCH_STORE = 'Search:Store';
 21:     const SEARCH_NAME = 'Search:Name';
 22:     const SEARCH_QUERY = 'Search:Query';
 23:     const SEARCH_OPTIONS = 'Search:Options';
 24:     const SEARCH_RANGE = 'Search:Range';
 25:     const SEARCH_STATUS = 'Search:Status';
 26:     const SEARCH_RESPONSE = 'Search:Response';
 27:     const SEARCH_RESULT = 'Search:Result';
 28:     const SEARCH_PROPERTIES = 'Search:Properties';
 29:     const SEARCH_TOTAL = 'Search:Total';
 30:     const SEARCH_EQUALTO = 'Search:EqualTo';
 31:     const SEARCH_VALUE = 'Search:Value';
 32:     const SEARCH_AND = 'Search:And';
 33:     const SEARCH_OR = 'Search:Or';
 34:     const SEARCH_FREETEXT = 'Search:FreeText';
 35:     const SEARCH_DEEPTRAVERSAL = 'Search:DeepTraversal';
 36:     const SEARCH_LONGID = 'Search:LongId';
 37:     const SEARCH_REBUILDRESULTS = 'Search:RebuildResults';
 38:     const SEARCH_LESSTHAN = 'Search:LessThan';
 39:     const SEARCH_GREATERTHAN = 'Search:GreaterThan';
 40:     const SEARCH_SCHEMA = 'Search:Schema';
 41:     const SEARCH_SUPPORTED = 'Search:Supported';
 42: 
 43:     /** Search Status **/
 44:     const SEARCH_STATUS_SUCCESS = 1;
 45:     const SEARCH_STATUS_ERROR = 3;
 46: 
 47:     /** Store Status **/
 48:     const STORE_STATUS_SUCCESS = 1;
 49:     const STORE_STATUS_PROTERR = 2;
 50:     const STORE_STATUS_SERVERERR = 3;
 51:     const STORE_STATUS_BADLINK = 4;
 52:     const STORE_STATUS_NOTFOUND = 6;
 53:     const STORE_STATUS_CONNECTIONERR = 7;
 54:     const STORE_STATUS_COMPLEX = 8;
 55: 
 56: 
 57:     /**
 58:      * Handle request
 59:      *
 60:      * @return boolean
 61:      */
 62:     public function handle()
 63:     {
 64:         parent::handle();
 65:         $this->_logger->info('[' . $this->_device->id . '] Beginning SEARCH');
 66: 
 67:         $searchrange = '0';
 68:         $search_status = self::SEARCH_STATUS_SUCCESS;
 69:         $store_status = self::STORE_STATUS_SUCCESS;
 70: 
 71:         if (!$this->_decoder->getElementStartTag(self::SEARCH_SEARCH) ||
 72:             !$this->_decoder->getElementStartTag(self::SEARCH_STORE) ||
 73:             !$this->_decoder->getElementStartTag(self::SEARCH_NAME)) {
 74: 
 75:             $search_status = self::SEARCH_STATUS_ERROR;
 76:         }
 77: 
 78:         /* The type of search, we only support GAL right now */
 79:         $searchname = $this->_decoder->getElementContent();
 80:         if (!$this->_decoder->getElementEndTag()) {
 81:             $search_status = self::SEARCH_STATUS_ERROR;
 82:             $store_status = self::STORE_STATUS_PROTERR;
 83:         }
 84: 
 85:         /* The search query */
 86:         if (!$this->_decoder->getElementStartTag(self::SEARCH_QUERY)) {
 87:             $search_status = self::SEARCH_STATUS_ERROR;
 88:             $store_status = self::STORE_STATUS_PROTERR;
 89:         }
 90:         $searchquery = $this->_decoder->getElementContent();
 91:         if (!$this->_decoder->getElementEndTag()) {
 92:             $search_status = self::SEARCH_STATUS_ERROR;
 93:             $store_status = self::STORE_STATUS_PROTERR;
 94:         }
 95: 
 96:         /* Range */
 97:         if ($this->_decoder->getElementStartTag(self::SEARCH_OPTIONS)) {
 98:             while(1) {
 99:                 if ($this->_decoder->getElementStartTag(self::SEARCH_RANGE)) {
100:                     $searchrange = $this->_decoder->getElementContent();
101:                     if (!$this->_decoder->getElementEndTag()) {
102:                         $search_status = self::SEARCH_STATUS_ERROR;
103:                         $store_status = self::STORE_STATUS_PROTERR;
104:                     }
105:                 }
106:                 $e = $this->_decoder->peek();
107:                 if ($e[Horde_ActiveSync_Wbxml::EN_TYPE] == Horde_ActiveSync_Wbxml::EN_TYPE_ENDTAG) {
108:                     $this->_decoder->getElementEndTag();
109:                     break;
110:                 }
111:             }
112:         }
113: 
114:         /* Close the store container */
115:         if (!$this->_decoder->getElementEndTag()) {//store
116:             $search_status = self::SEARCH_STATUS_ERROR;
117:             $store_status = self::STORE_STATUS_PROTERR;
118:         }
119: 
120:         /* Close the search container */
121:         if (!$this->_decoder->getElementEndTag()) {//search
122:             $search_status = self::SEARCH_STATUS_ERROR;
123:             $store_status = self::STORE_STATUS_PROTERR;
124:         }
125: 
126:         /* We only support the GAL */
127:         if (strtoupper($searchname) != "GAL") {
128:             $this->_logger->debug('Searchtype ' . $searchname . 'is not supported');
129:             $store_status = self::STORE_STATUS_COMPLEX;
130:         }
131: 
132:         /* Get search results from backend */
133:         $rows = $this->_driver->getSearchResults($searchquery, $searchrange);
134: 
135:         /* Send output */
136:         $this->_encoder->startWBXML();
137:         $this->_encoder->startTag(self::SEARCH_SEARCH);
138: 
139:         $this->_encoder->startTag(self::SEARCH_STATUS);
140:         $this->_encoder->content($search_status);
141:         $this->_encoder->endTag();
142: 
143:         $this->_encoder->startTag(self::SEARCH_RESPONSE);
144:         $this->_encoder->startTag(self::SEARCH_STORE);
145: 
146:         $this->_encoder->startTag(self::SEARCH_STATUS);
147:         $this->_encoder->content($store_status);
148:         $this->_encoder->endTag();
149: 
150:         $searchrange = $rows['range'];
151: 
152:         /* Build the results */
153:         foreach ($rows['rows'] as $u) {
154:             $this->_encoder->startTag(self::SEARCH_RESULT);
155:             $this->_encoder->startTag(self::SEARCH_PROPERTIES);
156: 
157:             $this->_encoder->startTag(Horde_ActiveSync::GAL_DISPLAYNAME);
158:             $this->_encoder->content($u[Horde_ActiveSync::GAL_DISPLAYNAME]);
159:             $this->_encoder->endTag();
160: 
161:             $this->_encoder->startTag(Horde_ActiveSync::GAL_PHONE);
162:             $this->_encoder->content($u[Horde_ActiveSync::GAL_PHONE]);
163:             $this->_encoder->endTag();
164: 
165:             $this->_encoder->startTag(Horde_ActiveSync::GAL_OFFICE);
166:             $this->_encoder->content($u[Horde_ActiveSync::GAL_OFFICE]);
167:             $this->_encoder->endTag();
168: 
169:             $this->_encoder->startTag(Horde_ActiveSync::GAL_TITLE);
170:             $this->_encoder->content($u[Horde_ActiveSync::GAL_TITLE]);
171:             $this->_encoder->endTag();
172: 
173:             $this->_encoder->startTag(Horde_ActiveSync::GAL_COMPANY);
174:             $this->_encoder->content($u[Horde_ActiveSync::GAL_COMPANY]);
175:             $this->_encoder->endTag();
176: 
177:             $this->_encoder->startTag(Horde_ActiveSync::GAL_ALIAS);
178:             $this->_encoder->content($u[Horde_ActiveSync::GAL_ALIAS]);
179:             $this->_encoder->endTag();
180: 
181:             $this->_encoder->startTag(Horde_ActiveSync::GAL_FIRSTNAME);
182:             $this->_encoder->content($u[Horde_ActiveSync::GAL_FIRSTNAME]);
183:             $this->_encoder->endTag();
184: 
185:             $this->_encoder->startTag(Horde_ActiveSync::GAL_LASTNAME);
186:             $this->_encoder->content($u[Horde_ActiveSync::GAL_LASTNAME]);
187:             $this->_encoder->endTag();
188: 
189:             $this->_encoder->startTag(Horde_ActiveSync::GAL_HOMEPHONE);
190:             $this->_encoder->content($u[Horde_ActiveSync::GAL_HOMEPHONE]);
191:             $this->_encoder->endTag();
192: 
193:             $this->_encoder->startTag(Horde_ActiveSync::GAL_MOBILEPHONE);
194:             $this->_encoder->content($u[Horde_ActiveSync::GAL_MOBILEPHONE]);
195:             $this->_encoder->endTag();
196: 
197:             $this->_encoder->startTag(Horde_ActiveSync::GAL_EMAILADDRESS);
198:             $this->_encoder->content($u[Horde_ActiveSync::GAL_EMAILADDRESS]);
199:             $this->_encoder->endTag();
200: 
201:             $this->_encoder->endTag();//result
202:             $this->_encoder->endTag();//properties
203: 
204:             $this->_encoder->startTag(self::SEARCH_RANGE);
205:             $this->_encoder->content($searchrange);
206:             $this->_encoder->endTag();
207: 
208:             $this->_encoder->startTag(self::SEARCH_TOTAL);
209:             $this->_encoder->content(count($rows));
210:             $this->_encoder->endTag();
211:         }
212: 
213:         $this->_encoder->endTag();//store
214:         $this->_encoder->endTag();//response
215:         $this->_encoder->endTag();//search
216: 
217:         return true;
218:     }
219: 
220: }
API documentation generated by ApiGen