From 6f614f5fda9671d76b20c7ce2dbf31ebd1a5dad7 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Thu, 24 Sep 2026 13:52:45 +0200 Subject: [PATCH 1/6] update php to 8.3 and laminas to ^3 --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index c2d7e80..ad83f64 100644 --- a/composer.json +++ b/composer.json @@ -18,9 +18,9 @@ "license": "MIT", "name": "pdsinterop/solid-crud", "require": { - "php": "^8.0", + "php": "^8.3", "ext-mbstring": "*", - "laminas/laminas-diactoros": "^2.14", + "laminas/laminas-diactoros": "^3", "league/flysystem": "^1.0", "mjrider/flysystem-factory": "^0.7", "pdsinterop/flysystem-rdf": "^0.6.1", From 24d5f3db71fd3a21bf44f67516d1606260dc77a5 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Thu, 24 Sep 2026 15:24:53 +0200 Subject: [PATCH 2/6] easyrdf fix --- src/Server.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Server.php b/src/Server.php index bab4982..c8e8640 100644 --- a/src/Server.php +++ b/src/Server.php @@ -298,7 +298,7 @@ private function handleSparqlUpdate(Response $response, string $path, $contents) try { // Assuming this is in our native format, turtle - $graph->parse($data, "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); + $graph->parse($data . "\n", "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); // FIXME: Use enums from namespace Pdsinterop\Rdf\Enum\Format instead of 'turtle'? // parse query in contents @@ -312,14 +312,14 @@ private function handleSparqlUpdate(Response $response, string $path, $contents) case "INSERT": // insert $triple(s) into $graph // @CHECKME: Does the Graph Parse here also need an URI? - $graph->parse($triples, "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); // FIXME: The triples here are in sparql format, not in turtle; + $graph->parse($triples . "\n", "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); // FIXME: The triples here are in sparql format, not in turtle; break; case "DELETE": // delete $triples from $graph $deleteGraph = $this->getGraph(); // @CHECKME: Does the Graph Parse here also need an URI? - $deleteGraph->parse($triples, "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); // FIXME: The triples here are in sparql format, not in turtle; + $deleteGraph->parse($triples . "\n", "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); // FIXME: The triples here are in sparql format, not in turtle; $resources = $deleteGraph->resources(); foreach ($resources as $resource) { $properties = $resource->propertyUris(); @@ -455,7 +455,7 @@ private function handleN3Update(Response $response, string $path, $contents): Re try { // Assuming this is in our native format, turtle - $graph->parse($data, "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); + $graph->parse($data . "\n", "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); // FIXME: Use enums from namespace Pdsinterop\Rdf\Enum\Format instead of 'turtle'? $instructions = $this->n3Convert($contents); foreach ($instructions as $key => $value) { @@ -463,14 +463,14 @@ private function handleN3Update(Response $response, string $path, $contents): Re case "insert": // error_log("INSERT"); // error_log($instructions['insert']); - $graph->parse($instructions['insert'], "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); + $graph->parse($instructions['insert'] . "\n", "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); break; case "delete": $deleteGraph = $this->getGraph(); // error_log("DELETE"); // error_log($instructions['delete']); - $deleteGraph->parse($instructions['delete'], "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); + $deleteGraph->parse($instructions['delete'] . "\n", "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); $resources = $deleteGraph->resources(); foreach ($resources as $resource) { $properties = $resource->propertyUris(); @@ -1016,7 +1016,7 @@ private function parseLinkedMetadata(string $path) $graph = $this->getGraph(); try { - $graph->parse($describedByContents, null, '/'.$describedByPath); + $graph->parse($describedByContents . "\n", null, '/'.$describedByPath); } catch (RdfException $exception) { // If the metadata can not be parsed, the resource should still be returned (or a 404) // @CHECKME: Should the upstream add a message to the header or something? @@ -1115,7 +1115,7 @@ private function removeLinkFromMetaFileFor($path): bool try { $contents = $this->filesystem->read($describedByPath); - $graph->parse($contents, 'turtle', '/'.$describedByPath); + $graph->parse($contents . "\n", 'turtle', '/'.$describedByPath); } catch (\Throwable $e) { return false; } From 57c4267642751d9c438837015afd0be2e730fc91 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 28 Sep 2026 15:04:35 +0200 Subject: [PATCH 3/6] update method names to align with flysystem 3 --- src/Server.php | 56 ++++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/src/Server.php b/src/Server.php index c8e8640..5b3518d 100644 --- a/src/Server.php +++ b/src/Server.php @@ -208,9 +208,9 @@ private function handle(string $method, string $path, $contents, $request): Resp } break; case 'POST': - $pathExists = $filesystem->has($path); + $pathExists = $filesystem->fileExists($path); if ($pathExists) { - $mimetype = $filesystem->getMimetype($path); + $mimetype = $filesystem->mimeType($path); } if ($path === "/") { $pathExists = true; @@ -268,7 +268,7 @@ private function handle(string $method, string $path, $contents, $request): Resp $response = $this->handleCreateDirectoryRequest($response, $path); break; default: - if ($filesystem->has($path) === true) { + if ($filesystem->fileExists($path) === true) { $response = $this->handleUpdateRequest($response, $path, $contents); } else { $response = $this->handleCreateRequest($response, $path, $contents); @@ -289,7 +289,7 @@ private function handleSparqlUpdate(Response $response, string $path, $contents) $filesystem = $this->filesystem; $graph = $this->getGraph(); - if ($filesystem->has($path) === false) { + if ($filesystem->fileExists($path) === false) { $data = ''; } else { // read ttl data @@ -349,11 +349,7 @@ private function handleSparqlUpdate(Response $response, string $path, $contents) $output = $graph->serialise("turtle"); // FIXME: Use enums from namespace Pdsinterop\Rdf\Enum\Format? // write ttl data - if ($filesystem->has($path) === true) { - $success = $filesystem->update($path, $output); - } else { - $success = $filesystem->write($path, $output); - } + $success = $filesystem->write($path, $output); $response = $response->withStatus($success ? 201 : 500); @@ -446,7 +442,7 @@ private function handleN3Update(Response $response, string $path, $contents): Re $graph = $this->getGraph(); $n3Graph = $this->getGraph(); - if ($filesystem->has($path) === false) { + if ($filesystem->fileExists($path) === false) { $data = ''; } else { // read ttl data @@ -497,11 +493,7 @@ private function handleN3Update(Response $response, string $path, $contents): Re $output = $graph->serialise("turtle"); // FIXME: Use enums from namespace Pdsinterop\Rdf\Enum\Format? // write ttl data - if ($filesystem->has($path) === true) { - $success = $filesystem->update($path, $output); - } else { - $success = $filesystem->write($path, $output); - } + $success = $filesystem->write($path, $output); $response = $response->withStatus($success ? 201 : 500); @@ -525,7 +517,7 @@ private function handleCreateRequest(Response $response, string $path, $contents { $filesystem = $this->filesystem; - if ($filesystem->has($path) === true) { + if ($filesystem->fileExists($path) === true) { $message = vsprintf(self::ERROR_PUT_EXISTING_RESOURCE, [$path]); $response->getBody()->write($message); $response = $response->withStatus(400); @@ -582,12 +574,12 @@ private function parentPath($path) private function handleCreateDirectoryRequest(Response $response, string $path): Response { $filesystem = $this->filesystem; - if ($filesystem->has($path) === true) { + if ($filesystem->fileExists($path) === true) { $message = vsprintf(self::ERROR_PUT_EXISTING_RESOURCE, [$path]); $response->getBody()->write($message); $response = $response->withStatus(400); } else { - $success = $filesystem->createDir($path); + $success = $filesystem->createDirectory($path); $response = $response->withStatus($success ? 201 : 500); if ($success) { $this->removeLinkFromMetaFileFor($path); @@ -617,8 +609,8 @@ private function handleDeleteRequest(Response $response, string $path, $contents { $filesystem = $this->filesystem; - if ($filesystem->has($path)) { - $mimetype = $filesystem->getMimetype($path); + if ($filesystem->fileExists($path)) { + $mimetype = $filesystem->mimeType($path); if ($mimetype === self::MIME_TYPE_DIRECTORY) { $directoryContents = $filesystem->listContents($path, true); @@ -627,7 +619,7 @@ private function handleDeleteRequest(Response $response, string $path, $contents $message = vsprintf(self::ERROR_CAN_NOT_DELETE_NON_EMPTY_CONTAINER, [$path]); $response->getBody()->write($message); } else { - $success = $filesystem->deleteDir($path); + $success = $filesystem->deleteDirectory($path); if ($success) { $this->sendNotificationUpdate($path, self::NOTIFICATION_TYPE_DELETE); } @@ -656,12 +648,12 @@ private function handleUpdateRequest(Response $response, string $path, string $c { $filesystem = $this->filesystem; - if ($filesystem->has($path) === false) { + if ($filesystem->fileExists($path) === false) { $message = vsprintf(self::ERROR_PUT_NON_EXISTING_RESOURCE, [$path]); $response->getBody()->write($message); $response = $response->withStatus(400); } else { - $success = $filesystem->update($path, $contents); + $success = $filesystem->write($path, $contents); $response = $response->withStatus($success ? 201 : 500); if ($success) { $this->removeLinkFromMetaFileFor($path); @@ -707,12 +699,12 @@ private function handleReadRequest(Response $response, string $path, $contents, '; rel="type"', ]); $response = $response->withStatus(200); - } elseif(($filesystem->has($path) === false) && (($path == ".meta") || ($path == "/.meta"))) { + } elseif(($filesystem->fileExists($path) === false) && (($path == ".meta") || ($path == "/.meta"))) { $contents = ''; $response->getBody()->write($contents); $response = $response->withHeader("Content-type", "text/turtle"); $response = $response->withStatus(200); - } elseif ($filesystem->has($path) === false && $this->hasDescribedBy($path) === false) { + } elseif ($filesystem->fileExists($path) === false && $this->hasDescribedBy($path) === false) { /*/ The file does not exist and no link-metadata is present /*/ $message = vsprintf(self::ERROR_PATH_DOES_NOT_EXIST, [$path]); $response->getBody()->write($message); @@ -722,21 +714,21 @@ private function handleReadRequest(Response $response, string $path, $contents, if ($linkMetadataResponse !== null) { /*/ Link-metadata is present, return the altered response /*/ $response = $linkMetadataResponse; - } elseif ($filesystem->getMimetype($path) === self::MIME_TYPE_DIRECTORY) { + } elseif ($filesystem->mimeType($path) === self::MIME_TYPE_DIRECTORY) { $contents = $this->listDirectoryAsTurtle($path); $response->getBody()->write($contents); $response = $response->withHeader("Content-type", "text/turtle")->withStatus(200); - } elseif ($filesystem->asMime($mime)->has($path)) { + } elseif ($filesystem->asMime($mime)->fileExists($path)) { /*/ The file does exist and no link-metadata is present /*/ $response = $this->addLinkRelationHeaders($response, $path, $mime); if (preg_match('/\.(acl|meta|ttl)$/', $path)) { $mimetype = "text/turtle"; // FIXME: teach flysystem that .acl/.meta/.ttl means text/turtle } else { - $mimetype = $filesystem->asMime($mime)->getMimetype($path); + $mimetype = $filesystem->asMime($mime)->mimeType($path); } - $fileMimeType = $filesystem->asMime('')->getMimetype($path); + $fileMimeType = $filesystem->asMime('')->mimeType($path); if (in_array($fileMimeType, $acceptedMimeTypes)) { $contents = $filesystem->asMime('')->read($path); $mimetype = $fileMimeType; @@ -748,7 +740,7 @@ private function handleReadRequest(Response $response, string $path, $contents, $response->getBody()->write($contents); $response = $response->withHeader("Content-type", $mimetype)->withStatus(200); } else { - // FIXME: we should not get here if the file does not exist, but here we are. It looks like $filesystem->has("/.meta") always returns true even if the file does not exist; + // FIXME: we should not get here if the file does not exist, but here we are. It looks like $filesystem->fileExists("/.meta") always returns true even if the file does not exist; if ($path == "/.meta") { $contents = ''; $response->getBody()->write($contents); @@ -1090,7 +1082,7 @@ private function findPath(array $rdfPaths, string $path) foreach ($rdfPaths as $rdfPath) { if ( strrpos($path, $rdfPath) === 0 - && $this->filesystem->has($rdfPath) + && $this->filesystem->fileExists($rdfPath) ) { // @FIXME: We have no way of knowing if the file is a directory or a file. // This means that, unless we make a trialing slash `/` required, @@ -1151,7 +1143,7 @@ private function removeLinkFromMetaFileFor($path): bool if ($changed) { $changedContents = $graph->serialise('turtle'); try { - $result = $this->filesystem->update($describedByPath, $changedContents); + $result = $this->filesystem->write($describedByPath, $changedContents); } catch (FileNotFoundException $exception) { // $result is already false; } From 577fd9fd51e8f324048a1362ad2f0f9d04897c54 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 28 Sep 2026 15:05:07 +0200 Subject: [PATCH 4/6] use dev-branch flysystem-3 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ad83f64..0301788 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "laminas/laminas-diactoros": "^3", "league/flysystem": "^1.0", "mjrider/flysystem-factory": "^0.7", - "pdsinterop/flysystem-rdf": "^0.6.1", + "pdsinterop/flysystem-rdf": "dev-feature/flysystem-3", "pietercolpaert/hardf": "^0.3", "psr/http-factory": "^1.0", "psr/http-message": "^1.0" From 9716ce2056e997e33d30096dc781d90a17f3e9ae Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 28 Sep 2026 15:06:42 +0200 Subject: [PATCH 5/6] drop php 8.0, 8.1 and 8.2. Add 8.4 --- .github/workflows/php.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 33c065c..b871f2c 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -74,10 +74,8 @@ jobs: fail-fast: false matrix: php: - - '8.0' # from 2020-11 to 2022-11 (2023-11) - - '8.1' # from 2021-11 to 2023-11 (2025-12) - - '8.2' # from 2022-12 to 2024-12 (2026-12) - '8.3' # from 2023-11 to 2025-12 (2027-12) + - '8.4' steps: - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 @@ -118,10 +116,8 @@ jobs: fail-fast: false matrix: php: - - '8.0' # from 2020-11 to 2022-11 (2023-11) - - '8.1' # from 2021-11 to 2023-11 (2025-12) - - '8.2' # from 2022-12 to 2024-12 (2026-12) - '8.3' # from 2023-11 to 2025-12 (2027-12) + - '8.4' steps: - uses: actions/checkout@v4 - uses: docker://pipelinecomponents/php-codesniffer From f7a254174474e46c34e9eb943520b6c4379b2fd8 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 28 Sep 2026 15:07:45 +0200 Subject: [PATCH 6/6] Revert "easyrdf fix" This reverts commit 24d5f3db71fd3a21bf44f67516d1606260dc77a5. --- src/Server.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Server.php b/src/Server.php index 5b3518d..28f8c87 100644 --- a/src/Server.php +++ b/src/Server.php @@ -298,7 +298,7 @@ private function handleSparqlUpdate(Response $response, string $path, $contents) try { // Assuming this is in our native format, turtle - $graph->parse($data . "\n", "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); + $graph->parse($data, "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); // FIXME: Use enums from namespace Pdsinterop\Rdf\Enum\Format instead of 'turtle'? // parse query in contents @@ -312,14 +312,14 @@ private function handleSparqlUpdate(Response $response, string $path, $contents) case "INSERT": // insert $triple(s) into $graph // @CHECKME: Does the Graph Parse here also need an URI? - $graph->parse($triples . "\n", "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); // FIXME: The triples here are in sparql format, not in turtle; + $graph->parse($triples, "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); // FIXME: The triples here are in sparql format, not in turtle; break; case "DELETE": // delete $triples from $graph $deleteGraph = $this->getGraph(); // @CHECKME: Does the Graph Parse here also need an URI? - $deleteGraph->parse($triples . "\n", "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); // FIXME: The triples here are in sparql format, not in turtle; + $deleteGraph->parse($triples, "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); // FIXME: The triples here are in sparql format, not in turtle; $resources = $deleteGraph->resources(); foreach ($resources as $resource) { $properties = $resource->propertyUris(); @@ -451,7 +451,7 @@ private function handleN3Update(Response $response, string $path, $contents): Re try { // Assuming this is in our native format, turtle - $graph->parse($data . "\n", "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); + $graph->parse($data, "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); // FIXME: Use enums from namespace Pdsinterop\Rdf\Enum\Format instead of 'turtle'? $instructions = $this->n3Convert($contents); foreach ($instructions as $key => $value) { @@ -459,14 +459,14 @@ private function handleN3Update(Response $response, string $path, $contents): Re case "insert": // error_log("INSERT"); // error_log($instructions['insert']); - $graph->parse($instructions['insert'] . "\n", "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); + $graph->parse($instructions['insert'], "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); break; case "delete": $deleteGraph = $this->getGraph(); // error_log("DELETE"); // error_log($instructions['delete']); - $deleteGraph->parse($instructions['delete'] . "\n", "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); + $deleteGraph->parse($instructions['delete'], "turtle", $this->baseUrl . $this->basePath . $this->requestedPath); $resources = $deleteGraph->resources(); foreach ($resources as $resource) { $properties = $resource->propertyUris(); @@ -1008,7 +1008,7 @@ private function parseLinkedMetadata(string $path) $graph = $this->getGraph(); try { - $graph->parse($describedByContents . "\n", null, '/'.$describedByPath); + $graph->parse($describedByContents, null, '/'.$describedByPath); } catch (RdfException $exception) { // If the metadata can not be parsed, the resource should still be returned (or a 404) // @CHECKME: Should the upstream add a message to the header or something? @@ -1107,7 +1107,7 @@ private function removeLinkFromMetaFileFor($path): bool try { $contents = $this->filesystem->read($describedByPath); - $graph->parse($contents . "\n", 'turtle', '/'.$describedByPath); + $graph->parse($contents, 'turtle', '/'.$describedByPath); } catch (\Throwable $e) { return false; }