22
33namespace Pdsinterop \Solid \Resources ;
44
5+ use Pdsinterop \Solid \SolidNotifications \SolidNotificationsInterface ;
56use EasyRdf \Exception as RdfException ;
67use EasyRdf \Graph as Graph ;
78use Laminas \Diactoros \ServerRequest ;
1112use Psr \Http \Message \ResponseInterface as Response ;
1213use Psr \Http \Message \ServerRequestInterface as Request ;
1314use Throwable ;
14- use WebSocket \Client ;
1515use pietercolpaert \hardf \TriGWriter ;
1616use pietercolpaert \hardf \TriGParser ;
1717
@@ -37,6 +37,10 @@ class Server
3737 private const MIME_TYPE_DIRECTORY = 'directory ' ;
3838 private const QUERY_PARAM_HTTP_METHOD = 'http-method ' ;
3939
40+ private const NOTIFICATION_TYPE_CREATE = "Create " ;
41+ private const NOTIFICATION_TYPE_UPDATE = "Update " ;
42+ private const NOTIFICATION_TYPE_DELETE = "Delete " ;
43+
4044 /** @var string[] */
4145 private $ availableMethods = [
4246 'DELETE ' ,
@@ -55,8 +59,8 @@ class Server
5559 private $ filesystem ;
5660 /** @var Graph */
5761 private $ graph ;
58- /** @var string */
59- private $ pubsub ;
62+ /** @var SolidNotificationsInterface */
63+ private $ notifications ;
6064 /** @var Response */
6165 private $ response ;
6266
@@ -85,19 +89,17 @@ final public function setBaseUrl($url)
8589 $ this ->basePath = $ serverRequest ->getUri ()->getPath ();
8690 }
8791
88- final public function setPubSubUrl ( $ url )
92+ final public function setNotifications ( SolidNotificationsInterface $ notifications )
8993 {
90- $ this ->pubsub = $ url ;
94+ $ this ->notifications = $ notifications ;
9195 }
92-
9396 //////////////////////////////// PUBLIC API \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
9497
9598 // @TODO: The Graph should be injected by the caller
9699 final public function __construct (Filesystem $ filesystem , Response $ response , Graph $ graph = null )
97100 {
98101 $ this ->basePath = '' ;
99102 $ this ->baseUrl = '' ;
100- $ this ->pubsub = '' ;
101103 $ this ->filesystem = $ filesystem ;
102104 $ this ->graph = $ graph ?? new Graph ();
103105 $ this ->response = $ response ;
@@ -152,17 +154,6 @@ private function handle(string $method, string $path, $contents, $request): Resp
152154 // Lets assume the worst...
153155 $ response = $ response ->withStatus (500 );
154156
155- // Set Accept, Allow, and CORS headers
156- // $response = $response
157- // ->withHeader('Access-Control-Allow-Origin', '*')
158- // ->withHeader('Access-Control-Allow-Credentials','true')
159- // ->withHeader('Access-Control-Allow-Headers', '*, authorization, accept, content-type')
160- // @FIXME: Add correct headers to resources (for instance allow DELETE on a GET resource)
161- // ->withAddedHeader('Accept-Patch', 'text/ldpatch')
162- // ->withAddedHeader('Accept-Post', 'text/turtle, application/ld+json, image/bmp, image/jpeg')
163- // ->withHeader('Allow', 'GET, HEAD, OPTIONS, PATCH, POST, PUT')
164- //;
165-
166157 switch ($ method ) {
167158 case 'DELETE ' :
168159 $ response = $ this ->handleDeleteRequest ($ response , $ path , $ contents );
@@ -175,9 +166,6 @@ private function handle(string $method, string $path, $contents, $request): Resp
175166 $ response ->getBody ()->rewind ();
176167 $ response ->getBody ()->write ('' );
177168 $ response = $ response ->withStatus (204 ); // CHECKME: nextcloud will remove the updates-via header - any objections to give the 'HEAD' request a 'no content' response type?
178- if ($ this ->pubsub ) {
179- $ response = $ response ->withHeader ("updates-via " , $ this ->pubsub );
180- }
181169 }
182170 break ;
183171
@@ -350,7 +338,7 @@ private function handleSparqlUpdate(Response $response, string $path, $contents)
350338
351339 if ($ success ) {
352340 $ this ->removeLinkFromMetaFileFor ($ path );
353- $ this ->sendWebsocketUpdate ($ path );
341+ $ this ->sendNotificationUpdate ($ path, self :: NOTIFICATION_TYPE_UPDATE );
354342 }
355343 } catch (RdfException $ exception ) {
356344 $ response ->getBody ()->write (self ::ERROR_CAN_NOT_PARSE_FOR_PATCH );
@@ -501,7 +489,7 @@ private function handleN3Update(Response $response, string $path, $contents): Re
501489
502490 if ($ success ) {
503491 $ this ->removeLinkFromMetaFileFor ($ path );
504- $ this ->sendWebsocketUpdate ($ path );
492+ $ this ->sendNotificationUpdate ($ path, self :: NOTIFICATION_TYPE_UPDATE );
505493 }
506494 } catch (RdfException $ exception ) {
507495 $ response ->getBody ()->write (self ::ERROR_CAN_NOT_PARSE_FOR_PATCH );
@@ -551,7 +539,7 @@ private function handleCreateRequest(Response $response, string $path, $contents
551539 $ this ->removeLinkFromMetaFileFor ($ path );
552540 $ response = $ response ->withHeader ("Location " , $ this ->baseUrl . $ path );
553541 $ response = $ response ->withStatus (201 );
554- $ this ->sendWebsocketUpdate ($ path );
542+ $ this ->sendNotificationUpdate ($ path, self :: NOTIFICATION_TYPE_CREATE );
555543 } else {
556544 $ response = $ response ->withStatus (500 );
557545 }
@@ -585,39 +573,21 @@ private function handleCreateDirectoryRequest(Response $response, string $path):
585573 $ response = $ response ->withStatus ($ success ? 201 : 500 );
586574 if ($ success ) {
587575 $ this ->removeLinkFromMetaFileFor ($ path );
588- $ this ->sendWebsocketUpdate ($ path );
576+ $ this ->sendNotificationUpdate ($ path, self :: NOTIFICATION_TYPE_CREATE );
589577 }
590578 }
591579
592580 return $ response ;
593581 }
594582
595- private function sendWebsocketUpdate ($ path )
583+ private function sendNotificationUpdate ($ path, $ type )
596584 {
597- $ pubsub = $ this ->pubsub ;
598- if (!$ pubsub ) {
599- return ; // no pubsub server available, don't even try;
600- }
601-
602- $ pubsub = str_replace (["https:// " , "http:// " ], "ws:// " , $ pubsub );
603-
604585 $ baseUrl = $ this ->baseUrl ;
586+ $ this ->notifications ->send ($ baseUrl . $ path , $ type );
605587
606- $ client = new Client ($ pubsub , array (
607- 'headers ' => array (
608- 'Sec-WebSocket-Protocol ' => 'solid-0.1 '
609- )
610- ));
611-
612- try {
613- $ client ->send ("pub $ baseUrl$ path \n" );
614-
615- while ($ path !== "/ " ) {
616- $ path = $ this ->parentPath ($ path );
617- $ client ->send ("pub $ baseUrl$ path \n" );
618- }
619- } catch (\WebSocket \Exception $ exception ) {
620- throw new Exception ('Could not write to pub-sup server ' , 502 , $ exception );
588+ while ($ path !== "/ " ) {
589+ $ path = $ this ->parentPath ($ path );
590+ $ this ->notifications ->send ($ baseUrl . $ path , self ::NOTIFICATION_TYPE_UPDATE ); // checkme: delete on a directory triggers update notifications on parents
621591 }
622592 }
623593
@@ -637,15 +607,15 @@ private function handleDeleteRequest(Response $response, string $path, $contents
637607 } else {
638608 $ success = $ filesystem ->deleteDir ($ path );
639609 if ($ success ) {
640- $ this ->sendWebsocketUpdate ($ path );
610+ $ this ->sendNotificationUpdate ($ path, self :: NOTIFICATION_TYPE_DELETE );
641611 }
642612
643613 $ status = $ success ? 204 : 500 ;
644614 }
645615 } else {
646616 $ success = $ filesystem ->delete ($ path );
647617 if ($ success ) {
648- $ this ->sendWebsocketUpdate ($ path );
618+ $ this ->sendNotificationUpdate ($ path, self :: NOTIFICATION_TYPE_DELETE );
649619 }
650620 $ status = $ success ? 204 : 500 ;
651621 }
@@ -673,7 +643,7 @@ private function handleUpdateRequest(Response $response, string $path, string $c
673643 $ response = $ response ->withStatus ($ success ? 201 : 500 );
674644 if ($ success ) {
675645 $ this ->removeLinkFromMetaFileFor ($ path );
676- $ this ->sendWebsocketUpdate ($ path );
646+ $ this ->sendNotificationUpdate ($ path, self :: NOTIFICATION_TYPE_UPDATE );
677647 }
678648 }
679649
0 commit comments