xref: /plugin/davcal/vendor/sabre/dav/lib/CalDAV/Notifications/Plugin.php (revision a1a3b6794e0e143a4a8b51d3185ce2d339be61ab)
1*a1a3b679SAndreas Boehler<?php
2*a1a3b679SAndreas Boehler
3*a1a3b679SAndreas Boehlernamespace Sabre\CalDAV\Notifications;
4*a1a3b679SAndreas Boehler
5*a1a3b679SAndreas Boehleruse Sabre\DAV;
6*a1a3b679SAndreas Boehleruse Sabre\DAV\PropFind;
7*a1a3b679SAndreas Boehleruse Sabre\DAV\INode as BaseINode;
8*a1a3b679SAndreas Boehleruse Sabre\DAV\ServerPlugin;
9*a1a3b679SAndreas Boehleruse Sabre\DAV\Server;
10*a1a3b679SAndreas Boehleruse Sabre\DAVACL;
11*a1a3b679SAndreas Boehleruse Sabre\HTTP\RequestInterface;
12*a1a3b679SAndreas Boehleruse Sabre\HTTP\ResponseInterface;
13*a1a3b679SAndreas Boehler
14*a1a3b679SAndreas Boehler/**
15*a1a3b679SAndreas Boehler * Notifications plugin
16*a1a3b679SAndreas Boehler *
17*a1a3b679SAndreas Boehler * This plugin implements several features required by the caldav-notification
18*a1a3b679SAndreas Boehler * draft specification.
19*a1a3b679SAndreas Boehler *
20*a1a3b679SAndreas Boehler * Before version 2.1.0 this functionality was part of Sabre\CalDAV\Plugin but
21*a1a3b679SAndreas Boehler * this has since been split up.
22*a1a3b679SAndreas Boehler *
23*a1a3b679SAndreas Boehler * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
24*a1a3b679SAndreas Boehler * @author Evert Pot (http://evertpot.com/)
25*a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License
26*a1a3b679SAndreas Boehler */
27*a1a3b679SAndreas Boehlerclass Plugin extends ServerPlugin {
28*a1a3b679SAndreas Boehler
29*a1a3b679SAndreas Boehler    /**
30*a1a3b679SAndreas Boehler     * This is the namespace for the proprietary calendarserver extensions
31*a1a3b679SAndreas Boehler     */
32*a1a3b679SAndreas Boehler    const NS_CALENDARSERVER = 'http://calendarserver.org/ns/';
33*a1a3b679SAndreas Boehler
34*a1a3b679SAndreas Boehler    /**
35*a1a3b679SAndreas Boehler     * Reference to the main server object.
36*a1a3b679SAndreas Boehler     *
37*a1a3b679SAndreas Boehler     * @var Server
38*a1a3b679SAndreas Boehler     */
39*a1a3b679SAndreas Boehler    protected $server;
40*a1a3b679SAndreas Boehler
41*a1a3b679SAndreas Boehler    /**
42*a1a3b679SAndreas Boehler     * Returns a plugin name.
43*a1a3b679SAndreas Boehler     *
44*a1a3b679SAndreas Boehler     * Using this name other plugins will be able to access other plugins
45*a1a3b679SAndreas Boehler     * using \Sabre\DAV\Server::getPlugin
46*a1a3b679SAndreas Boehler     *
47*a1a3b679SAndreas Boehler     * @return string
48*a1a3b679SAndreas Boehler     */
49*a1a3b679SAndreas Boehler    function getPluginName() {
50*a1a3b679SAndreas Boehler
51*a1a3b679SAndreas Boehler        return 'notifications';
52*a1a3b679SAndreas Boehler
53*a1a3b679SAndreas Boehler    }
54*a1a3b679SAndreas Boehler
55*a1a3b679SAndreas Boehler    /**
56*a1a3b679SAndreas Boehler     * This initializes the plugin.
57*a1a3b679SAndreas Boehler     *
58*a1a3b679SAndreas Boehler     * This function is called by Sabre\DAV\Server, after
59*a1a3b679SAndreas Boehler     * addPlugin is called.
60*a1a3b679SAndreas Boehler     *
61*a1a3b679SAndreas Boehler     * This method should set up the required event subscriptions.
62*a1a3b679SAndreas Boehler     *
63*a1a3b679SAndreas Boehler     * @param Server $server
64*a1a3b679SAndreas Boehler     * @return void
65*a1a3b679SAndreas Boehler     */
66*a1a3b679SAndreas Boehler    function initialize(Server $server) {
67*a1a3b679SAndreas Boehler
68*a1a3b679SAndreas Boehler        $this->server = $server;
69*a1a3b679SAndreas Boehler        $server->on('method:GET', [$this, 'httpGet'], 90);
70*a1a3b679SAndreas Boehler        $server->on('propFind',   [$this, 'propFind']);
71*a1a3b679SAndreas Boehler
72*a1a3b679SAndreas Boehler        $server->xml->namespaceMap[self::NS_CALENDARSERVER] = 'cs';
73*a1a3b679SAndreas Boehler        $server->resourceTypeMapping['\\Sabre\\CalDAV\\Notifications\\ICollection'] = '{' . self::NS_CALENDARSERVER . '}notification';
74*a1a3b679SAndreas Boehler
75*a1a3b679SAndreas Boehler        array_push($server->protectedProperties,
76*a1a3b679SAndreas Boehler            '{' . self::NS_CALENDARSERVER . '}notification-URL',
77*a1a3b679SAndreas Boehler            '{' . self::NS_CALENDARSERVER . '}notificationtype'
78*a1a3b679SAndreas Boehler        );
79*a1a3b679SAndreas Boehler
80*a1a3b679SAndreas Boehler    }
81*a1a3b679SAndreas Boehler
82*a1a3b679SAndreas Boehler    /**
83*a1a3b679SAndreas Boehler     * PropFind
84*a1a3b679SAndreas Boehler     *
85*a1a3b679SAndreas Boehler     * @param PropFind $propFind
86*a1a3b679SAndreas Boehler     * @param BaseINode $node
87*a1a3b679SAndreas Boehler     * @return void
88*a1a3b679SAndreas Boehler     */
89*a1a3b679SAndreas Boehler    function propFind(PropFind $propFind, BaseINode $node) {
90*a1a3b679SAndreas Boehler
91*a1a3b679SAndreas Boehler        $caldavPlugin = $this->server->getPlugin('caldav');
92*a1a3b679SAndreas Boehler
93*a1a3b679SAndreas Boehler        if ($node instanceof DAVACL\IPrincipal) {
94*a1a3b679SAndreas Boehler
95*a1a3b679SAndreas Boehler            $principalUrl = $node->getPrincipalUrl();
96*a1a3b679SAndreas Boehler
97*a1a3b679SAndreas Boehler            // notification-URL property
98*a1a3b679SAndreas Boehler            $propFind->handle('{' . self::NS_CALENDARSERVER . '}notification-URL', function() use ($principalUrl, $caldavPlugin) {
99*a1a3b679SAndreas Boehler
100*a1a3b679SAndreas Boehler                $notificationPath = $caldavPlugin->getCalendarHomeForPrincipal($principalUrl) . '/notifications/';
101*a1a3b679SAndreas Boehler                return new DAV\Xml\Property\Href($notificationPath);
102*a1a3b679SAndreas Boehler
103*a1a3b679SAndreas Boehler            });
104*a1a3b679SAndreas Boehler
105*a1a3b679SAndreas Boehler        }
106*a1a3b679SAndreas Boehler
107*a1a3b679SAndreas Boehler        if ($node instanceof INode) {
108*a1a3b679SAndreas Boehler
109*a1a3b679SAndreas Boehler            $propFind->handle(
110*a1a3b679SAndreas Boehler                '{' . self::NS_CALENDARSERVER . '}notificationtype',
111*a1a3b679SAndreas Boehler                [$node, 'getNotificationType']
112*a1a3b679SAndreas Boehler            );
113*a1a3b679SAndreas Boehler
114*a1a3b679SAndreas Boehler        }
115*a1a3b679SAndreas Boehler
116*a1a3b679SAndreas Boehler    }
117*a1a3b679SAndreas Boehler
118*a1a3b679SAndreas Boehler    /**
119*a1a3b679SAndreas Boehler     * This event is triggered before the usual GET request handler.
120*a1a3b679SAndreas Boehler     *
121*a1a3b679SAndreas Boehler     * We use this to intercept GET calls to notification nodes, and return the
122*a1a3b679SAndreas Boehler     * proper response.
123*a1a3b679SAndreas Boehler     *
124*a1a3b679SAndreas Boehler     * @param RequestInterface $request
125*a1a3b679SAndreas Boehler     * @param ResponseInterface $response
126*a1a3b679SAndreas Boehler     * @return void
127*a1a3b679SAndreas Boehler     */
128*a1a3b679SAndreas Boehler    function httpGet(RequestInterface $request, ResponseInterface $response) {
129*a1a3b679SAndreas Boehler
130*a1a3b679SAndreas Boehler        $path = $request->getPath();
131*a1a3b679SAndreas Boehler
132*a1a3b679SAndreas Boehler        try {
133*a1a3b679SAndreas Boehler            $node = $this->server->tree->getNodeForPath($path);
134*a1a3b679SAndreas Boehler        } catch (DAV\Exception\NotFound $e) {
135*a1a3b679SAndreas Boehler            return;
136*a1a3b679SAndreas Boehler        }
137*a1a3b679SAndreas Boehler
138*a1a3b679SAndreas Boehler        if (!$node instanceof INode)
139*a1a3b679SAndreas Boehler            return;
140*a1a3b679SAndreas Boehler
141*a1a3b679SAndreas Boehler        $writer = $this->server->xml->getWriter();
142*a1a3b679SAndreas Boehler        $writer->contextUri = $this->server->getBaseUri();
143*a1a3b679SAndreas Boehler        $writer->openMemory();
144*a1a3b679SAndreas Boehler        $writer->startDocument('1.0', 'UTF-8');
145*a1a3b679SAndreas Boehler        $writer->startElement('{http://calendarserver.org/ns/}notification');
146*a1a3b679SAndreas Boehler        $node->getNotificationType()->xmlSerializeFull($writer);
147*a1a3b679SAndreas Boehler        $writer->endElement();
148*a1a3b679SAndreas Boehler
149*a1a3b679SAndreas Boehler        $response->setHeader('Content-Type', 'application/xml');
150*a1a3b679SAndreas Boehler        $response->setHeader('ETag', $node->getETag());
151*a1a3b679SAndreas Boehler        $response->setStatus(200);
152*a1a3b679SAndreas Boehler        $response->setBody($writer->outputMemory());
153*a1a3b679SAndreas Boehler
154*a1a3b679SAndreas Boehler        // Return false to break the event chain.
155*a1a3b679SAndreas Boehler        return false;
156*a1a3b679SAndreas Boehler
157*a1a3b679SAndreas Boehler    }
158*a1a3b679SAndreas Boehler
159*a1a3b679SAndreas Boehler    /**
160*a1a3b679SAndreas Boehler     * Returns a bunch of meta-data about the plugin.
161*a1a3b679SAndreas Boehler     *
162*a1a3b679SAndreas Boehler     * Providing this information is optional, and is mainly displayed by the
163*a1a3b679SAndreas Boehler     * Browser plugin.
164*a1a3b679SAndreas Boehler     *
165*a1a3b679SAndreas Boehler     * The description key in the returned array may contain html and will not
166*a1a3b679SAndreas Boehler     * be sanitized.
167*a1a3b679SAndreas Boehler     *
168*a1a3b679SAndreas Boehler     * @return array
169*a1a3b679SAndreas Boehler     */
170*a1a3b679SAndreas Boehler    function getPluginInfo() {
171*a1a3b679SAndreas Boehler
172*a1a3b679SAndreas Boehler        return [
173*a1a3b679SAndreas Boehler            'name'        => $this->getPluginName(),
174*a1a3b679SAndreas Boehler            'description' => 'Adds support for caldav-notifications, which is required to enable caldav-sharing.',
175*a1a3b679SAndreas Boehler            'link'        => 'http://sabre.io/dav/caldav-sharing/',
176*a1a3b679SAndreas Boehler        ];
177*a1a3b679SAndreas Boehler
178*a1a3b679SAndreas Boehler    }
179*a1a3b679SAndreas Boehler
180*a1a3b679SAndreas Boehler}
181