1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10:
11: class Horde_ActiveSync_Message_Appointment extends Horde_ActiveSync_Message_Base
12: {
13:
14: const POOMCAL_TIMEZONE = 'POOMCAL:Timezone';
15: const POOMCAL_ALLDAYEVENT = 'POOMCAL:AllDayEvent';
16: const POOMCAL_ATTENDEES = 'POOMCAL:Attendees';
17: const POOMCAL_ATTENDEE = 'POOMCAL:Attendee';
18: const POOMCAL_ATTENDEESTATUS = 'POOMCAL:AttendeeStatus';
19: const POOMCAL_ATTENDEETYPE = 'POOMCAL:AttendeeType';
20: const POOMCAL_EMAIL = 'POOMCAL:Email';
21: const POOMCAL_NAME = 'POOMCAL:Name';
22: const POOMCAL_BODY = 'POOMCAL:Body';
23: const POOMCAL_BODYTRUNCATED = 'POOMCAL:BodyTruncated';
24: const POOMCAL_BUSYSTATUS = 'POOMCAL:BusyStatus';
25: const POOMCAL_CATEGORIES = 'POOMCAL:Categories';
26: const POOMCAL_CATEGORY = 'POOMCAL:Category';
27: const POOMCAL_RTF = 'POOMCAL:Rtf';
28: const POOMCAL_DTSTAMP = 'POOMCAL:DtStamp';
29: const POOMCAL_ENDTIME = 'POOMCAL:EndTime';
30: const POOMCAL_EXCEPTION = 'POOMCAL:Exception';
31: const POOMCAL_EXCEPTIONS = 'POOMCAL:Exceptions';
32: const POOMCAL_DELETED = 'POOMCAL:Deleted';
33: const POOMCAL_EXCEPTIONSTARTTIME = 'POOMCAL:ExceptionStartTime';
34: const POOMCAL_LOCATION = 'POOMCAL:Location';
35: const POOMCAL_MEETINGSTATUS = 'POOMCAL:MeetingStatus';
36: const POOMCAL_ORGANIZEREMAIL = 'POOMCAL:OrganizerEmail';
37: const POOMCAL_ORGANIZERNAME = 'POOMCAL:OrganizerName';
38: const POOMCAL_RECURRENCE = 'POOMCAL:Recurrence';
39: const POOMCAL_TYPE = 'POOMCAL:Type';
40: const POOMCAL_UNTIL = 'POOMCAL:Until';
41: const POOMCAL_OCCURRENCES = 'POOMCAL:Occurrences';
42: const POOMCAL_INTERVAL = 'POOMCAL:Interval';
43: const POOMCAL_DAYOFWEEK = 'POOMCAL:DayOfWeek';
44: const POOMCAL_DAYOFMONTH = 'POOMCAL:DayOfMonth';
45: const POOMCAL_WEEKOFMONTH = 'POOMCAL:WeekOfMonth';
46: const POOMCAL_MONTHOFYEAR = 'POOMCAL:MonthOfYear';
47: const POOMCAL_REMINDER = 'POOMCAL:Reminder';
48: const POOMCAL_SENSITIVITY = 'POOMCAL:Sensitivity';
49: const POOMCAL_SUBJECT = 'POOMCAL:Subject';
50: const POOMCAL_STARTTIME = 'POOMCAL:StartTime';
51: const POOMCAL_UID = 'POOMCAL:UID';
52: const POOMCAL_RESPONSETYPE = 'POOMCAL:ResponseType';
53:
54:
55: const SENSITIVITY_NORMAL = 0;
56: const SENSITIVITY_PERSONAL = 1;
57: const SENSITIVITY_PRIVATE = 2;
58: const SENSITIVITY_CONFIDENTIAL = 3;
59:
60:
61: const BUSYSTATUS_FREE = 0;
62: const BUSYSTATUS_TENTATIVE = 1;
63: const BUSYSTATUS_BUSY = 2;
64: const BUSYSTATUS_OUT = 3;
65:
66:
67: const IS_ALL_DAY = 1;
68:
69:
70: const MEETING_NOT_MEETING = 0;
71: const MEETING_IS_MEETING = 1;
72: const MEETING_RECEIVED = 3;
73: const MEETING_CANCELLED = 5;
74: const MEETING_CANCELLED_RECEIVED = 7;
75:
76:
77: const RESPONSE_NONE = 0;
78: const RESPONSE_ORGANIZER = 1;
79: const RESPONSE_TENTATIVE = 2;
80: const RESPONSE_ACCEPTED = 3;
81: const RESPONSE_DECLINED = 4;
82: const RESPONSE_NORESPONSE = 5;
83:
84: 85: 86: 87:
88: public $exceptions = array();
89: public $attendees = array();
90: public $categories = array();
91: public $bodytruncated = 0;
92:
93: protected $_dayOfWeekMap = array(
94: Horde_Date::DATE_SUNDAY => Horde_Date::MASK_SUNDAY,
95: Horde_Date::DATE_MONDAY => Horde_Date::MASK_MONDAY,
96: Horde_Date::DATE_TUESDAY => Horde_Date::MASK_TUESDAY,
97: Horde_Date::DATE_WEDNESDAY => Horde_Date::MASK_WEDNESDAY,
98: Horde_Date::DATE_THURSDAY => Horde_Date::MASK_THURSDAY,
99: Horde_Date::DATE_FRIDAY => Horde_Date::MASK_FRIDAY,
100: Horde_Date::DATE_SATURDAY => Horde_Date::MASK_SATURDAY,
101: );
102:
103: protected $_mapping = array(
104: self::POOMCAL_TIMEZONE => array (self::KEY_ATTRIBUTE => 'timezone'),
105: self::POOMCAL_DTSTAMP => array (self::KEY_ATTRIBUTE => 'dtstamp', self::KEY_TYPE => self::TYPE_DATE),
106: self::POOMCAL_STARTTIME => array (self::KEY_ATTRIBUTE => 'starttime', self::KEY_TYPE => self::TYPE_DATE),
107: self::POOMCAL_SUBJECT => array (self::KEY_ATTRIBUTE => 'subject'),
108: self::POOMCAL_UID => array (self::KEY_ATTRIBUTE => 'uid', self::KEY_TYPE => self::TYPE_HEX),
109: self::POOMCAL_ORGANIZERNAME => array (self::KEY_ATTRIBUTE => 'organizername'),
110: self::POOMCAL_ORGANIZEREMAIL => array (self::KEY_ATTRIBUTE => 'organizeremail'),
111: self::POOMCAL_LOCATION => array (self::KEY_ATTRIBUTE => 'location'),
112: self::POOMCAL_ENDTIME => array (self::KEY_ATTRIBUTE => 'endtime', self::KEY_TYPE => self::TYPE_DATE),
113: self::POOMCAL_RECURRENCE => array (self::KEY_ATTRIBUTE => 'recurrence', self::KEY_TYPE => 'Horde_ActiveSync_Message_Recurrence'),
114: self::POOMCAL_SENSITIVITY => array (self::KEY_ATTRIBUTE => 'sensitivity'),
115: self::POOMCAL_BUSYSTATUS => array (self::KEY_ATTRIBUTE => 'busystatus'),
116: self::POOMCAL_ALLDAYEVENT => array (self::KEY_ATTRIBUTE => 'alldayevent'),
117: self::POOMCAL_REMINDER => array (self::KEY_ATTRIBUTE => 'reminder'),
118: self::POOMCAL_RTF => array (self::KEY_ATTRIBUTE => 'rtf'),
119: self::POOMCAL_MEETINGSTATUS => array (self::KEY_ATTRIBUTE => 'meetingstatus'),
120: self::POOMCAL_ATTENDEES => array (self::KEY_ATTRIBUTE => 'attendees', self::KEY_TYPE => 'Horde_ActiveSync_Message_Attendee', self::KEY_VALUES => self::POOMCAL_ATTENDEE),
121: self::POOMCAL_BODY => array (self::KEY_ATTRIBUTE => 'body'),
122: self::POOMCAL_BODYTRUNCATED => array (self::KEY_ATTRIBUTE => 'bodytruncated'),
123: self::POOMCAL_EXCEPTIONS => array (self::KEY_ATTRIBUTE => 'exceptions', self::KEY_TYPE => 'Horde_ActiveSync_Message_Exception', self::KEY_VALUES => self::POOMCAL_EXCEPTION),
124: self::POOMCAL_CATEGORIES => array (self::KEY_ATTRIBUTE => 'categories', self::KEY_VALUES => self::POOMCAL_CATEGORY),
125:
126: );
127:
128: protected $_properties = array(
129: 'timezone' => false,
130: 'dtstamp' => false,
131: 'starttime' => false,
132: 'subject' => false,
133: 'uid' => false,
134: 'organizername' => false,
135: 'organizeremail' => false,
136: 'location' => false,
137: 'endtime' => false,
138: 'recurrence' => false,
139: 'sensitivity' => false,
140: 'busystatus' => false,
141: 'alldayevent' => false,
142: 'reminder' => false,
143: 'rtf' => false,
144: 'meetingstatus' => false,
145: 'body' => false,
146: 'bodytruncated' => false,
147: );
148:
149: 150: 151: 152: 153: 154: 155: 156:
157: public function setTimezone($date)
158: {
159: if (!($date instanceof Horde_Date)) {
160: if (!is_string($date)) {
161: throw new InvalidArgumentException(
162: '$date must be an instance of Horde_Date or a valid timezone descriptor');
163: }
164: $date = new Horde_Date(time(), $date);
165: }
166: $offsets = Horde_ActiveSync_Timezone::getOffsetsFromDate($date);
167: $tz = Horde_ActiveSync_Timezone::getSyncTZFromOffsets($offsets);
168: $this->_properties['timezone'] = $tz;
169: }
170:
171: 172: 173: 174: 175:
176: public function getTimezone()
177: {
178: $parser = new Horde_ActiveSync_Timezone();
179: return $parser->getTimezone($this->timezone, date_default_timezone_get());
180: }
181:
182: 183: 184: 185: 186:
187: public function setDTStamp($date)
188: {
189: if (!($date instanceof Horde_Date)) {
190: $date = new Horde_Date($date);
191: }
192: $this->_properties['dtstamp'] = $date;
193: }
194:
195: 196: 197: 198: 199:
200: public function getDTStamp()
201: {
202: return $this->_getAttribute('dtstamp');
203: }
204:
205: 206: 207: 208: 209: 210: 211:
212: public function setDatetime(array $datetime = array())
213: {
214:
215: if (empty($datetime['start'])) {
216: throw new InvalidArgumentException('Missing the required start parameter');
217: }
218:
219:
220: $start = clone($datetime['start']);
221: if (!empty($datetime['end'])) {
222: $end = clone($datetime['end']);
223: } elseif (!empty($datetime['duration'])) {
224: $end = clone($start);
225: $end->sec += $datetime['duration'];
226: } else {
227: $end = clone($start);
228: }
229:
230:
231: if ($start->hour == 0 &&
232: $start->min == 0 &&
233: $start->sec == 0 &&
234: $end->hour == 23 &&
235: $end->min == 59) {
236:
237: $end = new Horde_Date(
238: array('year' => (int)$end->year,
239: 'month' => (int)$end->month,
240: 'mday' => (int)$end->mday + 1));
241: $this->_properties['alldayevent'] = self::IS_ALL_DAY;
242:
243: } elseif (!empty($datetime['allday'])) {
244: $this->_properties['alldayevent'] = self::IS_ALL_DAY;
245: $end = new Horde_Date(
246: array('year' => (int)$end->year,
247: 'month' => (int)$end->month,
248: 'mday' => (int)$end->mday));
249: }
250: $this->_properties['starttime'] = $start;
251: $this->_properties['endtime'] = $end;
252: }
253:
254: 255: 256: 257: 258:
259: public function getDatetime()
260: {
261: return array(
262: 'start' => $this->_properties['starttime'],
263: 'end' => $this->_properties['endtime'],
264: 'allday' => !empty($this->_properties['alldayevent']) ? true : false
265: );
266: }
267:
268: 269: 270: 271: 272:
273: public function setSubject($subject)
274: {
275: $this->_properties['subject'] = $subject;
276: }
277:
278: 279: 280: 281: 282:
283: public function getSubject()
284: {
285: return $this->_getAttribute('subject');
286: }
287:
288: 289: 290: 291: 292: 293: 294:
295: public function setUid($uid)
296: {
297: $this->_properties['uid'] = $uid;
298: }
299:
300: 301: 302: 303: 304:
305: public function getUid()
306: {
307: return $this->_getAttribute('uid');
308: }
309:
310: 311: 312: 313: 314: 315: 316:
317: public function setServerUID($uid)
318: {
319: $this->_properties['serveruid'] = $uid;
320: }
321:
322: 323: 324: 325: 326:
327: public function getServerUID()
328: {
329: return $this->_getAttribute('serveruid');
330: }
331:
332: 333: 334: 335: 336:
337: public function setOrganizer(array $organizer)
338: {
339: $this->_properties['organizername'] = !empty($organizer['name'])
340: ? $organizer['name']
341: : '';
342:
343: $this->_properties['organizeremail'] = !empty($organizer['email'])
344: ? $organizer['email']
345: : '';
346: }
347:
348: 349: 350: 351: 352:
353: public function getOrganizer()
354: {
355: return array('name' => $this->_getAttribute('organizername'),
356: 'email' => $this->_getAttribute('organizeremail'));
357: }
358:
359: 360: 361: 362: 363:
364: public function setLocation($location)
365: {
366: $this->_properties['location'] = $location;
367: }
368:
369: 370: 371: 372: 373:
374: public function getLocation()
375: {
376: return $this->_getAttribute('location');
377: }
378:
379: 380: 381: 382: 383:
384: public function setRecurrence(Horde_Date_Recurrence $recurrence)
385: {
386: $r = new Horde_ActiveSync_Message_Recurrence();
387:
388:
389: switch ($recurrence->recurType) {
390: case Horde_Date_Recurrence::RECUR_DAILY:
391: $r->type = Horde_ActiveSync_Message_Recurrence::TYPE_DAILY;
392: break;
393: case Horde_Date_Recurrence::RECUR_WEEKLY;
394: $r->type = Horde_ActiveSync_Message_Recurrence::TYPE_WEEKLY;
395: $r->dayofweek = $recurrence->getRecurOnDays();
396: break;
397: case Horde_Date_Recurrence::RECUR_MONTHLY_DATE:
398: $r->type = Horde_ActiveSync_Message_Recurrence::TYPE_MONTHLY;
399: break;
400: case Horde_Date_Recurrence::RECUR_MONTHLY_WEEKDAY;
401: $r->type = Horde_ActiveSync_Message_Recurrence::TYPE_MONTHLY_NTH;
402: $r->weekofmonth = ceil($recurrence->start->mday / 7);
403: $r->dayofweek = $this->_dayOfWeekMap[$recurrence->start->dayOfWeek()];
404: break;
405: case Horde_Date_Recurrence::RECUR_YEARLY_DATE:
406: $r->type = Horde_ActiveSync_Message_Recurrence::TYPE_YEARLY;
407: break;
408: case Horde_Date_Recurrence::RECUR_YEARLY_WEEKDAY:
409: $r->type = Horde_ActiveSync_Message_Recurrence::TYPE_YEARLYNTH;
410: $r->dayofweek = $this->_dayOfWeekMap[$recurrence->start->dayOfWeek()];
411: $r->weekofmonth = ceil($recurrence->start->mday / 7);
412: $r->monthofyear = $recurrence->start->month;
413: break;
414: }
415: if (!empty($recurrence->recurInterval)) {
416: $r->interval = $recurrence->recurInterval;
417: }
418:
419:
420: if ($recurrence->hasRecurCount()) {
421: $r->occurrences = $recurrence->getRecurCount();
422: } elseif ($recurrence->hasRecurEnd()) {
423: $r->until = $recurrence->getRecurEnd();
424: }
425:
426: $this->_properties['recurrence'] = $r;
427: }
428:
429: 430: 431: 432: 433: 434:
435: public function getRecurrence()
436: {
437: if (!$recurrence = $this->_getAttribute('recurrence')) {
438: return false;
439: }
440:
441: $d = clone($this->_getAttribute('starttime'));
442: $d->setTimezone($this->getTimezone());
443:
444: $rrule = new Horde_Date_Recurrence($d);
445:
446:
447: switch ($recurrence->type) {
448: case Horde_ActiveSync_Message_Recurrence::TYPE_DAILY:
449: $rrule->setRecurType(Horde_Date_Recurrence::RECUR_DAILY);
450: break;
451: case Horde_ActiveSync_Message_Recurrence::TYPE_WEEKLY:
452: $rrule->setRecurType(Horde_Date_Recurrence::RECUR_WEEKLY);
453: $rrule->setRecurOnDay($recurrence->dayofweek);
454: break;
455: case Horde_ActiveSync_Message_Recurrence::TYPE_MONTHLY:
456: $rrule->setRecurType(Horde_Date_Recurrence::RECUR_MONTHLY_DATE);
457: break;
458: case Horde_ActiveSync_Message_Recurrence::TYPE_MONTHLY_NTH:
459: $rrule->setRecurType(Horde_Date_Recurrence::RECUR_MONTHLY_WEEKDAY);
460: $rrule->setRecurOnDay($recurrence->dayofweek);
461: break;
462: case Horde_ActiveSync_Message_Recurrence::TYPE_YEARLY:
463: $rrule->setRecurType(Horde_Date_Recurrence::RECUR_YEARLY_DATE);
464: break;
465: case Horde_ActiveSync_Message_Recurrence::TYPE_YEARLYNTH:
466: $rrule->setRecurType(Horde_Date_Recurrence::RECUR_YEARLY_WEEKDAY);
467: $rrule->setRecurOnDay($recurrence->dayofweek);
468: break;
469: }
470:
471: if ($rcnt = $recurrence->occurrences) {
472: $rrule->setRecurCount($rcnt);
473: }
474: if ($runtil = $recurrence->until) {
475: $rrule->setRecurEnd(new Horde_Date($runtil));
476: }
477: if ($interval = $recurrence->interval) {
478: $rrule->setRecurInterval($interval);
479: }
480:
481: return $rrule;
482: }
483:
484: 485: 486: 487: 488:
489: public function addException(Horde_ActiveSync_Message_Exception $exception)
490: {
491: $this->exceptions[] = $exception;
492: }
493:
494: 495: 496: 497:
498: public function getExceptions()
499: {
500: return $this->exceptions;
501: }
502:
503: 504: 505: 506: 507: 508: 509: 510:
511: public function setSensitivity($sensitivity)
512: {
513: $this->_properties['sensitivity'] = $sensitivity;
514: }
515:
516: 517: 518: 519: 520:
521: public function getSensitivity()
522: {
523: return $this->_getAttribute('sensitivity');
524: }
525:
526: 527: 528: 529: 530:
531: public function setBusyStatus($busy)
532: {
533: $this->_properties['busystatus'] = $busy;
534: }
535:
536: 537: 538: 539: 540:
541: public function getBusyStatus()
542: {
543: return $this->_getAttribute('busystatus');
544: }
545:
546: 547: 548: 549: 550: 551:
552: public function setResponseType($response)
553: {
554: $this->_properties['responsetype'] = $response;
555: }
556:
557: 558: 559: 560: 561:
562: public function getResponseType()
563: {
564: return $this->_getAttribute('responsetype');
565: }
566:
567: 568: 569: 570: 571: 572:
573: public function setReminder($minutes)
574: {
575: $this->_properties['reminder'] = (int)$minutes;
576: }
577:
578: 579: 580: 581:
582: public function getReminder()
583: {
584: return $this->_getAttribute('reminder');
585: }
586:
587: 588: 589: 590: 591: 592:
593: public function setMeetingStatus($status)
594: {
595:
596: $this->_properties['meetingstatus'] = $status;
597: }
598:
599: 600: 601: 602:
603: public function getMeetingStatus()
604: {
605: return $this->_getAttribute('meetingstatus', self::MEETING_NOT_MEETING);
606: }
607:
608: 609: 610: 611: 612:
613: public function addAttendee($attendee)
614: {
615:
616: $this->attendees[] = $attendee;
617: }
618:
619: 620: 621: 622: 623:
624: public function getAttendees()
625: {
626: return $this->attendees;
627: }
628:
629: 630: 631: 632: 633:
634: public function setBody($body)
635: {
636: $this->_properties['body'] = $body;
637: }
638:
639: 640: 641: 642: 643:
644: public function getBody()
645: {
646: return $this->_getAttribute('body');
647: }
648:
649: 650: 651: 652: 653:
654: public function addCategory($category)
655: {
656: $this->categories[] = $category;
657: }
658:
659: public function getCategories()
660: {
661: return $this->categories;
662: }
663:
664: 665: 666: 667: 668:
669: public function getClass()
670: {
671: return 'Calendar';
672: }
673:
674: }
675: