/** * This function handles the MKCALENDAR HTTP method, which creates * a new calendar. * * @param RequestInterface $request * @param ResponseInterface $response * @return bool */ function httpMkCalendar(RequestInterface $request, ResponseInterface $response) { $body = $request->getBodyAsString(); $path = $request->getPath(); $properties = []; if ($body) { try { $mkcalendar = $this->server->xml->expect('{urn:ietf:params:xml:ns:caldav}mkcalendar', $body); } catch (\Sabre\Xml\ParseException $e) { throw new BadRequest($e->getMessage(), null, $e); } $properties = $mkcalendar->getProperties(); } // iCal abuses MKCALENDAR since iCal 10.9.2 to create server-stored // subscriptions. Before that it used MKCOL which was the correct way // to do this. // // If the body had a {DAV:}resourcetype, it means we stumbled upon this // request, and we simply use it instead of the pre-defined list. if (isset($properties['{DAV:}resourcetype'])) { $resourceType = $properties['{DAV:}resourcetype']->getValue(); } else { $resourceType = ['{DAV:}collection', '{urn:ietf:params:xml:ns:caldav}calendar']; } $this->server->createCollection($path, new MkCol($resourceType, $properties)); $this->server->httpResponse->setStatus(201); $this->server->httpResponse->setHeader('Content-Length', 0); // This breaks the method chain. return false; }
/** * WebDAV MKCOL * * The MKCOL method is used to create a new collection (directory) on the server * * @param RequestInterface $request * @param ResponseInterface $response * @return bool */ function httpMkcol(RequestInterface $request, ResponseInterface $response) { $requestBody = $request->getBodyAsString(); $path = $request->getPath(); if ($requestBody) { $contentType = $request->getHeader('Content-Type'); if (strpos($contentType, 'application/xml') !== 0 && strpos($contentType, 'text/xml') !== 0) { // We must throw 415 for unsupported mkcol bodies throw new Exception\UnsupportedMediaType('The request body for the MKCOL request must have an xml Content-Type'); } try { $mkcol = $this->server->xml->expect('{DAV:}mkcol', $requestBody); } catch (\Sabre\Xml\ParseException $e) { throw new Exception\BadRequest($e->getMessage(), null, $e); } $properties = $mkcol->getProperties(); if (!isset($properties['{DAV:}resourcetype'])) throw new Exception\BadRequest('The mkcol request must include a {DAV:}resourcetype property'); $resourceType = $properties['{DAV:}resourcetype']->getValue(); unset($properties['{DAV:}resourcetype']); } else { $properties = []; $resourceType = ['{DAV:}collection']; } $mkcol = new MkCol($resourceType, $properties); $result = $this->server->createCollection($path, $mkcol); if (is_array($result)) { $response->setStatus(207); $response->setHeader('Content-Type', 'application/xml; charset=utf-8'); $response->setBody( $this->server->generateMultiStatus([$result]) ); } else { $response->setHeader('Content-Length', '0'); $response->setStatus(201); } // Sending back false will interupt the event chain and tell the server // we've handled this method. return false; }
/** * This method allows us to intercept the 'mkcalendar' sabreAction. This * action enables the user to create new calendars from the browser plugin. * * @param string $uri * @param string $action * @param array $postVars * @return bool */ function browserPostAction($uri, $action, array $postVars) { if ($action !== 'mkcalendar') { return; } $resourceType = ['{DAV:}collection', '{urn:ietf:params:xml:ns:caldav}calendar']; $properties = []; if (isset($postVars['{DAV:}displayname'])) { $properties['{DAV:}displayname'] = $postVars['{DAV:}displayname']; } $this->server->createCollection($uri . '/' . $postVars['name'], $resourceType, $properties); return false; }
/** * WebDAV MKCOL * * The MKCOL method is used to create a new collection (directory) on the server * * @param RequestInterface $request * @param ResponseInterface $response * @return bool */ function httpMkcol(RequestInterface $request, ResponseInterface $response) { $requestBody = $request->getBodyAsString(); $path = $request->getPath(); if ($requestBody) { $contentType = $request->getHeader('Content-Type'); if (strpos($contentType, 'application/xml') !== 0 && strpos($contentType, 'text/xml') !== 0) { // We must throw 415 for unsupported mkcol bodies throw new Exception\UnsupportedMediaType('The request body for the MKCOL request must have an xml Content-Type'); } $dom = XMLUtil::loadDOMDocument($requestBody); if (XMLUtil::toClarkNotation($dom->firstChild) !== '{DAV:}mkcol') { // We must throw 415 for unsupported mkcol bodies throw new Exception\UnsupportedMediaType('The request body for the MKCOL request must be a {DAV:}mkcol request construct.'); } $properties = []; foreach ($dom->firstChild->childNodes as $childNode) { if (XMLUtil::toClarkNotation($childNode) !== '{DAV:}set') { continue; } $properties = array_merge($properties, XMLUtil::parseProperties($childNode, $this->server->propertyMap)); } if (!isset($properties['{DAV:}resourcetype'])) { throw new Exception\BadRequest('The mkcol request must include a {DAV:}resourcetype property'); } $resourceType = $properties['{DAV:}resourcetype']->getValue(); unset($properties['{DAV:}resourcetype']); } else { $properties = []; $resourceType = ['{DAV:}collection']; } $result = $this->server->createCollection($path, $resourceType, $properties); if (is_array($result)) { $response->setStatus(207); $response->setHeader('Content-Type', 'application/xml; charset=utf-8'); $response->setBody($this->server->generateMultiStatus([$result])); } else { $response->setHeader('Content-Length', '0'); $response->setStatus(201); } // Sending back false will interupt the event chain and tell the server // we've handled this method. return false; }