1*a1a3b679SAndreas Boehler<?php 2*a1a3b679SAndreas Boehler 3*a1a3b679SAndreas Boehlernamespace Sabre\CalDAV\Xml\Notification; 4*a1a3b679SAndreas Boehler 5*a1a3b679SAndreas Boehleruse Sabre\Xml\Writer; 6*a1a3b679SAndreas Boehleruse Sabre\CalDAV\SharingPlugin as SharingPlugin; 7*a1a3b679SAndreas Boehleruse Sabre\CalDAV; 8*a1a3b679SAndreas Boehler 9*a1a3b679SAndreas Boehler/** 10*a1a3b679SAndreas Boehler * This class represents the cs:invite-notification notification element. 11*a1a3b679SAndreas Boehler * 12*a1a3b679SAndreas Boehler * This element is defined here: 13*a1a3b679SAndreas Boehler * http://svn.calendarserver.org/repository/calendarserver/CalendarServer/trunk/doc/Extensions/caldav-sharing.txt 14*a1a3b679SAndreas Boehler * 15*a1a3b679SAndreas Boehler * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/). 16*a1a3b679SAndreas Boehler * @author Evert Pot (http://evertpot.com/) 17*a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License 18*a1a3b679SAndreas Boehler */ 19*a1a3b679SAndreas Boehlerclass Invite implements NotificationInterface { 20*a1a3b679SAndreas Boehler 21*a1a3b679SAndreas Boehler /** 22*a1a3b679SAndreas Boehler * A unique id for the message 23*a1a3b679SAndreas Boehler * 24*a1a3b679SAndreas Boehler * @var string 25*a1a3b679SAndreas Boehler */ 26*a1a3b679SAndreas Boehler protected $id; 27*a1a3b679SAndreas Boehler 28*a1a3b679SAndreas Boehler /** 29*a1a3b679SAndreas Boehler * Timestamp of the notification 30*a1a3b679SAndreas Boehler * 31*a1a3b679SAndreas Boehler * @var DateTime 32*a1a3b679SAndreas Boehler */ 33*a1a3b679SAndreas Boehler protected $dtStamp; 34*a1a3b679SAndreas Boehler 35*a1a3b679SAndreas Boehler /** 36*a1a3b679SAndreas Boehler * A url to the recipient of the notification. This can be an email 37*a1a3b679SAndreas Boehler * address (mailto:), or a principal url. 38*a1a3b679SAndreas Boehler * 39*a1a3b679SAndreas Boehler * @var string 40*a1a3b679SAndreas Boehler */ 41*a1a3b679SAndreas Boehler protected $href; 42*a1a3b679SAndreas Boehler 43*a1a3b679SAndreas Boehler /** 44*a1a3b679SAndreas Boehler * The type of message, see the SharingPlugin::STATUS_* constants. 45*a1a3b679SAndreas Boehler * 46*a1a3b679SAndreas Boehler * @var int 47*a1a3b679SAndreas Boehler */ 48*a1a3b679SAndreas Boehler protected $type; 49*a1a3b679SAndreas Boehler 50*a1a3b679SAndreas Boehler /** 51*a1a3b679SAndreas Boehler * True if access to a calendar is read-only. 52*a1a3b679SAndreas Boehler * 53*a1a3b679SAndreas Boehler * @var bool 54*a1a3b679SAndreas Boehler */ 55*a1a3b679SAndreas Boehler protected $readOnly; 56*a1a3b679SAndreas Boehler 57*a1a3b679SAndreas Boehler /** 58*a1a3b679SAndreas Boehler * A url to the shared calendar. 59*a1a3b679SAndreas Boehler * 60*a1a3b679SAndreas Boehler * @var string 61*a1a3b679SAndreas Boehler */ 62*a1a3b679SAndreas Boehler protected $hostUrl; 63*a1a3b679SAndreas Boehler 64*a1a3b679SAndreas Boehler /** 65*a1a3b679SAndreas Boehler * Url to the sharer of the calendar 66*a1a3b679SAndreas Boehler * 67*a1a3b679SAndreas Boehler * @var string 68*a1a3b679SAndreas Boehler */ 69*a1a3b679SAndreas Boehler protected $organizer; 70*a1a3b679SAndreas Boehler 71*a1a3b679SAndreas Boehler /** 72*a1a3b679SAndreas Boehler * The name of the sharer. 73*a1a3b679SAndreas Boehler * 74*a1a3b679SAndreas Boehler * @var string 75*a1a3b679SAndreas Boehler */ 76*a1a3b679SAndreas Boehler protected $commonName; 77*a1a3b679SAndreas Boehler 78*a1a3b679SAndreas Boehler /** 79*a1a3b679SAndreas Boehler * The name of the sharer. 80*a1a3b679SAndreas Boehler * 81*a1a3b679SAndreas Boehler * @var string 82*a1a3b679SAndreas Boehler */ 83*a1a3b679SAndreas Boehler protected $firstName; 84*a1a3b679SAndreas Boehler 85*a1a3b679SAndreas Boehler /** 86*a1a3b679SAndreas Boehler * The name of the sharer. 87*a1a3b679SAndreas Boehler * 88*a1a3b679SAndreas Boehler * @var string 89*a1a3b679SAndreas Boehler */ 90*a1a3b679SAndreas Boehler protected $lastName; 91*a1a3b679SAndreas Boehler 92*a1a3b679SAndreas Boehler /** 93*a1a3b679SAndreas Boehler * A description of the share request 94*a1a3b679SAndreas Boehler * 95*a1a3b679SAndreas Boehler * @var string 96*a1a3b679SAndreas Boehler */ 97*a1a3b679SAndreas Boehler protected $summary; 98*a1a3b679SAndreas Boehler 99*a1a3b679SAndreas Boehler /** 100*a1a3b679SAndreas Boehler * The Etag for the notification 101*a1a3b679SAndreas Boehler * 102*a1a3b679SAndreas Boehler * @var string 103*a1a3b679SAndreas Boehler */ 104*a1a3b679SAndreas Boehler protected $etag; 105*a1a3b679SAndreas Boehler 106*a1a3b679SAndreas Boehler /** 107*a1a3b679SAndreas Boehler * The list of supported components 108*a1a3b679SAndreas Boehler * 109*a1a3b679SAndreas Boehler * @var Sabre\CalDAV\Property\SupportedCalendarComponentSet 110*a1a3b679SAndreas Boehler */ 111*a1a3b679SAndreas Boehler protected $supportedComponents; 112*a1a3b679SAndreas Boehler 113*a1a3b679SAndreas Boehler /** 114*a1a3b679SAndreas Boehler * Creates the Invite notification. 115*a1a3b679SAndreas Boehler * 116*a1a3b679SAndreas Boehler * This constructor receives an array with the following elements: 117*a1a3b679SAndreas Boehler * 118*a1a3b679SAndreas Boehler * * id - A unique id 119*a1a3b679SAndreas Boehler * * etag - The etag 120*a1a3b679SAndreas Boehler * * dtStamp - A DateTime object with a timestamp for the notification. 121*a1a3b679SAndreas Boehler * * type - The type of notification, see SharingPlugin::STATUS_* 122*a1a3b679SAndreas Boehler * constants for details. 123*a1a3b679SAndreas Boehler * * readOnly - This must be set to true, if this is an invite for 124*a1a3b679SAndreas Boehler * read-only access to a calendar. 125*a1a3b679SAndreas Boehler * * hostUrl - A url to the shared calendar. 126*a1a3b679SAndreas Boehler * * organizer - Url to the sharer principal. 127*a1a3b679SAndreas Boehler * * commonName - The real name of the sharer (optional). 128*a1a3b679SAndreas Boehler * * firstName - The first name of the sharer (optional). 129*a1a3b679SAndreas Boehler * * lastName - The last name of the sharer (optional). 130*a1a3b679SAndreas Boehler * * summary - Description of the share, can be the same as the 131*a1a3b679SAndreas Boehler * calendar, but may also be modified (optional). 132*a1a3b679SAndreas Boehler * * supportedComponents - An instance of 133*a1a3b679SAndreas Boehler * Sabre\CalDAV\Property\SupportedCalendarComponentSet. 134*a1a3b679SAndreas Boehler * This allows the client to determine which components 135*a1a3b679SAndreas Boehler * will be supported in the shared calendar. This is 136*a1a3b679SAndreas Boehler * also optional. 137*a1a3b679SAndreas Boehler * 138*a1a3b679SAndreas Boehler * @param array $values All the options 139*a1a3b679SAndreas Boehler */ 140*a1a3b679SAndreas Boehler function __construct(array $values) { 141*a1a3b679SAndreas Boehler 142*a1a3b679SAndreas Boehler $required = [ 143*a1a3b679SAndreas Boehler 'id', 144*a1a3b679SAndreas Boehler 'etag', 145*a1a3b679SAndreas Boehler 'href', 146*a1a3b679SAndreas Boehler 'dtStamp', 147*a1a3b679SAndreas Boehler 'type', 148*a1a3b679SAndreas Boehler 'readOnly', 149*a1a3b679SAndreas Boehler 'hostUrl', 150*a1a3b679SAndreas Boehler 'organizer', 151*a1a3b679SAndreas Boehler ]; 152*a1a3b679SAndreas Boehler foreach ($required as $item) { 153*a1a3b679SAndreas Boehler if (!isset($values[$item])) { 154*a1a3b679SAndreas Boehler throw new \InvalidArgumentException($item . ' is a required constructor option'); 155*a1a3b679SAndreas Boehler } 156*a1a3b679SAndreas Boehler } 157*a1a3b679SAndreas Boehler 158*a1a3b679SAndreas Boehler foreach ($values as $key => $value) { 159*a1a3b679SAndreas Boehler if (!property_exists($this, $key)) { 160*a1a3b679SAndreas Boehler throw new \InvalidArgumentException('Unknown option: ' . $key); 161*a1a3b679SAndreas Boehler } 162*a1a3b679SAndreas Boehler $this->$key = $value; 163*a1a3b679SAndreas Boehler } 164*a1a3b679SAndreas Boehler 165*a1a3b679SAndreas Boehler } 166*a1a3b679SAndreas Boehler 167*a1a3b679SAndreas Boehler /** 168*a1a3b679SAndreas Boehler * The xmlSerialize metod is called during xml writing. 169*a1a3b679SAndreas Boehler * 170*a1a3b679SAndreas Boehler * Use the $writer argument to write its own xml serialization. 171*a1a3b679SAndreas Boehler * 172*a1a3b679SAndreas Boehler * An important note: do _not_ create a parent element. Any element 173*a1a3b679SAndreas Boehler * implementing XmlSerializble should only ever write what's considered 174*a1a3b679SAndreas Boehler * its 'inner xml'. 175*a1a3b679SAndreas Boehler * 176*a1a3b679SAndreas Boehler * The parent of the current element is responsible for writing a 177*a1a3b679SAndreas Boehler * containing element. 178*a1a3b679SAndreas Boehler * 179*a1a3b679SAndreas Boehler * This allows serializers to be re-used for different element names. 180*a1a3b679SAndreas Boehler * 181*a1a3b679SAndreas Boehler * If you are opening new elements, you must also close them again. 182*a1a3b679SAndreas Boehler * 183*a1a3b679SAndreas Boehler * @param Writer $writer 184*a1a3b679SAndreas Boehler * @return void 185*a1a3b679SAndreas Boehler */ 186*a1a3b679SAndreas Boehler function xmlSerialize(Writer $writer) { 187*a1a3b679SAndreas Boehler 188*a1a3b679SAndreas Boehler $writer->writeElement('{' . CalDAV\Plugin::NS_CALENDARSERVER . '}invite-notification'); 189*a1a3b679SAndreas Boehler 190*a1a3b679SAndreas Boehler } 191*a1a3b679SAndreas Boehler 192*a1a3b679SAndreas Boehler /** 193*a1a3b679SAndreas Boehler * This method serializes the entire notification, as it is used in the 194*a1a3b679SAndreas Boehler * response body. 195*a1a3b679SAndreas Boehler * 196*a1a3b679SAndreas Boehler * @param Writer $writer 197*a1a3b679SAndreas Boehler * @return void 198*a1a3b679SAndreas Boehler */ 199*a1a3b679SAndreas Boehler function xmlSerializeFull(Writer $writer) { 200*a1a3b679SAndreas Boehler 201*a1a3b679SAndreas Boehler $cs = '{' . CalDAV\Plugin::NS_CALENDARSERVER . '}'; 202*a1a3b679SAndreas Boehler 203*a1a3b679SAndreas Boehler $this->dtStamp->setTimezone(new \DateTimezone('GMT')); 204*a1a3b679SAndreas Boehler $writer->writeElement($cs . 'dtstamp', $this->dtStamp->format('Ymd\\THis\\Z')); 205*a1a3b679SAndreas Boehler 206*a1a3b679SAndreas Boehler $writer->startElement($cs . 'invite-notification'); 207*a1a3b679SAndreas Boehler 208*a1a3b679SAndreas Boehler $writer->writeElement($cs . 'uid', $this->id); 209*a1a3b679SAndreas Boehler $writer->writeElement('{DAV:}href', $this->href); 210*a1a3b679SAndreas Boehler 211*a1a3b679SAndreas Boehler switch ($this->type) { 212*a1a3b679SAndreas Boehler 213*a1a3b679SAndreas Boehler case SharingPlugin::STATUS_ACCEPTED : 214*a1a3b679SAndreas Boehler $writer->writeElement($cs . 'invite-accepted'); 215*a1a3b679SAndreas Boehler break; 216*a1a3b679SAndreas Boehler case SharingPlugin::STATUS_DECLINED : 217*a1a3b679SAndreas Boehler $writer->writeElement($cs . 'invite-declined'); 218*a1a3b679SAndreas Boehler break; 219*a1a3b679SAndreas Boehler case SharingPlugin::STATUS_DELETED : 220*a1a3b679SAndreas Boehler $writer->writeElement($cs . 'invite-deleted'); 221*a1a3b679SAndreas Boehler break; 222*a1a3b679SAndreas Boehler case SharingPlugin::STATUS_NORESPONSE : 223*a1a3b679SAndreas Boehler $writer->writeElement($cs . 'invite-noresponse'); 224*a1a3b679SAndreas Boehler break; 225*a1a3b679SAndreas Boehler 226*a1a3b679SAndreas Boehler } 227*a1a3b679SAndreas Boehler 228*a1a3b679SAndreas Boehler $writer->writeElement($cs . 'hosturl', [ 229*a1a3b679SAndreas Boehler '{DAV:}href' => $writer->contextUri . $this->hostUrl 230*a1a3b679SAndreas Boehler ]); 231*a1a3b679SAndreas Boehler 232*a1a3b679SAndreas Boehler if ($this->summary) { 233*a1a3b679SAndreas Boehler $writer->writeElement($cs . 'summary', $this->summary); 234*a1a3b679SAndreas Boehler } 235*a1a3b679SAndreas Boehler 236*a1a3b679SAndreas Boehler $writer->startElement($cs . 'access'); 237*a1a3b679SAndreas Boehler if ($this->readOnly) { 238*a1a3b679SAndreas Boehler $writer->writeElement($cs . 'read'); 239*a1a3b679SAndreas Boehler } else { 240*a1a3b679SAndreas Boehler $writer->writeElement($cs . 'read-write'); 241*a1a3b679SAndreas Boehler } 242*a1a3b679SAndreas Boehler $writer->endElement(); // access 243*a1a3b679SAndreas Boehler 244*a1a3b679SAndreas Boehler $writer->startElement($cs . 'organizer'); 245*a1a3b679SAndreas Boehler // If the organizer contains a 'mailto:' part, it means it should be 246*a1a3b679SAndreas Boehler // treated as absolute. 247*a1a3b679SAndreas Boehler if (strtolower(substr($this->organizer, 0, 7)) === 'mailto:') { 248*a1a3b679SAndreas Boehler $writer->writeElement('{DAV:}href', $this->organizer); 249*a1a3b679SAndreas Boehler } else { 250*a1a3b679SAndreas Boehler $writer->writeElement('{DAV:}href', $writer->contextUri . $this->organizer); 251*a1a3b679SAndreas Boehler } 252*a1a3b679SAndreas Boehler if ($this->commonName) { 253*a1a3b679SAndreas Boehler $writer->writeElement($cs . 'common-name', $this->commonName); 254*a1a3b679SAndreas Boehler } 255*a1a3b679SAndreas Boehler if ($this->firstName) { 256*a1a3b679SAndreas Boehler $writer->writeElement($cs . 'first-name', $this->firstName); 257*a1a3b679SAndreas Boehler } 258*a1a3b679SAndreas Boehler if ($this->lastName) { 259*a1a3b679SAndreas Boehler $writer->writeElement($cs . 'last-name', $this->lastName); 260*a1a3b679SAndreas Boehler } 261*a1a3b679SAndreas Boehler $writer->endElement(); // organizer 262*a1a3b679SAndreas Boehler 263*a1a3b679SAndreas Boehler if ($this->commonName) { 264*a1a3b679SAndreas Boehler $writer->writeElement($cs . 'organizer-cn', $this->commonName); 265*a1a3b679SAndreas Boehler } 266*a1a3b679SAndreas Boehler if ($this->firstName) { 267*a1a3b679SAndreas Boehler $writer->writeElement($cs . 'organizer-first', $this->firstName); 268*a1a3b679SAndreas Boehler } 269*a1a3b679SAndreas Boehler if ($this->lastName) { 270*a1a3b679SAndreas Boehler $writer->writeElement($cs . 'organizer-last', $this->lastName); 271*a1a3b679SAndreas Boehler } 272*a1a3b679SAndreas Boehler if ($this->supportedComponents) { 273*a1a3b679SAndreas Boehler $writer->writeElement('{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set', $this->supportedComponents); 274*a1a3b679SAndreas Boehler } 275*a1a3b679SAndreas Boehler 276*a1a3b679SAndreas Boehler $writer->endElement(); // invite-notification 277*a1a3b679SAndreas Boehler 278*a1a3b679SAndreas Boehler } 279*a1a3b679SAndreas Boehler 280*a1a3b679SAndreas Boehler /** 281*a1a3b679SAndreas Boehler * Returns a unique id for this notification 282*a1a3b679SAndreas Boehler * 283*a1a3b679SAndreas Boehler * This is just the base url. This should generally be some kind of unique 284*a1a3b679SAndreas Boehler * id. 285*a1a3b679SAndreas Boehler * 286*a1a3b679SAndreas Boehler * @return string 287*a1a3b679SAndreas Boehler */ 288*a1a3b679SAndreas Boehler function getId() { 289*a1a3b679SAndreas Boehler 290*a1a3b679SAndreas Boehler return $this->id; 291*a1a3b679SAndreas Boehler 292*a1a3b679SAndreas Boehler } 293*a1a3b679SAndreas Boehler 294*a1a3b679SAndreas Boehler /** 295*a1a3b679SAndreas Boehler * Returns the ETag for this notification. 296*a1a3b679SAndreas Boehler * 297*a1a3b679SAndreas Boehler * The ETag must be surrounded by literal double-quotes. 298*a1a3b679SAndreas Boehler * 299*a1a3b679SAndreas Boehler * @return string 300*a1a3b679SAndreas Boehler */ 301*a1a3b679SAndreas Boehler function getETag() { 302*a1a3b679SAndreas Boehler 303*a1a3b679SAndreas Boehler return $this->etag; 304*a1a3b679SAndreas Boehler 305*a1a3b679SAndreas Boehler } 306*a1a3b679SAndreas Boehler 307*a1a3b679SAndreas Boehler} 308