22
33namespace Pdsinterop \Solid \Resources ;
44
5+ use EasyRdf \Format ;
56use Pdsinterop \Solid \SolidNotifications \SolidNotificationsInterface ;
67use EasyRdf \Exception as RdfException ;
78use EasyRdf \Graph as Graph ;
@@ -34,7 +35,7 @@ class Server
3435 public const ERROR_PUT_NON_EXISTING_RESOURCE = self ::ERROR_PATH_DOES_NOT_EXIST . '. Can not "PUT" non-existing resource. Use "POST" instead ' ;
3536 public const ERROR_UNKNOWN_HTTP_METHOD = 'Unknown or unsupported HTTP METHOD "%s" ' ;
3637
37- private const MIME_TYPE_DIRECTORY = 'directory ' ;
38+ public const MIME_TYPE_DIRECTORY = 'directory ' ;
3839 private const QUERY_PARAM_HTTP_METHOD = 'http-method ' ;
3940
4041 private const NOTIFICATION_TYPE_CREATE = "Create " ;
@@ -55,6 +56,10 @@ class Server
5556 private $ basePath ;
5657 /** @var string */
5758 private $ baseUrl ;
59+ /** @var string */
60+ private $ lockedPath ;
61+ /** @var string */
62+ private $ requestedPath ;
5863 /** @var Filesystem */
5964 private $ filesystem ;
6065 /** @var Graph */
@@ -89,6 +94,11 @@ final public function setBaseUrl($url)
8994 $ this ->basePath = $ serverRequest ->getUri ()->getPath ();
9095 }
9196
97+ final public function lockToPath ($ path )
98+ {
99+ $ this ->lockedPath = $ path ;
100+ }
101+
92102 final public function setNotifications (SolidNotificationsInterface $ notifications )
93103 {
94104 $ this ->notifications = $ notifications ;
@@ -100,9 +110,14 @@ final public function __construct(Filesystem $filesystem, Response $response, ?G
100110 {
101111 $ this ->basePath = '' ;
102112 $ this ->baseUrl = '' ;
113+ $ this ->lockedPath = false ;
103114 $ this ->filesystem = $ filesystem ;
104115 $ this ->graph = $ graph ?? new Graph ();
105116 $ this ->response = $ response ;
117+
118+ // Store and serve json-ld with '.json' extension instead of '.jsonld''
119+ Format::getFormat ('jsonld ' )->setExtensions ('json ' );
120+
106121 // @TODO: Mention \EasyRdf_Namespace::set('lm', 'https://purl.org/pdsinterop/link-metadata#');
107122 }
108123
@@ -121,6 +136,11 @@ final public function respondToRequest(Request $request): Response
121136 $ path = reset ($ slugs );
122137 }
123138
139+ $ this ->requestedPath = $ path ;
140+ if ($ this ->lockedPath ) {
141+ $ path = $ this ->lockedPath ;
142+ }
143+
124144 $ method = $ this ->getRequestMethod ($ request );
125145
126146 $ contents = $ request ->getBody ()->getContents ();
@@ -191,7 +211,8 @@ private function handle(string $method, string $path, $contents, $request): Resp
191211 $ response = $ response ->withStatus (400 );
192212 break ;
193213 }
194- break ;
214+ break ;
215+
195216 case 'POST ' :
196217 $ pathExists = $ filesystem ->has ($ path );
197218 if ($ pathExists ) {
@@ -201,6 +222,7 @@ private function handle(string $method, string $path, $contents, $request): Resp
201222 $ pathExists = true ;
202223 $ mimetype = self ::MIME_TYPE_DIRECTORY ;
203224 }
225+
204226 if ($ pathExists === true ) {
205227 if (isset ($ mimetype ) && $ mimetype === self ::MIME_TYPE_DIRECTORY ) {
206228 $ contentType = explode ("; " , $ request ->getHeaderLine ("Content-Type " ))[0 ];
@@ -217,25 +239,18 @@ private function handle(string $method, string $path, $contents, $request): Resp
217239 $ response = $ this ->handleCreateDirectoryRequest ($ response , $ path . $ filename );
218240 break ;
219241 default :
220- // FIXME: make this list complete for at least the things we'd expect (turtle, n3, jsonld, ntriples, rdf);
221- switch ($ contentType ) {
222- case '' :
223- // FIXME: if no content type was passed, we should reject the request according to the spec;
224- break ;
225- case "text/plain " :
226- $ filename .= ".txt " ;
227- break ;
228- case "text/turtle " :
229- $ filename .= ".ttl " ;
230- break ;
231- case "text/html " :
232- $ filename .= ".html " ;
233- break ;
234- case "application/json " :
235- case "application/ld+json " :
236- $ filename .= ".json " ;
237- break ;
242+ // FIXME: if no content type was passed, we should reject the request according to the spec;
243+ foreach (Format::getFormats () as $ format ) {
244+ $ mimeTypes = array_keys ($ format ->getMimeTypes ());
245+ foreach ($ mimeTypes as $ mimeType ) {
246+ $ extensions [$ mimeType ] = '. ' .$ format ->getDefaultExtension ();
247+ }
248+ }
249+
250+ if (isset ($ extensions [$ contentType ]) && ! str_ends_with ($ filename , $ extensions [$ contentType ])) {
251+ $ filename .= $ extensions [$ contentType ];
238252 }
253+
239254 $ response = $ this ->handleCreateRequest ($ response , $ path . $ filename , $ contents );
240255 break ;
241256 }
@@ -245,7 +260,8 @@ private function handle(string $method, string $path, $contents, $request): Resp
245260 } else {
246261 $ response = $ this ->handleCreateRequest ($ response , $ path , $ contents );
247262 }
248- break ;
263+ break ;
264+
249265 case 'PUT ' :
250266 $ link = $ request ->getHeaderLine ("Link " );
251267 switch ($ link ) {
@@ -260,7 +276,8 @@ private function handle(string $method, string $path, $contents, $request): Resp
260276 }
261277 break ;
262278 }
263- break ;
279+ break ;
280+
264281 default :
265282 throw Exception::create (self ::ERROR_UNKNOWN_HTTP_METHOD , [$ method ]);
266283 break ;
@@ -283,7 +300,7 @@ private function handleSparqlUpdate(Response $response, string $path, $contents)
283300
284301 try {
285302 // Assuming this is in our native format, turtle
286- $ graph ->parse ($ data , "turtle " , $ this ->baseUrl . $ path );
303+ $ graph ->parse ($ data , "turtle " , $ this ->baseUrl . $ this -> basePath . $ this -> requestedPath );
287304 // FIXME: Use enums from namespace Pdsinterop\Rdf\Enum\Format instead of 'turtle'?
288305
289306 // parse query in contents
@@ -297,14 +314,14 @@ private function handleSparqlUpdate(Response $response, string $path, $contents)
297314 case "INSERT " :
298315 // insert $triple(s) into $graph
299316 // @CHECKME: Does the Graph Parse here also need an URI?
300- $ graph ->parse ($ triples , "turtle " ); // FIXME: The triples here are in sparql format, not in turtle;
317+ $ graph ->parse ($ triples , "turtle " , $ this -> baseUrl . $ this -> basePath . $ this -> requestedPath ); // FIXME: The triples here are in sparql format, not in turtle;
301318
302319 break ;
303320 case "DELETE " :
304321 // delete $triples from $graph
305322 $ deleteGraph = $ this ->getGraph ();
306323 // @CHECKME: Does the Graph Parse here also need an URI?
307- $ deleteGraph ->parse ($ triples , "turtle " ); // FIXME: The triples here are in sparql format, not in turtle;
324+ $ deleteGraph ->parse ($ triples , "turtle " , $ this -> baseUrl . $ this -> basePath . $ this -> requestedPath ); // FIXME: The triples here are in sparql format, not in turtle;
308325 $ resources = $ deleteGraph ->resources ();
309326 foreach ($ resources as $ resource ) {
310327 $ properties = $ resource ->propertyUris ();
@@ -440,25 +457,22 @@ private function handleN3Update(Response $response, string $path, $contents): Re
440457
441458 try {
442459 // Assuming this is in our native format, turtle
443- // @CHECKME: Does the Graph Parse here also need an URI?
444- $ graph ->parse ($ data , "turtle " );
445- // FIXME: Adding this base will allow us to parse <> entries; , $this->baseUrl . $this->basePath . $path), but that breaks the build.
460+ $ graph ->parse ($ data , "turtle " , $ this ->baseUrl . $ this ->basePath . $ this ->requestedPath );
446461 // FIXME: Use enums from namespace Pdsinterop\Rdf\Enum\Format instead of 'turtle'?
447462 $ instructions = $ this ->n3Convert ($ contents );
448463 foreach ($ instructions as $ key => $ value ) {
449464 switch ($ key ) {
450465 case "insert " :
451466 // error_log("INSERT");
452467 // error_log($instructions['insert']);
453- $ graph ->parse ($ instructions ['insert ' ], "turtle " );
468+ $ graph ->parse ($ instructions ['insert ' ], "turtle " , $ this -> baseUrl . $ this -> basePath . $ this -> requestedPath );
454469 break ;
455470 case "delete " :
456471 $ deleteGraph = $ this ->getGraph ();
457472 // error_log("DELETE");
458473 // error_log($instructions['delete']);
459474
460- // @CHECKME: Does the Graph Parse here also need an URI?
461- $ deleteGraph ->parse ($ instructions ['delete ' ], "turtle " );
475+ $ deleteGraph ->parse ($ instructions ['delete ' ], "turtle " , $ this ->baseUrl . $ this ->basePath . $ this ->requestedPath );
462476 $ resources = $ deleteGraph ->resources ();
463477 foreach ($ resources as $ resource ) {
464478 $ properties = $ resource ->propertyUris ();
0 commit comments