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 Server - ported from ZPush
  4:  *
  5:  * Refactoring and other changes are
  6:  * Copyright 2009-2012 Horde LLC (http://www.horde.org/)
  7:  *
  8:  * @author Michael J. Rubinsky <mrubinsk@horde.org>
  9:  * @package ActiveSync
 10:  */
 11: /**
 12:  * File      :   diffbackend.php
 13:  * Project   :   Z-Push
 14:  * Descr     :   We do a standard differential
 15:  *               change detection by sorting both
 16:  *               lists of items by their unique id,
 17:  *               and then traversing both arrays
 18:  *               of items at once. Changes can be
 19:  *               detected by comparing items at
 20:  *               the same position in both arrays.
 21:  *
 22:  * Created   :   01.10.2007
 23:  *
 24:  * Zarafa Deutschland GmbH, www.zarafaserver.de
 25:  * This file is distributed under GPL-2.0.
 26:  * Consult COPYING file for details
 27:  */
 28: 
 29: // POOMMAIL
 30: //define("SYNC_POOMMAIL_ATTACHMENT","POOMMAIL:Attachment");
 31: //define("SYNC_POOMMAIL_ATTACHMENTS","POOMMAIL:Attachments");
 32: //define("SYNC_POOMMAIL_ATTNAME","POOMMAIL:AttName");
 33: //define("SYNC_POOMMAIL_ATTSIZE","POOMMAIL:AttSize");
 34: //define("SYNC_POOMMAIL_ATTOID","POOMMAIL:AttOid");
 35: //define("SYNC_POOMMAIL_ATTMETHOD","POOMMAIL:AttMethod");
 36: //define("SYNC_POOMMAIL_ATTREMOVED","POOMMAIL:AttRemoved");
 37: //define("SYNC_POOMMAIL_BODY","POOMMAIL:Body");
 38: //define("SYNC_POOMMAIL_BODYSIZE","POOMMAIL:BodySize");
 39: //define("SYNC_POOMMAIL_BODYTRUNCATED","POOMMAIL:BodyTruncated");
 40: //define("SYNC_POOMMAIL_DATERECEIVED","POOMMAIL:DateReceived");
 41: //define("SYNC_POOMMAIL_DISPLAYNAME","POOMMAIL:DisplayName");
 42: //define("SYNC_POOMMAIL_DISPLAYTO","POOMMAIL:DisplayTo");
 43: //define("SYNC_POOMMAIL_IMPORTANCE","POOMMAIL:Importance");
 44: //define("SYNC_POOMMAIL_MESSAGECLASS","POOMMAIL:MessageClass");
 45: //define("SYNC_POOMMAIL_SUBJECT","POOMMAIL:Subject");
 46: //define("SYNC_POOMMAIL_READ","POOMMAIL:Read");
 47: //define("SYNC_POOMMAIL_TO","POOMMAIL:To");
 48: //define("SYNC_POOMMAIL_CC","POOMMAIL:Cc");
 49: //define("SYNC_POOMMAIL_FROM","POOMMAIL:From");
 50: //define("SYNC_POOMMAIL_REPLY_TO","POOMMAIL:Reply-To");
 51: //define("SYNC_POOMMAIL_ALLDAYEVENT","POOMMAIL:AllDayEvent");
 52: //define("SYNC_POOMMAIL_CATEGORIES","POOMMAIL:Categories");
 53: //define("SYNC_POOMMAIL_CATEGORY","POOMMAIL:Category");
 54: //define("SYNC_POOMMAIL_DTSTAMP","POOMMAIL:DtStamp");
 55: //define("SYNC_POOMMAIL_ENDTIME","POOMMAIL:EndTime");
 56: //define("SYNC_POOMMAIL_INSTANCETYPE","POOMMAIL:InstanceType");
 57: //define("SYNC_POOMMAIL_BUSYSTATUS","POOMMAIL:BusyStatus");
 58: //define("SYNC_POOMMAIL_LOCATION","POOMMAIL:Location");
 59: //define("SYNC_POOMMAIL_MEETINGREQUEST","POOMMAIL:MeetingRequest");
 60: //define("SYNC_POOMMAIL_ORGANIZER","POOMMAIL:Organizer");
 61: //define("SYNC_POOMMAIL_RECURRENCEID","POOMMAIL:RecurrenceId");
 62: //define("SYNC_POOMMAIL_REMINDER","POOMMAIL:Reminder");
 63: //define("SYNC_POOMMAIL_RESPONSEREQUESTED","POOMMAIL:ResponseRequested");
 64: //define("SYNC_POOMMAIL_RECURRENCES","POOMMAIL:Recurrences");
 65: //define("SYNC_POOMMAIL_RECURRENCE","POOMMAIL:Recurrence");
 66: //define("SYNC_POOMMAIL_TYPE","POOMMAIL:Type");
 67: //define("SYNC_POOMMAIL_UNTIL","POOMMAIL:Until");
 68: //define("SYNC_POOMMAIL_OCCURRENCES","POOMMAIL:Occurrences");
 69: //define("SYNC_POOMMAIL_INTERVAL","POOMMAIL:Interval");
 70: //define("SYNC_POOMMAIL_DAYOFWEEK","POOMMAIL:DayOfWeek");
 71: //define("SYNC_POOMMAIL_DAYOFMONTH","POOMMAIL:DayOfMonth");
 72: //define("SYNC_POOMMAIL_WEEKOFMONTH","POOMMAIL:WeekOfMonth");
 73: //define("SYNC_POOMMAIL_MONTHOFYEAR","POOMMAIL:MonthOfYear");
 74: //define("SYNC_POOMMAIL_STARTTIME","POOMMAIL:StartTime");
 75: //define("SYNC_POOMMAIL_SENSITIVITY","POOMMAIL:Sensitivity");
 76: //define("SYNC_POOMMAIL_TIMEZONE","POOMMAIL:TimeZone");
 77: //define("SYNC_POOMMAIL_GLOBALOBJID","POOMMAIL:GlobalObjId");
 78: //define("SYNC_POOMMAIL_THREADTOPIC","POOMMAIL:ThreadTopic");
 79: //define("SYNC_POOMMAIL_MIMEDATA","POOMMAIL:MIMEData");
 80: //define("SYNC_POOMMAIL_MIMETRUNCATED","POOMMAIL:MIMETruncated");
 81: //define("SYNC_POOMMAIL_MIMESIZE","POOMMAIL:MIMESize");
 82: //define("SYNC_POOMMAIL_INTERNETCPID","POOMMAIL:InternetCPID");
 83: //
 84: //// ResolveRecipients
 85: //define("SYNC_RESOLVERECIPIENTS_RESOLVERECIPIENTS","ResolveRecipients:ResolveRecipients");
 86: //define("SYNC_RESOLVERECIPIENTS_RESPONSE","ResolveRecipients:Response");
 87: //define("SYNC_RESOLVERECIPIENTS_STATUS","ResolveRecipients:Status");
 88: //define("SYNC_RESOLVERECIPIENTS_TYPE","ResolveRecipients:Type");
 89: //define("SYNC_RESOLVERECIPIENTS_RECIPIENT","ResolveRecipients:Recipient");
 90: //define("SYNC_RESOLVERECIPIENTS_DISPLAYNAME","ResolveRecipients:DisplayName");
 91: //define("SYNC_RESOLVERECIPIENTS_EMAILADDRESS","ResolveRecipients:EmailAddress");
 92: //define("SYNC_RESOLVERECIPIENTS_CERTIFICATES","ResolveRecipients:Certificates");
 93: //define("SYNC_RESOLVERECIPIENTS_CERTIFICATE","ResolveRecipients:Certificate");
 94: //define("SYNC_RESOLVERECIPIENTS_MINICERTIFICATE","ResolveRecipients:MiniCertificate");
 95: //define("SYNC_RESOLVERECIPIENTS_OPTIONS","ResolveRecipients:Options");
 96: //define("SYNC_RESOLVERECIPIENTS_TO","ResolveRecipients:To");
 97: //define("SYNC_RESOLVERECIPIENTS_CERTIFICATERETRIEVAL","ResolveRecipients:CertificateRetrieval");
 98: //define("SYNC_RESOLVERECIPIENTS_RECIPIENTCOUNT","ResolveRecipients:RecipientCount");
 99: //define("SYNC_RESOLVERECIPIENTS_MAXCERTIFICATES","ResolveRecipients:MaxCertificates");
100: //define("SYNC_RESOLVERECIPIENTS_MAXAMBIGUOUSRECIPIENTS","ResolveRecipients:MaxAmbiguousRecipients");
101: //define("SYNC_RESOLVERECIPIENTS_CERTIFICATECOUNT","ResolveRecipients:CertificateCount");
102: //
103: //// ValidateCert
104: //define("SYNC_VALIDATECERT_VALIDATECERT","ValidateCert:ValidateCert");
105: //define("SYNC_VALIDATECERT_CERTIFICATES","ValidateCert:Certificates");
106: //define("SYNC_VALIDATECERT_CERTIFICATE","ValidateCert:Certificate");
107: //define("SYNC_VALIDATECERT_CERTIFICATECHAIN","ValidateCert:CertificateChain");
108: //define("SYNC_VALIDATECERT_CHECKCRL","ValidateCert:CheckCRL");
109: //define("SYNC_VALIDATECERT_STATUS","ValidateCert:Status");
110: 
111: /**
112:  * Main ActiveSync class. Entry point for performing all ActiveSync operations
113:  *
114:  */
115: class Horde_ActiveSync
116: {
117:     /* Conflict resolution */
118:     const CONFLICT_OVERWRITE_SERVER     = 0;
119:     const CONFLICT_OVERWRITE_PIM        = 1;
120: 
121:     const BACKEND_DISCARD_DATA          = 1;
122: 
123:     /* TRUNCATION Constants */
124:     const TRUNCATION_HEADERS            = 0;
125:     const TRUNCATION_512B               = 1;
126:     const TRUNCATION_1K                 = 2;
127:     const TRUNCATION_5K                 = 4;
128:     const TRUNCATION_SEVEN              = 7;
129:     const TRUNCATION_ALL                = 9;
130: 
131:     /* Request related constants that are used in multiple places */
132:     /* FOLDERHIERARCHY */
133:     const FOLDERHIERARCHY_FOLDERS       = 'FolderHierarchy:Folders';
134:     const FOLDERHIERARCHY_FOLDER        = 'FolderHierarchy:Folder';
135:     const FOLDERHIERARCHY_DISPLAYNAME   = 'FolderHierarchy:DisplayName';
136:     const FOLDERHIERARCHY_SERVERENTRYID = 'FolderHierarchy:ServerEntryId';
137:     const FOLDERHIERARCHY_PARENTID      = 'FolderHierarchy:ParentId';
138:     const FOLDERHIERARCHY_TYPE          = 'FolderHierarchy:Type';
139:     const FOLDERHIERARCHY_RESPONSE      = 'FolderHierarchy:Response';
140:     const FOLDERHIERARCHY_STATUS        = 'FolderHierarchy:Status';
141:     const FOLDERHIERARCHY_CONTENTCLASS  = 'FolderHierarchy:ContentClass';
142:     const FOLDERHIERARCHY_CHANGES       = 'FolderHierarchy:Changes';
143:     const FOLDERHIERARCHY_ADD           = 'FolderHierarchy:Add';
144:     const FOLDERHIERARCHY_REMOVE        = 'FolderHierarchy:Remove';
145:     const FOLDERHIERARCHY_UPDATE        = 'FolderHierarchy:Update';
146:     const FOLDERHIERARCHY_SYNCKEY       = 'FolderHierarchy:SyncKey';
147:     const FOLDERHIERARCHY_FOLDERCREATE  = 'FolderHierarchy:FolderCreate';
148:     const FOLDERHIERARCHY_FOLDERDELETE  = 'FolderHierarchy:FolderDelete';
149:     const FOLDERHIERARCHY_FOLDERUPDATE  = 'FolderHierarchy:FolderUpdate';
150:     const FOLDERHIERARCHY_FOLDERSYNC    = 'FolderHierarchy:FolderSync';
151:     const FOLDERHIERARCHY_COUNT         = 'FolderHierarchy:Count';
152:     const FOLDERHIERARCHY_VERSION       = 'FolderHierarchy:Version';
153: 
154:     /* SYNC */
155:     const SYNC_SYNCHRONIZE              = 'Synchronize';
156:     const SYNC_REPLIES                  = 'Replies';
157:     const SYNC_ADD                      = 'Add';
158:     const SYNC_MODIFY                   = 'Modify';
159:     const SYNC_REMOVE                   = 'Remove';
160:     const SYNC_FETCH                    = 'Fetch';
161:     const SYNC_SYNCKEY                  = 'SyncKey';
162:     const SYNC_CLIENTENTRYID            = 'ClientEntryId';
163:     const SYNC_SERVERENTRYID            = 'ServerEntryId';
164:     const SYNC_STATUS                   = 'Status';
165:     const SYNC_FOLDER                   = 'Folder';
166:     const SYNC_FOLDERTYPE               = 'FolderType';
167:     const SYNC_VERSION                  = 'Version';
168:     const SYNC_FOLDERID                 = 'FolderId';
169:     const SYNC_GETCHANGES               = 'GetChanges';
170:     const SYNC_MOREAVAILABLE            = 'MoreAvailable';
171:     const SYNC_WINDOWSIZE               = 'WindowSize';
172:     const SYNC_COMMANDS                 = 'Commands';
173:     const SYNC_OPTIONS                  = 'Options';
174:     const SYNC_FILTERTYPE               = 'FilterType';
175:     const SYNC_TRUNCATION               = 'Truncation';
176:     const SYNC_RTFTRUNCATION            = 'RtfTruncation';
177:     const SYNC_CONFLICT                 = 'Conflict';
178:     const SYNC_FOLDERS                  = 'Folders';
179:     const SYNC_DATA                     = 'Data';
180:     const SYNC_DELETESASMOVES           = 'DeletesAsMoves';
181:     const SYNC_NOTIFYGUID               = 'NotifyGUID';
182:     const SYNC_SUPPORTED                = 'Supported';
183:     const SYNC_SOFTDELETE               = 'SoftDelete';
184:     const SYNC_MIMESUPPORT              = 'MIMESupport';
185:     const SYNC_MIMETRUNCATION           = 'MIMETruncation';
186: 
187:     /* PROVISION */
188:     const PROVISION_PROVISION           =  'Provision:Provision';
189:     const PROVISION_POLICIES            =  'Provision:Policies';
190:     const PROVISION_POLICY              =  'Provision:Policy';
191:     const PROVISION_POLICYTYPE          =  'Provision:PolicyType';
192:     const PROVISION_POLICYKEY           =  'Provision:PolicyKey';
193:     const PROVISION_DATA                =  'Provision:Data';
194:     const PROVISION_STATUS              =  'Provision:Status';
195:     const PROVISION_REMOTEWIPE          =  'Provision:RemoteWipe';
196:     const PROVISION_EASPROVISIONDOC     =  'Provision:EASProvisionDoc';
197: 
198:     /* Flags */
199:     const FLAG_NEWMESSAGE               = 'NewMessage';
200: 
201:     /* Folder types */
202:     const FOLDER_TYPE_OTHER             =  1;
203:     const FOLDER_TYPE_INBOX             =  2;
204:     const FOLDER_TYPE_DRAFTS            =  3;
205:     const FOLDER_TYPE_WASTEBASKET       =  4;
206:     const FOLDER_TYPE_SENTMAIL          =  5;
207:     const FOLDER_TYPE_OUTBOX            =  6;
208:     const FOLDER_TYPE_TASK              =  7;
209:     const FOLDER_TYPE_APPOINTMENT       =  8;
210:     const FOLDER_TYPE_CONTACT           =  9;
211:     const FOLDER_TYPE_NOTE              =  10;
212:     const FOLDER_TYPE_JOURNAL           =  11;
213:     const FOLDER_TYPE_USER_MAIL         =  12;
214:     const FOLDER_TYPE_USER_APPOINTMENT  =  13;
215:     const FOLDER_TYPE_USER_CONTACT      =  14;
216:     const FOLDER_TYPE_USER_TASK         =  15;
217:     const FOLDER_TYPE_USER_JOURNAL      =  16;
218:     const FOLDER_TYPE_USER_NOTE         =  17;
219:     const FOLDER_TYPE_UNKNOWN           =  18;
220:     const FOLDER_TYPE_RECIPIENT_CACHE   =  19;
221:     const FOLDER_TYPE_DUMMY             =  '__dummy.Folder.Id__';
222: 
223:     /** Origin of changes **/
224:     const CHANGE_ORIGIN_PIM             = 0;
225:     const CHANGE_ORIGIN_SERVER          = 1;
226:     const CHANGE_ORIGIN_NA              = 3;
227: 
228:     /** Remote wipe **/
229:     const RWSTATUS_NA                   = 0;
230:     const RWSTATUS_OK                   = 1;
231:     const RWSTATUS_PENDING              = 2;
232:     const RWSTATUS_WIPED                = 3;
233: 
234:     /** GAL **/
235:     const GAL_DISPLAYNAME               = 'GAL:DisplayName';
236:     const GAL_PHONE                     = 'GAL:Phone';
237:     const GAL_OFFICE                    = 'GAL:Office';
238:     const GAL_TITLE                     = 'GAL:Title';
239:     const GAL_COMPANY                   = 'GAL:Company';
240:     const GAL_ALIAS                     = 'GAL:Alias';
241:     const GAL_FIRSTNAME                 = 'GAL:FirstName';
242:     const GAL_LASTNAME                  = 'GAL:LastName';
243:     const GAL_HOMEPHONE                 = 'GAL:HomePhone';
244:     const GAL_MOBILEPHONE               = 'GAL:MobilePhone';
245:     const GAL_EMAILADDRESS              = 'GAL:EmailAddress';
246: 
247:     const PROVISIONING_LOOSE            = 'loose';
248:     /**
249:      * Logger
250:      *
251:      * @var Horde_Log_Logger
252:      */
253:     protected $_logger;
254: 
255:     /**
256:      * Provisioning support
257:      *
258:      * @var string (TODO _constant this)
259:      */
260:     protected $_provisioning;
261: 
262:     /**
263:      * Const'r
264:      *
265:      * @param Horde_ActiveSync_Driver $driver            The backend driver
266:      * @param Horde_ActiveSync_StateMachine $state       The state machine
267:      * @param Horde_ActiveSync_Wbxml_Decoder $decoder    The Wbxml decoder
268:      * @param Horde_ActiveSync_Wbxml_Endcodder $encdoer  The Wbxml encoder
269:      *
270:      * @return Horde_ActiveSync
271:      */
272:     public function __construct(Horde_ActiveSync_Driver_Base $driver,
273:                                 Horde_ActiveSync_Wbxml_Decoder $decoder,
274:                                 Horde_ActiveSync_Wbxml_Encoder $encoder,
275:                                 Horde_Controller_Request_Http $request)
276:     {
277:         // Backend driver
278:         $this->_driver = $driver;
279: 
280:         // Wbxml handlers
281:         $this->_encoder = $encoder;
282:         $this->_decoder = $decoder;
283: 
284:         // Read the initial Wbxml header
285:         $this->_decoder->readWbxmlHeader();
286: 
287:         // The http request
288:         $this->_request = $request;
289:     }
290: 
291:     /**
292:      * Setter for the logger
293:      *
294:      * @param Horde_Log_Logger $logger  The logger object.
295:      *
296:      * @return void
297:      */
298:     public function setLogger(Horde_Log_Logger $logger)
299:     {
300:         $this->_logger = $logger;
301:         $this->_encoder->setLogger($logger);
302:         $this->_decoder->setLogger($logger);
303:         $this->_driver->setLogger($logger);
304:     }
305: 
306:     /**
307:      * Setter for provisioning support
308:      *
309:      */
310:     public function setProvisioning($provision)
311:     {
312:         $this->_provisioning = $provision;
313:     }
314: 
315:     static public function provisioningRequired()
316:     {
317:         self::provisionHeader();
318:         self::activeSyncHeader();
319:         self::versionHeader();
320:         self::commandsHeader();
321:         header("Cache-Control: private");
322:     }
323: 
324:     /**
325:      * The heart of the server. Dispatch a request to the appropriate request
326:      * handler.
327:      *
328:      * @param string $cmd    The command we are requesting.
329:      * @param string $devId  The device id making the request.
330:      *
331:      * @return boolean
332:      */
333:     public function handleRequest($cmd, $devId)
334:     {
335:         $this->_logger->debug('['. $devId . '] ' . strtoupper($cmd) . ' request received for user ' . $this->_driver->getUser());
336: 
337:         // Don't bother with everything else if all we want are Options
338:         if ($cmd == 'Options') {
339:             self::activeSyncHeader();
340:             self::versionHeader();
341:             self::commandsHeader();
342:             return true;
343:         }
344: 
345:         $state = $this->_driver->getStateObject();
346: 
347:         if (is_null($devId)) {
348:             throw new Horde_ActiveSync_Exception('Device failed to send device id.');
349:         }
350:         // Does device exist AND does the user have an account on the device?
351:         if (!empty($devId) && !$state->deviceExists($devId, $this->_driver->getUser())) {
352:             // Device might exist, but with a new (additional) user account
353:             $device = new StdClass();
354:             if ($state->deviceExists($devId)) {
355:                 $d = $state->loadDeviceInfo($devId, '');;
356:             }
357:             $device->policykey = 0;
358:             $get = $this->_request->getGetVars();
359:             $device->userAgent = $this->_request->getHeader('User-Agent');
360:             $device->deviceType = !empty($get['DeviceType']) ? $get['DeviceType'] : '';
361:             $device->rwstatus = self::RWSTATUS_NA;
362:             $device->user = $this->_driver->getUser();
363:             $device->id = $devId;
364:             $state->setDeviceInfo($device);
365:         } else {
366:             $device = $state->loadDeviceInfo($devId, $this->_driver->getUser());
367:         }
368: 
369:         // Load the request handler to handle the request
370:         $class = 'Horde_ActiveSync_Request_' . basename($cmd);
371:         $version = $this->getProtocolVersion();
372:         if (class_exists($class)) {
373:             $request = new $class(
374:                 $this->_driver,
375:                 $this->_decoder,
376:                 $this->_encoder,
377:                 $this->_request,
378:                 $this,
379:                 $device,
380:                 $this->_provisioning);
381:             $request->setLogger($this->_logger);
382:             // @TODO: The headers really should be output in the Rpc layer.
383:             // Can't due that until Horde 5 because the InvalidRequest Exception
384:             // was introduced after release i.e., this is a BC break.
385:             try {
386:                 $result = $request->handle();
387:             } catch (Horde_ActiveSync_Exception_InvalidRequest $e) {
388:                 $this->_logger->err('Returning HTTP 400:' . $e->getMessage());
389:                 header('HTTP/1.1 400 Invalid Request ' . $e->getMessage());
390:             } catch (Horde_ActiveSync_Exception $e) {
391:                 $this->_logger->err('Returning HTTP 500:' . $e->getMessage());
392:                 header('HTTP/1.1 500');
393:             }
394:             $this->_driver->logOff();
395: 
396:             return $result;
397:         }
398: 
399:         // No idea what the client is talking about
400:         header('HTTP/1.1 400 Invalid Request ' . basename($cmd) . ' not supported.');
401:     }
402: 
403:     /**
404:      * Send the MS_Server-ActiveSync header
405:      * (This is the version Exchange 2003 advertises)
406:      *
407:      * @return void
408:      */
409:     static public function activeSyncHeader()
410:     {
411:         header("MS-Server-ActiveSync: 6.5.7638.1");
412:     }
413: 
414:     /**
415:      * Send the protocol versions header
416:      *
417:      * @return void
418:      */
419:     static public function versionHeader()
420:     {
421:         header("MS-ASProtocolVersions: 1.0,2.0,2.1,2.5");
422:     }
423: 
424:     /**
425:      * Send protocol commands header. This contains appropriate command for
426:      * ActiveSync version 2.5 support.
427:      *
428:      * @return void
429:      */
430:     static public function commandsHeader()
431:     {
432:         header("MS-ASProtocolCommands: Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteCollection,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,MoveItems,GetItemEstimate,MeetingResponse,ResolveRecipients,ValidateCert,Provision,Search,Ping");
433:     }
434: 
435:     /**
436:      * Send provision header
437:      *
438:      * @return void
439:      */
440:     static public function provisionHeader()
441:     {
442:         header("HTTP/1.1 449 Retry after sending a PROVISION command");
443:     }
444: 
445:     /**
446:      * Obtain the policy key header from the request.
447:      *
448:      * @return integer  The policy key or '0' if not set.
449:      */
450:     public function getPolicyKey()
451:     {
452:         $this->_policykey = $this->_request->getHeader('X-MS-PolicyKey');
453:         if (empty($this->_policykey)) {
454:             $this->_policykey = 0;
455:         }
456: 
457:         return $this->_policykey;
458:     }
459: 
460:     /**
461:      * Obtain the ActiveSync protocol version
462:      *
463:      * @return string
464:      */
465:     public function getProtocolVersion()
466:     {
467:         if (isset($this->_version)) {
468:             return $this->_version;
469:         }
470:         $this->_version = $this->_request->getHeader('MS-ASProtocolVersion');
471:         if (empty($this->_version)) {
472:             $this->_version = '1.0';
473:         }
474: 
475:         return $this->_version;
476:     }
477: 
478: }
API documentation generated by ApiGen