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 -43
View File
@@ -10,8 +10,9 @@ use Psr\Http\Message\RequestInterface, Psr\Http\Message\ResponseInterface,
Psr\Http\Message\ServerRequestInterface;
use Psr\Container\ContainerInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Slim\App;
use Slim\Http\Headers, Slim\Http\Request, Slim\Http\Response, Slim\Http\Environment;
use Slim\Psr7\Response;
use Slim\Factory\ServerRequestCreatorFactory;
use Slim\ResponseEmitter;
use ML\IRI\IRI;
use ML\JsonLD\Node;
use Tuupola\Middleware\HttpBasicAuthentication,
@@ -27,7 +28,7 @@ use CloudObjects\PhpMAE\Exceptions\PhpMAEException;
class Engine implements RequestHandlerInterface {
const SKEY = '__self';
const PREPARE_TIME_LIMIT = 2;
const CLASS_TIME_LIMIT = 5;
@@ -35,7 +36,6 @@ class Engine implements RequestHandlerInterface {
private $objectRetriever;
private $classRepository;
private $slim;
private $container;
private $reader;
@@ -43,12 +43,11 @@ class Engine implements RequestHandlerInterface {
private $runClass;
public function __construct(ObjectRetriever $objectRetriever,
ClassRepository $classRepository, App $slim,
ClassRepository $classRepository,
ErrorHandler $errorHandler, ContainerInterface $container) {
$this->objectRetriever = $objectRetriever;
$this->classRepository = $classRepository;
$this->slim = $slim;
$this->container = $container;
$this->reader = new NodeReader([
'prefixes' => [
@@ -62,7 +61,7 @@ class Engine implements RequestHandlerInterface {
}, $errorHandler); // see: http://stackoverflow.com/questions/4410632/handle-fatal-errors-in-php-using-register-shutdown-function
}
private function isObjectPublic() {
private function isObjectPublic() {
return ($this->reader->hasProperty($this->object, 'co:isVisibleTo')
&& $this->reader->getFirstValueIRI($this->object, 'co:isVisibleTo')
->equals(self::CO_PUBLIC)
@@ -85,13 +84,13 @@ class Engine implements RequestHandlerInterface {
return new CorsMiddleware($defaultConfig); // every origin is allowed, by class
$origins = $this->reader->getAllValuesString($this->object, 'phpmae:allowsCORSOrigin');
if ($this->container->has('global_cors_origins'))
$origins = array_merge($origins, explode('|', $this->container->get('global_cors_origins')));
if (count($origins) == 0 || trim($origins[0]) == '')
return null; // no CORS enabled
return new CorsMiddleware(array_merge($defaultConfig, [
'origin' => $origins
])); // configured CORS middleware
@@ -120,14 +119,14 @@ class Engine implements RequestHandlerInterface {
== SharedSecretAuthentication::RESULT_OK);
if ($authResult != true)
continue;
if (substr($as, 14) == 'runclass')
$authenticated = (substr($object->getId(), 7, strlen($args['user']) +1) == $args['user'].'/');
else
$authenticated = (substr($as, 14) == 'coid://'.$args['user']);
} elseif (substr($as, 0, 4) != 'none')
throw new PhpMAEException("Unsupported authentication scheme!");
if ($authenticated == true)
break;
}
@@ -149,14 +148,14 @@ class Engine implements RequestHandlerInterface {
if ($this->reader->getFirstValueBool($this->object, 'phpmae:allowsGETRequests'))
$input = $request->getQueryParams();
else
return (new Response(405));
return new Response(405);
} elseif ($request->getMethod() == 'POST') {
// POST is always allowed
$input = $request->getParsedBody();
if (!is_array($input))
$input = [];
} else
return (new Response(405));
return new Response(405);
set_time_limit($this->container->has('execution_time_limit')
? $this->container->get('execution_time_limit') : self::CLASS_TIME_LIMIT);
@@ -171,25 +170,29 @@ class Engine implements RequestHandlerInterface {
*/
public function generateResponse($content) {
$lowercaseContent = is_string($content) ? strtolower($content) : '';
if (!isset($content))
if (!isset($content)) {
// Empty response
$response = new Response(204);
elseif (is_string($content) && (substr($lowercaseContent, 0, 5) == '<html' || substr($lowercaseContent, 0, 14) == '<!doctype html'))
} elseif (is_string($content) && (substr($lowercaseContent, 0, 5) == '<html' || substr($lowercaseContent, 0, 14) == '<!doctype html')) {
// HTML response
$response = (new Response)->write($content);
elseif (is_string($content) && (substr($lowercaseContent, 0, 7) == 'http://' || substr($lowercaseContent, 0, 8) == 'https://'))
$response = new Response(200);
$response->getBody()->write($content);
} elseif (is_string($content) && (substr($lowercaseContent, 0, 7) == 'http://' || substr($lowercaseContent, 0, 8) == 'https://')) {
// Redirect response
$response = (new Response)->withRedirect($content);
elseif (is_string($content) || is_numeric($content))
$response = (new Response(302))->withHeader('Location', $content);
} elseif (is_string($content) || is_numeric($content)) {
// Plain text response
$response = (new Response)->withHeader('Content-Type', 'text/plain')->write($content);
elseif (is_object($content) && in_array(ResponseInterface::class, class_implements($content)))
$response = (new Response(200))->withHeader('Content-Type', 'text/plain');
$response->getBody()->write((string)$content);
} elseif (is_object($content) && in_array(ResponseInterface::class, class_implements($content))) {
// Existing response to pass through
$response = $content;
else
} else {
// JSON response (default)
$response = (new Response)->withJson($content);
$response = (new Response(200))->withHeader('Content-Type', 'application/json');
$response->getBody()->write(json_encode($content));
}
// TODO: add support for XML
// Add cookies if any
@@ -199,7 +202,7 @@ class Engine implements RequestHandlerInterface {
$response = FigResponseCookies::set($response, $cookie);
}
}
return $response;
}
@@ -219,7 +222,8 @@ class Engine implements RequestHandlerInterface {
* Start execution of a request.
*/
public function execute(RequestInterface $request) {
$path = rtrim($request->getUri()->getBasePath().$request->getUri()->getPath(), '/');
$path = $request->getUri()->getPath();
switch ($path) {
case "":
case "/":
@@ -227,7 +231,7 @@ class Engine implements RequestHandlerInterface {
$file = ($this->container
->get(InteractiveRunController::class)
->isEnabled()) ? 'app.html' : 'app_disabled.html';
return $this->generateResponse(file_get_contents(__DIR__.'/../static/'.$file));
case "/run":
// Run interactive code request
@@ -243,7 +247,8 @@ class Engine implements RequestHandlerInterface {
if (file_exists(__DIR__.'/../static'.$path)) {
// Proxy for static files
$filename = realpath(__DIR__.'/../static'.$path);
$response = (new Response)->write(file_get_contents($filename));
$response = new Response(200);
$response->getBody()->write(file_get_contents($filename));
switch (pathinfo($filename, PATHINFO_EXTENSION)) {
case "css":
return $response->withHeader('Content-Type', 'text/css');
@@ -252,12 +257,12 @@ class Engine implements RequestHandlerInterface {
default:
return $response;
}
}
$coid = COIDParser::fromString(substr($path, 1));
$this->loadRunClass($coid, $request);
// Process a standard request for a phpMAE class
$queue = [
$this->getCORSMiddleware(),
@@ -266,7 +271,7 @@ class Engine implements RequestHandlerInterface {
];
$relay = new Relay(
array_filter($queue, function ($q) {
return $q !== null;
return $q !== null;
})
);
return $relay->handle($request);
@@ -278,7 +283,7 @@ class Engine implements RequestHandlerInterface {
*/
public function loadRunClass(IRI $coid, RequestInterface $request = null) {
if (COIDParser::isValidCOID($coid) && COIDParser::getType($coid) != COIDParser::COID_ROOT) {
$this->object = $this->objectRetriever->get($coid);
$this->object = $this->objectRetriever->getObjectNode($coid);
if (!isset($this->object))
throw new PhpMAEException("The object <" . (string)$coid . "> does not exist or this phpMAE instance is not allowed to access it.");
$this->runClass = $this->classRepository->createInstance($this->object, $request);
@@ -315,18 +320,17 @@ class Engine implements RequestHandlerInterface {
public function run() {
set_time_limit(self::PREPARE_TIME_LIMIT);
$env = new Environment($_SERVER);
$request = Request::createFromEnvironment($env);
$request = ServerRequestCreatorFactory::create()->createServerRequestFromGlobals();
try {
$response = $this->execute($request);
} 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());
}
$this->slim->respond($response);
(new ResponseEmitter())->emit($response);
}
}
}