Overview

Packages

  • ActiveSync
  • None

Classes

  • Horde_ActiveSync_Message_Appointment
  • Horde_ActiveSync_Message_Attendee
  • Horde_ActiveSync_Message_Contact
  • Horde_ActiveSync_Message_Exception
  • Horde_ActiveSync_Message_Folder
  • Horde_ActiveSync_Message_Recurrence
  • Horde_ActiveSync_Message_Task
  • Horde_ActiveSync_State_Base
  • Horde_ActiveSync_State_History
  • Horde_ActiveSync_Timezone
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Horde_ActiveSync_Message_Appointment class represents a single ActiveSync
  4:  * Appointment object. Responsible for mapping all fields to and from wbxml.
  5:  *
  6:  * Copyright 2010-2012 Horde LLC (http://www.horde.org/)
  7:  *
  8:  * @author Michael J. Rubinsky <mrubinsk@horde.org>
  9:  * @package ActiveSync
 10:  */
 11: class Horde_ActiveSync_Message_Appointment extends Horde_ActiveSync_Message_Base
 12: {
 13:     /* POOMCAL Tag Constants */
 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:     /* Sensitivity */
 55:     const SENSITIVITY_NORMAL         = 0;
 56:     const SENSITIVITY_PERSONAL       = 1;
 57:     const SENSITIVITY_PRIVATE        = 2;
 58:     const SENSITIVITY_CONFIDENTIAL   = 3;
 59: 
 60:     /* Busy status */
 61:     const BUSYSTATUS_FREE            = 0;
 62:     const BUSYSTATUS_TENTATIVE       = 1;
 63:     const BUSYSTATUS_BUSY            = 2;
 64:     const BUSYSTATUS_OUT             = 3;
 65: 
 66:     /* All day meeting */
 67:     const IS_ALL_DAY                 = 1;
 68: 
 69:     /* Meeting status */
 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:     /* Response status */
 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:      * Workarounds for PHP < 5.2.6 not being able to return an array by reference
 86:      * from a __get() property.
 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:         //self::POOMCAL_RESPONSETYPE => array(self::KEY_ATTRIBUTE => 'responsetype'),
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:      * Set the timezone
151:      *
152:      * @param mixed $date  Either a Horde_Date or timezone descriptor such as
153:      *                     America/New_York etc...
154:      *
155:      * @throws InvalidArgumentException
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:      * Get the event's timezone
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:      * Set the appointment's modify timestamp
184:      *
185:      * @param mixed $timestamp  Horde_Date or a unix timestamp
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:      * Get the appointment's dtimestamp
197:      *
198:      * @return integer  timestamp
199:      */
200:     public function getDTStamp()
201:     {
202:         return $this->_getAttribute('dtstamp');
203:     }
204: 
205:     /**
206:      * Set the appointment time/duration.
207:      *
208:      * @param array $timestamp 'start', 'end' or 'duration' (in seconds) or 'allday'
209:      *
210:      * @throws InvalidArgumentException
211:      */
212:     public function setDatetime(array $datetime = array())
213:     {
214:         // Start date is always required
215:         if (empty($datetime['start'])) {
216:             throw new InvalidArgumentException('Missing the required start parameter');
217:         }
218: 
219:         /* Get or calculate start and end time in local tz */
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:         // Is this an all day event?
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:      * Get the appointment's time data
256:      *
257:      * @return array containing 'start', 'end', 'allday'
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:      * Set the appointment subject field.
270:      *
271:      * @param string $subject   UTF-8 string
272:      */
273:     public function setSubject($subject)
274:     {
275:         $this->_properties['subject'] = $subject;
276:     }
277: 
278:     /**
279:      * Get the subject
280:      *
281:      * @return string  The UTF-8 subject string
282:      */
283:     public function getSubject()
284:     {
285:         return $this->_getAttribute('subject');
286:     }
287: 
288:     /**
289:      * Set the appointment uid. Note that this is the PIM's UID value, and not
290:      * the value that the server uses for the UID. ActiveSync messages do not
291:      * include any server uid value as part of the message natively.
292:      *
293:      * @param string $uid  The server's uid for this appointment
294:      */
295:     public function setUid($uid)
296:     {
297:         $this->_properties['uid'] = $uid;
298:     }
299: 
300:     /**
301:      * Get the PIM's UID. See not above regarding server UIDs.
302:      *
303:      * @return string
304:      */
305:     public function getUid()
306:     {
307:         return $this->_getAttribute('uid');
308:     }
309: 
310:     /**
311:      * Because the PIM doesn't pass the server uid as part of the message,
312:      * we need to add it manually so the backend can have access to it
313:      * when changing this object.
314:      *
315:      * @param string $uid  The server UID
316:      */
317:     public function setServerUID($uid)
318:     {
319:         $this->_properties['serveruid'] = $uid;
320:     }
321: 
322:     /**
323:      * Obtain the server UID. See note above.
324:      *
325:      * @return string
326:      */
327:     public function getServerUID()
328:     {
329:         return $this->_getAttribute('serveruid');
330:     }
331: 
332:     /**
333:      * Set the organizer name and/or email
334:      *
335:      * @param array  'name' and 'email' for this appointment organizer.
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:      * Get the details for the appointment organizer
350:      *
351:      * @return array with 'name' and 'email' values
352:      */
353:     public function getOrganizer()
354:     {
355:         return array('name' => $this->_getAttribute('organizername'),
356:                      'email' => $this->_getAttribute('organizeremail'));
357:     }
358: 
359:     /**
360:      * Set appointment location field.
361:      *
362:      * @param string $location
363:      */
364:     public function setLocation($location)
365:     {
366:         $this->_properties['location'] = $location;
367:     }
368: 
369:     /**
370:      * Get the location field
371:      *
372:      * @return string
373:      */
374:     public function getLocation()
375:     {
376:         return $this->_getAttribute('location');
377:     }
378: 
379:     /**
380:      * Set recurrence information for this appointment
381:      *
382:      * @param Horde_Date_Recurrence $recurrence
383:      */
384:     public function setRecurrence(Horde_Date_Recurrence $recurrence)
385:     {
386:         $r = new Horde_ActiveSync_Message_Recurrence();
387: 
388:         /* Map the type fields */
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:         /* AS messages can only have one or the other (or none), not both */
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:      * Obtain a recurrence object. Note this returns a Horde_Date_Recurrence
431:      * object, not Horde_ActiveSync_Message_Recurrence.
432:      *
433:      * @return Horde_Date_Recurrence
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:         /* Map MS AS type field to Horde_Date_Recurrence types */
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:      * Add a recurrence exception
486:      *
487:      * @param Horde_ActiveSync_Message_Exception $exception
488:      */
489:     public function addException(Horde_ActiveSync_Message_Exception $exception)
490:     {
491:         $this->exceptions[] = $exception;
492:     }
493: 
494:     /**
495:      *
496:      * @return array  An array of Horde_ActiveSync_Message_Exception objects
497:      */
498:     public function getExceptions()
499:     {
500:         return $this->exceptions;
501:     }
502: 
503:     /**
504:      * Set the sensitivity level for this appointment.
505:      *
506:      * Should be one of:
507:      *   normal, personal, private, confidential
508:      *
509:      * @param integer $sensitivity  The SENSITIVITY constant
510:      */
511:     public function setSensitivity($sensitivity)
512:     {
513:         $this->_properties['sensitivity'] = $sensitivity;
514:     }
515: 
516:     /**
517:      * Return the sensitivity setting for this appointment
518:      *
519:      * @return integer  The SENSITIVITY constant
520:      */
521:     public function getSensitivity()
522:     {
523:         return $this->_getAttribute('sensitivity');
524:     }
525: 
526:     /**
527:      * Sets the busy status for this appointment
528:      *
529:      * @param integer  $busy  The BUSYSTATUS constant
530:      */
531:     public function setBusyStatus($busy)
532:     {
533:         $this->_properties['busystatus'] = $busy;
534:     }
535: 
536:     /**
537:      * Return the busy status for this appointment.
538:      *
539:      * @return integer The BUSYSTATUS constant
540:      */
541:     public function getBusyStatus()
542:     {
543:         return $this->_getAttribute('busystatus');
544:     }
545: 
546:     /**
547:      * Set user response type. Should be one of:
548:      *   none, organizer, tentative, accepted, declined
549:      *
550:      * @param integer $response  The response type constant
551:      */
552:     public function setResponseType($response)
553:     {
554:         $this->_properties['responsetype'] = $response;
555:     }
556: 
557:     /**
558:      * Get response type
559:      *
560:      * @return integer  The responsetype constant
561:      */
562:     public function getResponseType()
563:     {
564:         return $this->_getAttribute('responsetype');
565:     }
566: 
567:     /**
568:      * Set reminder for this appointment.
569:      *
570:      * @param integer $minutes  The number of minutes before appintment to
571:      *                          trigger a reminder.
572:      */
573:     public function setReminder($minutes)
574:     {
575:         $this->_properties['reminder'] = (int)$minutes;
576:     }
577: 
578:     /**
579:      *
580:      * @return integer  Number of minutes before appointment for notifications.
581:      */
582:     public function getReminder()
583:     {
584:         return $this->_getAttribute('reminder');
585:     }
586: 
587:     /**
588:      * Set the status for this appointment. Should be one of:
589:      *   none, meeting, received, canceled, canceledreceived.
590:      *
591:      * @param integer $status  A MEETING_* constant
592:      */
593:     public function setMeetingStatus($status)
594:     {
595: 
596:         $this->_properties['meetingstatus'] = $status;
597:     }
598: 
599:     /**
600:      *
601:      * @return integer A MEETING_* constant
602:      */
603:     public function getMeetingStatus()
604:     {
605:         return $this->_getAttribute('meetingstatus', self::MEETING_NOT_MEETING);
606:     }
607: 
608:     /**
609:      * Add an attendee to this appointment
610:      *
611:      * @param array $attendee   'name', 'email' for each attendee
612:      */
613:     public function addAttendee($attendee)
614:     {
615:         /* Both email and name are REQUIRED if setting an attendee */
616:         $this->attendees[] = $attendee;
617:     }
618: 
619:     /**
620:      * Get a list of this event's attendees
621:      *
622:      * @return array  An array of 'name' and 'email' hashes
623:      */
624:     public function getAttendees()
625:     {
626:         return $this->attendees;
627:     }
628: 
629:     /**
630:      * Set the appointment's body
631:      *
632:      * @param string $body  UTF-8 encoded string
633:      */
634:     public function setBody($body)
635:     {
636:         $this->_properties['body'] = $body;
637:     }
638: 
639:     /**
640:      * Get the appointment's body
641:      *
642:      * @return string  UTF-8 encoded string
643:      */
644:     public function getBody()
645:     {
646:         return $this->_getAttribute('body');
647:     }
648: 
649:     /**
650:      * Add a category to the appointment
651:      *
652:      * @param string $category
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:      * Return the collection class name the object is for.
666:      *
667:      * @return string
668:      */
669:     public function getClass()
670:     {
671:         return 'Calendar';
672:     }
673: 
674: }
675: 
API documentation generated by ApiGen