1*a1a3b679SAndreas Boehler<?php 2*a1a3b679SAndreas Boehler 3*a1a3b679SAndreas Boehlernamespace Sabre\CalDAV\Schedule; 4*a1a3b679SAndreas Boehler 5*a1a3b679SAndreas Boehleruse Sabre\DAV; 6*a1a3b679SAndreas Boehleruse Sabre\CalDAV; 7*a1a3b679SAndreas Boehleruse Sabre\DAVACL; 8*a1a3b679SAndreas Boehleruse Sabre\CalDAV\Backend; 9*a1a3b679SAndreas Boehleruse Sabre\VObject; 10*a1a3b679SAndreas Boehler 11*a1a3b679SAndreas Boehler/** 12*a1a3b679SAndreas Boehler * The CalDAV scheduling inbox 13*a1a3b679SAndreas Boehler * 14*a1a3b679SAndreas Boehler * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/). 15*a1a3b679SAndreas Boehler * @author Evert Pot (http://evertpot.com/) 16*a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License 17*a1a3b679SAndreas Boehler */ 18*a1a3b679SAndreas Boehlerclass Inbox extends DAV\Collection implements IInbox { 19*a1a3b679SAndreas Boehler 20*a1a3b679SAndreas Boehler /** 21*a1a3b679SAndreas Boehler * CalDAV backend 22*a1a3b679SAndreas Boehler * 23*a1a3b679SAndreas Boehler * @var Backend\BackendInterface 24*a1a3b679SAndreas Boehler */ 25*a1a3b679SAndreas Boehler protected $caldavBackend; 26*a1a3b679SAndreas Boehler 27*a1a3b679SAndreas Boehler /** 28*a1a3b679SAndreas Boehler * The principal Uri 29*a1a3b679SAndreas Boehler * 30*a1a3b679SAndreas Boehler * @var string 31*a1a3b679SAndreas Boehler */ 32*a1a3b679SAndreas Boehler protected $principalUri; 33*a1a3b679SAndreas Boehler 34*a1a3b679SAndreas Boehler /** 35*a1a3b679SAndreas Boehler * Constructor 36*a1a3b679SAndreas Boehler * 37*a1a3b679SAndreas Boehler * @param Backend\SchedulingSupport $caldavBackend 38*a1a3b679SAndreas Boehler * @param string $principalUri 39*a1a3b679SAndreas Boehler */ 40*a1a3b679SAndreas Boehler function __construct(Backend\SchedulingSupport $caldavBackend, $principalUri) { 41*a1a3b679SAndreas Boehler 42*a1a3b679SAndreas Boehler $this->caldavBackend = $caldavBackend; 43*a1a3b679SAndreas Boehler $this->principalUri = $principalUri; 44*a1a3b679SAndreas Boehler 45*a1a3b679SAndreas Boehler } 46*a1a3b679SAndreas Boehler 47*a1a3b679SAndreas Boehler /** 48*a1a3b679SAndreas Boehler * Returns the name of the node. 49*a1a3b679SAndreas Boehler * 50*a1a3b679SAndreas Boehler * This is used to generate the url. 51*a1a3b679SAndreas Boehler * 52*a1a3b679SAndreas Boehler * @return string 53*a1a3b679SAndreas Boehler */ 54*a1a3b679SAndreas Boehler function getName() { 55*a1a3b679SAndreas Boehler 56*a1a3b679SAndreas Boehler return 'inbox'; 57*a1a3b679SAndreas Boehler 58*a1a3b679SAndreas Boehler } 59*a1a3b679SAndreas Boehler 60*a1a3b679SAndreas Boehler /** 61*a1a3b679SAndreas Boehler * Returns an array with all the child nodes 62*a1a3b679SAndreas Boehler * 63*a1a3b679SAndreas Boehler * @return \Sabre\DAV\INode[] 64*a1a3b679SAndreas Boehler */ 65*a1a3b679SAndreas Boehler function getChildren() { 66*a1a3b679SAndreas Boehler 67*a1a3b679SAndreas Boehler $objs = $this->caldavBackend->getSchedulingObjects($this->principalUri); 68*a1a3b679SAndreas Boehler $children = []; 69*a1a3b679SAndreas Boehler foreach ($objs as $obj) { 70*a1a3b679SAndreas Boehler //$obj['acl'] = $this->getACL(); 71*a1a3b679SAndreas Boehler $obj['principaluri'] = $this->principalUri; 72*a1a3b679SAndreas Boehler $children[] = new SchedulingObject($this->caldavBackend, $obj); 73*a1a3b679SAndreas Boehler } 74*a1a3b679SAndreas Boehler return $children; 75*a1a3b679SAndreas Boehler 76*a1a3b679SAndreas Boehler } 77*a1a3b679SAndreas Boehler 78*a1a3b679SAndreas Boehler /** 79*a1a3b679SAndreas Boehler * Creates a new file in the directory 80*a1a3b679SAndreas Boehler * 81*a1a3b679SAndreas Boehler * Data will either be supplied as a stream resource, or in certain cases 82*a1a3b679SAndreas Boehler * as a string. Keep in mind that you may have to support either. 83*a1a3b679SAndreas Boehler * 84*a1a3b679SAndreas Boehler * After succesful creation of the file, you may choose to return the ETag 85*a1a3b679SAndreas Boehler * of the new file here. 86*a1a3b679SAndreas Boehler * 87*a1a3b679SAndreas Boehler * The returned ETag must be surrounded by double-quotes (The quotes should 88*a1a3b679SAndreas Boehler * be part of the actual string). 89*a1a3b679SAndreas Boehler * 90*a1a3b679SAndreas Boehler * If you cannot accurately determine the ETag, you should not return it. 91*a1a3b679SAndreas Boehler * If you don't store the file exactly as-is (you're transforming it 92*a1a3b679SAndreas Boehler * somehow) you should also not return an ETag. 93*a1a3b679SAndreas Boehler * 94*a1a3b679SAndreas Boehler * This means that if a subsequent GET to this new file does not exactly 95*a1a3b679SAndreas Boehler * return the same contents of what was submitted here, you are strongly 96*a1a3b679SAndreas Boehler * recommended to omit the ETag. 97*a1a3b679SAndreas Boehler * 98*a1a3b679SAndreas Boehler * @param string $name Name of the file 99*a1a3b679SAndreas Boehler * @param resource|string $data Initial payload 100*a1a3b679SAndreas Boehler * @return null|string 101*a1a3b679SAndreas Boehler */ 102*a1a3b679SAndreas Boehler function createFile($name, $data = null) { 103*a1a3b679SAndreas Boehler 104*a1a3b679SAndreas Boehler $this->caldavBackend->createSchedulingObject($this->principalUri, $name, $data); 105*a1a3b679SAndreas Boehler 106*a1a3b679SAndreas Boehler } 107*a1a3b679SAndreas Boehler 108*a1a3b679SAndreas Boehler /** 109*a1a3b679SAndreas Boehler * Returns the owner principal 110*a1a3b679SAndreas Boehler * 111*a1a3b679SAndreas Boehler * This must be a url to a principal, or null if there's no owner 112*a1a3b679SAndreas Boehler * 113*a1a3b679SAndreas Boehler * @return string|null 114*a1a3b679SAndreas Boehler */ 115*a1a3b679SAndreas Boehler function getOwner() { 116*a1a3b679SAndreas Boehler 117*a1a3b679SAndreas Boehler return $this->principalUri; 118*a1a3b679SAndreas Boehler 119*a1a3b679SAndreas Boehler } 120*a1a3b679SAndreas Boehler 121*a1a3b679SAndreas Boehler /** 122*a1a3b679SAndreas Boehler * Returns a group principal 123*a1a3b679SAndreas Boehler * 124*a1a3b679SAndreas Boehler * This must be a url to a principal, or null if there's no owner 125*a1a3b679SAndreas Boehler * 126*a1a3b679SAndreas Boehler * @return string|null 127*a1a3b679SAndreas Boehler */ 128*a1a3b679SAndreas Boehler function getGroup() { 129*a1a3b679SAndreas Boehler 130*a1a3b679SAndreas Boehler return null; 131*a1a3b679SAndreas Boehler 132*a1a3b679SAndreas Boehler } 133*a1a3b679SAndreas Boehler 134*a1a3b679SAndreas Boehler /** 135*a1a3b679SAndreas Boehler * Returns a list of ACE's for this node. 136*a1a3b679SAndreas Boehler * 137*a1a3b679SAndreas Boehler * Each ACE has the following properties: 138*a1a3b679SAndreas Boehler * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are 139*a1a3b679SAndreas Boehler * currently the only supported privileges 140*a1a3b679SAndreas Boehler * * 'principal', a url to the principal who owns the node 141*a1a3b679SAndreas Boehler * * 'protected' (optional), indicating that this ACE is not allowed to 142*a1a3b679SAndreas Boehler * be updated. 143*a1a3b679SAndreas Boehler * 144*a1a3b679SAndreas Boehler * @return array 145*a1a3b679SAndreas Boehler */ 146*a1a3b679SAndreas Boehler function getACL() { 147*a1a3b679SAndreas Boehler 148*a1a3b679SAndreas Boehler return [ 149*a1a3b679SAndreas Boehler [ 150*a1a3b679SAndreas Boehler 'privilege' => '{DAV:}read', 151*a1a3b679SAndreas Boehler 'principal' => $this->getOwner(), 152*a1a3b679SAndreas Boehler 'protected' => true, 153*a1a3b679SAndreas Boehler ], 154*a1a3b679SAndreas Boehler [ 155*a1a3b679SAndreas Boehler 'privilege' => '{DAV:}write-properties', 156*a1a3b679SAndreas Boehler 'principal' => $this->getOwner(), 157*a1a3b679SAndreas Boehler 'protected' => true, 158*a1a3b679SAndreas Boehler ], 159*a1a3b679SAndreas Boehler [ 160*a1a3b679SAndreas Boehler 'privilege' => '{DAV:}unbind', 161*a1a3b679SAndreas Boehler 'principal' => $this->getOwner(), 162*a1a3b679SAndreas Boehler 'protected' => true, 163*a1a3b679SAndreas Boehler ], 164*a1a3b679SAndreas Boehler [ 165*a1a3b679SAndreas Boehler 'privilege' => '{DAV:}read', 166*a1a3b679SAndreas Boehler 'principal' => $this->getOwner() . '/calendar-proxy-read', 167*a1a3b679SAndreas Boehler 'protected' => true, 168*a1a3b679SAndreas Boehler ], 169*a1a3b679SAndreas Boehler [ 170*a1a3b679SAndreas Boehler 'privilege' => '{DAV:}read', 171*a1a3b679SAndreas Boehler 'principal' => $this->getOwner() . '/calendar-proxy-write', 172*a1a3b679SAndreas Boehler 'protected' => true, 173*a1a3b679SAndreas Boehler ], 174*a1a3b679SAndreas Boehler [ 175*a1a3b679SAndreas Boehler 'privilege' => '{DAV:}unbind', 176*a1a3b679SAndreas Boehler 'principal' => $this->getOwner() . '/calendar-proxy-write', 177*a1a3b679SAndreas Boehler 'protected' => true, 178*a1a3b679SAndreas Boehler ], 179*a1a3b679SAndreas Boehler [ 180*a1a3b679SAndreas Boehler 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-deliver-invite', 181*a1a3b679SAndreas Boehler 'principal' => '{DAV:}authenticated', 182*a1a3b679SAndreas Boehler 'protected' => true, 183*a1a3b679SAndreas Boehler ], 184*a1a3b679SAndreas Boehler [ 185*a1a3b679SAndreas Boehler 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-deliver-reply', 186*a1a3b679SAndreas Boehler 'principal' => '{DAV:}authenticated', 187*a1a3b679SAndreas Boehler 'protected' => true, 188*a1a3b679SAndreas Boehler ], 189*a1a3b679SAndreas Boehler ]; 190*a1a3b679SAndreas Boehler 191*a1a3b679SAndreas Boehler } 192*a1a3b679SAndreas Boehler 193*a1a3b679SAndreas Boehler /** 194*a1a3b679SAndreas Boehler * Updates the ACL 195*a1a3b679SAndreas Boehler * 196*a1a3b679SAndreas Boehler * This method will receive a list of new ACE's. 197*a1a3b679SAndreas Boehler * 198*a1a3b679SAndreas Boehler * @param array $acl 199*a1a3b679SAndreas Boehler * @return void 200*a1a3b679SAndreas Boehler */ 201*a1a3b679SAndreas Boehler function setACL(array $acl) { 202*a1a3b679SAndreas Boehler 203*a1a3b679SAndreas Boehler throw new DAV\Exception\MethodNotAllowed('You\'re not allowed to update the ACL'); 204*a1a3b679SAndreas Boehler 205*a1a3b679SAndreas Boehler } 206*a1a3b679SAndreas Boehler 207*a1a3b679SAndreas Boehler /** 208*a1a3b679SAndreas Boehler * Returns the list of supported privileges for this node. 209*a1a3b679SAndreas Boehler * 210*a1a3b679SAndreas Boehler * The returned data structure is a list of nested privileges. 211*a1a3b679SAndreas Boehler * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple 212*a1a3b679SAndreas Boehler * standard structure. 213*a1a3b679SAndreas Boehler * 214*a1a3b679SAndreas Boehler * If null is returned from this method, the default privilege set is used, 215*a1a3b679SAndreas Boehler * which is fine for most common usecases. 216*a1a3b679SAndreas Boehler * 217*a1a3b679SAndreas Boehler * @return array|null 218*a1a3b679SAndreas Boehler */ 219*a1a3b679SAndreas Boehler function getSupportedPrivilegeSet() { 220*a1a3b679SAndreas Boehler 221*a1a3b679SAndreas Boehler $ns = '{' . CalDAV\Plugin::NS_CALDAV . '}'; 222*a1a3b679SAndreas Boehler 223*a1a3b679SAndreas Boehler $default = DAVACL\Plugin::getDefaultSupportedPrivilegeSet(); 224*a1a3b679SAndreas Boehler $default['aggregates'][] = [ 225*a1a3b679SAndreas Boehler 'privilege' => $ns . 'schedule-deliver', 226*a1a3b679SAndreas Boehler 'aggregates' => [ 227*a1a3b679SAndreas Boehler ['privilege' => $ns . 'schedule-deliver-invite'], 228*a1a3b679SAndreas Boehler ['privilege' => $ns . 'schedule-deliver-reply'], 229*a1a3b679SAndreas Boehler ], 230*a1a3b679SAndreas Boehler ]; 231*a1a3b679SAndreas Boehler return $default; 232*a1a3b679SAndreas Boehler 233*a1a3b679SAndreas Boehler } 234*a1a3b679SAndreas Boehler 235*a1a3b679SAndreas Boehler /** 236*a1a3b679SAndreas Boehler * Performs a calendar-query on the contents of this calendar. 237*a1a3b679SAndreas Boehler * 238*a1a3b679SAndreas Boehler * The calendar-query is defined in RFC4791 : CalDAV. Using the 239*a1a3b679SAndreas Boehler * calendar-query it is possible for a client to request a specific set of 240*a1a3b679SAndreas Boehler * object, based on contents of iCalendar properties, date-ranges and 241*a1a3b679SAndreas Boehler * iCalendar component types (VTODO, VEVENT). 242*a1a3b679SAndreas Boehler * 243*a1a3b679SAndreas Boehler * This method should just return a list of (relative) urls that match this 244*a1a3b679SAndreas Boehler * query. 245*a1a3b679SAndreas Boehler * 246*a1a3b679SAndreas Boehler * The list of filters are specified as an array. The exact array is 247*a1a3b679SAndreas Boehler * documented by \Sabre\CalDAV\CalendarQueryParser. 248*a1a3b679SAndreas Boehler * 249*a1a3b679SAndreas Boehler * @param array $filters 250*a1a3b679SAndreas Boehler * @return array 251*a1a3b679SAndreas Boehler */ 252*a1a3b679SAndreas Boehler function calendarQuery(array $filters) { 253*a1a3b679SAndreas Boehler 254*a1a3b679SAndreas Boehler $result = []; 255*a1a3b679SAndreas Boehler $validator = new CalDAV\CalendarQueryValidator(); 256*a1a3b679SAndreas Boehler 257*a1a3b679SAndreas Boehler $objects = $this->caldavBackend->getSchedulingObjects($this->principalUri); 258*a1a3b679SAndreas Boehler foreach ($objects as $object) { 259*a1a3b679SAndreas Boehler $vObject = VObject\Reader::read($object['calendardata']); 260*a1a3b679SAndreas Boehler if ($validator->validate($vObject, $filters)) { 261*a1a3b679SAndreas Boehler $result[] = $object['uri']; 262*a1a3b679SAndreas Boehler } 263*a1a3b679SAndreas Boehler } 264*a1a3b679SAndreas Boehler return $result; 265*a1a3b679SAndreas Boehler 266*a1a3b679SAndreas Boehler } 267*a1a3b679SAndreas Boehler 268*a1a3b679SAndreas Boehler} 269