Updated all dependencies and prepared for PHP 8

This commit is contained in:
2026-06-19 09:37:22 +00:00
parent 941c9104dc
commit 5f9f6ca2ff
21 changed files with 3334 additions and 2643 deletions
+47 -41
View File
@@ -10,9 +10,11 @@ use InvalidArgumentException;
use Psr\Http\Message\RequestInterface, Psr\Http\Message\ResponseInterface;
use Psr\Container\ContainerInterface;
use Slim\App;
use Tuupola\Middleware\CorsMiddleware;;
use Slim\Http\Environment, Slim\Http\Uri, Slim\Http\Response,
Slim\Http\Request, Slim\Http\Headers;
use Slim\Factory\AppFactory;
use Slim\Factory\ServerRequestCreatorFactory;
use Slim\ResponseEmitter;
use Slim\Psr7\Response;
use Tuupola\Middleware\CorsMiddleware;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Psr7\ServerRequest;
@@ -34,17 +36,16 @@ class Router {
public function __construct(Engine $engine, ObjectRetriever $objectRetriever,
ContainerInterface $container) {
$this->engine = $engine;
$this->objectRetriever = $objectRetriever;
$this->container = $container;
}
private function getRequestHeaders(Request $request) {
$headers = new Headers; // this instance is required to access the "normalizeKey" method
private function getRequestHeaders(RequestInterface $request) {
$output = [];
foreach (array_keys($request->getHeaders()) as $key) {
$key = $headers->normalizeKey($key);
$key = strtolower($key);
if (substr($key, 0, 9) == 'c-phpmae-' || $key == 'host') {
// do not forward "Host" header or custom phpMAE headers
continue;
@@ -83,14 +84,14 @@ class Router {
$router = $this;
$engine = $this->engine;
$retriever = $this->getObjectRetriever(new IRI($object->getId()));
foreach ($routes as $r) {
if (!$reader->hasProperty($r, 'wa:hasVerb') || !$reader->hasProperty($r, 'wa:hasPath'))
throw new PhpMAEException("Incomplete route configuration! Routes must have wa:hasVerb and wa:hasPath.");
$app->map([ $reader->getFirstValueString($r, 'wa:hasVerb') ],
$reader->getFirstValueString($r, 'wa:hasPath'),
function(RequestInterface $request, ResponseInterface $response, $args) use ($r, $reader, $router, $engine, $retriever, $object) {
function(RequestInterface $request, ResponseInterface $response, $args) use ($r, $reader, $router, $engine, $retriever, $object) {
if ($reader->hasProperty($r, 'phpmae:runsClass')) {
try {
$params = [];
@@ -112,10 +113,13 @@ class Router {
$params = $request->getQueryParams();
}
} catch (InvalidArgumentException $e) {
return (new Response(400))->withJson([
$errorResponse = (new Response(400))
->withHeader('Content-Type', 'application/json');
$errorResponse->getBody()->write(json_encode([
'error' => 'InputValidationFailed',
'message' => $e->getMessage()
]);
]));
return $errorResponse;
}
// Add static parameters from Router
@@ -158,7 +162,10 @@ class Router {
if (isset($rpcResponse['result'])) {
return $engine->generateResponse($rpcResponse['result']);
} else {
return (new Response(500))->withJson($rpcResponse);
$errResponse = (new Response(500))
->withHeader('Content-Type', 'application/json');
$errResponse->getBody()->write(json_encode($rpcResponse));
return $errResponse;
}
} else {
// Generic class execution (invokable)
@@ -167,15 +174,16 @@ class Router {
} elseif ($reader->hasProperty($r, 'phpmae:redirectsToURL')) {
// Route to redirect to a specific external URL
return (new Response)->withRedirect($reader->getFirstValueString($r, 'phpmae:redirectsToURL'));
return (new Response(302))
->withHeader('Location', $reader->getFirstValueString($r, 'phpmae:redirectsToURL'));
} elseif ($reader->hasProperty($r, 'phpmae:redirectsToBaseURL')) {
// Route to redirect to an external base URL
$baseUrl = $reader->getFirstValueIRI($r, 'phpmae:redirectsToBaseURL');
$uri = $request->getUri();
$targetUrl = (string)$baseUrl->resolve(substr($uri->getPath(), 1) . ($uri->getQuery() != '' ? '?'.$uri->getQuery() : ''));
return (new Response)->withRedirect($targetUrl);
return (new Response(302))->withHeader('Location', $targetUrl);
} elseif ($reader->hasProperty($r, 'phpmae:proxiesRequestsToBaseURL')) {
// Route to proxy requests to an external URL
@@ -197,25 +205,31 @@ class Router {
// Rule to serve an attached file
$etag = '"'.md5($reader->getFirstValueString($object, 'co:isAtRevision')
.'+'.$reader->getFirstValueString($r, 'phpmae:servesStaticFileAttachment')).'"';
if ($request->hasHeader('If-None-Match') && strpos($request->getHeaderLine('If-None-Match'), $etag) > -1) {
// Can use cached version
return (new Response(304))->withHeader('ETag', $etag)
return (new Response(304))
->withHeader('ETag', $etag)
->withHeader('Cache-Control', 'max-age='.self::STATIC_CACHE_TTL.', public');
}
$attachmentContent = $retriever->getAttachment(new IRI($object->getId()),
$reader->getFirstValueString($r, 'phpmae:servesStaticFileAttachment'));
if (!isset($attachmentContent))
return (new Response(501))->write("Requested static file attachment cannot be found.");
if (!isset($attachmentContent)) {
$notFoundResponse = new Response(501);
$notFoundResponse->getBody()->write("Requested static file attachment cannot be found.");
return $notFoundResponse;
}
return $engine->generateResponse($attachmentContent)
->withHeader('ETag', $etag)
->withHeader('Cache-Control', 'max-age='.self::STATIC_CACHE_TTL.', public');
} else {
// Route has no implementation
return (new Response(501))->write("Route implementation not available or no access granted.");
$notImplResponse = new Response(501);
$notImplResponse->getBody()->write("Route implementation not available or no access granted.");
return $notImplResponse;
}
});
}
@@ -235,26 +249,20 @@ class Router {
* Setup and run router.
*/
public function run() {
try {
try {
$modes = explode('|', $this->container->get('mode'));
$fallback = false;
$configuration = [
'settings' => [
'displayErrorDetails' => true,
],
];
$c = new \Slim\Container($configuration);
$app = new App($c);
$app = AppFactory::create();
$serverRequest = ServerRequestCreatorFactory::create()->createServerRequestFromGlobals();
$router = null;
$env = new Environment($_SERVER);
foreach ($modes as $m) {
switch ($m) {
case 'router:vhost':
if ($router == null) {
$uri = Uri::createFromEnvironment($env);
if ($uri->getHost() == 'localhost' || filter_var($uri->getHost(), FILTER_VALIDATE_IP) !== false) continue;
$uri = $serverRequest->getUri();
if ($uri->getHost() == 'localhost' || filter_var($uri->getHost(), FILTER_VALIDATE_IP) !== false) break;
$namespace = $this->objectRetriever->get('coid://'.$uri->getHost());
if (isset($namespace) && $routerCoid = $namespace->getProperty('coid://phpmae.dev/hasRouter'))
@@ -263,9 +271,8 @@ class Router {
break;
case 'router:header':
if ($router == null) {
$request = Request::createFromEnvironment($env);
if ($request->hasHeader('C-PhpMae-Router-COID'))
$router = $this->getRouter(new IRI($request->getHeaderLine('C-PhpMae-Router-COID')));
if ($serverRequest->hasHeader('C-PhpMae-Router-COID'))
$router = $this->getRouter(new IRI($serverRequest->getHeaderLine('C-PhpMae-Router-COID')));
}
break;
case 'default':
@@ -281,7 +288,7 @@ class Router {
if (isset($router)) {
$this->configure($app, $router);
$response = $app->run(true);
$response = $app->handle($serverRequest);
} elseif ($fallback) {
$this->container->get(Engine::class)
->run();
@@ -292,11 +299,10 @@ class Router {
} catch (PhpMAEException $e) {
// Create plain-text error response
$response = (new Response(500))
->withHeader('Content-Type', 'text/plain')
->write($e->getMessage());
$response = (new Response(500))->withHeader('Content-Type', 'text/plain');
$response->getBody()->write($e->getMessage());
}
$app->respond($response);
(new ResponseEmitter())->emit($response);
}
}
}