Merge pull request #548 from flightphp/php8-named-arguments-support

PHP 8 named arguments support
master
n0nag0n 2 weeks ago committed by GitHub
commit 22570b9987
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -33,14 +33,17 @@
}, },
"autoload-dev": { "autoload-dev": {
"classmap": [ "classmap": [
"tests/classes/User.php", "tests/classes/"
"tests/classes/Hello.php", ],
"tests/classes/Factory.php", "psr-4": {
"tests/classes/TesterClass.php" "Tests\\PHP8\\": [
] "tests/named-arguments"
]
}
}, },
"require-dev": { "require-dev": {
"ext-pdo_sqlite": "*", "ext-pdo_sqlite": "*",
"flightphp/container": "^1.0",
"flightphp/runway": "^0.2.3 || ^1.0", "flightphp/runway": "^0.2.3 || ^1.0",
"league/container": "^4.2", "league/container": "^4.2",
"level-2/dice": "^4.0", "level-2/dice": "^4.0",

@ -16,6 +16,7 @@ use flight\net\Router;
use flight\template\View; use flight\template\View;
use Throwable; use Throwable;
use flight\net\Route; use flight\net\Route;
use Psr\Container\ContainerInterface;
/** /**
* The Engine class contains the core functionality of the framework. * The Engine class contains the core functionality of the framework.
@ -265,9 +266,9 @@ class Engine
/** /**
* Registers the container handler * Registers the container handler
* *
* @param callable|object $containerHandler Callback function or PSR-11 Container object that sets the container and how it will inject classes * @template T of object
* *
* @return void * @param ContainerInterface|callable(class-string<T> $id, array<int|string, mixed> $params): ?T $containerHandler Callback function or PSR-11 Container object that sets the container and how it will inject classes
*/ */
public function registerContainerHandler($containerHandler): void public function registerContainerHandler($containerHandler): void
{ {

@ -9,6 +9,7 @@ use flight\net\Router;
use flight\template\View; use flight\template\View;
use flight\net\Route; use flight\net\Route;
use flight\core\EventDispatcher; use flight\core\EventDispatcher;
use Psr\Container\ContainerInterface;
require_once __DIR__ . '/autoload.php'; require_once __DIR__ . '/autoload.php';
@ -18,9 +19,11 @@ require_once __DIR__ . '/autoload.php';
* @license MIT, http://flightphp.com/license * @license MIT, http://flightphp.com/license
* @copyright Copyright (c) 2011, Mike Cao <mike@mikecao.com> * @copyright Copyright (c) 2011, Mike Cao <mike@mikecao.com>
* *
* @template T of object
*
* # Core methods * # Core methods
* @method static void start() Starts the framework. * @method static void start() Starts the framework.
* @method static void path(string $path) Adds a path for autoloading classes. * @method static void path(string $dir) Adds a path for autoloading classes.
* @method static void stop(?int $code = null) Stops the framework and sends a response. * @method static void stop(?int $code = null) Stops the framework and sends a response.
* @method static void halt(int $code = 200, string $message = '', bool $actuallyExit = true) * @method static void halt(int $code = 200, string $message = '', bool $actuallyExit = true)
* Stop the framework with an optional status code and message. * Stop the framework with an optional status code and message.
@ -28,7 +31,10 @@ require_once __DIR__ . '/autoload.php';
* Registers a class to a framework method. * Registers a class to a framework method.
* @method static void unregister(string $methodName) * @method static void unregister(string $methodName)
* Unregisters a class to a framework method. * Unregisters a class to a framework method.
* @method static void registerContainerHandler(callable|object $containerHandler) Registers a container handler. * @method static void registerContainerHandler(ContainerInterface|callable(class-string<T> $id, array<int|string, mixed> $params): ?T $containerHandler) Registers a container handler.
*
* # Class registration
* @method EventDispatcher eventDispatcher() Gets event dispatcher
* *
* # Class registration * # Class registration
* @method EventDispatcher eventDispatcher() Gets event dispatcher * @method EventDispatcher eventDispatcher() Gets event dispatcher
@ -104,6 +110,7 @@ class Flight
*/ */
private function __construct() private function __construct()
{ {
//
} }
/** /**
@ -114,6 +121,7 @@ class Flight
*/ */
private function __clone() private function __clone()
{ {
//
} }
/** /**

@ -106,7 +106,7 @@ class RouteCommand extends AbstractBaseCommand
if ($showAll === true) { if ($showAll === true) {
$boolval = true; $boolval = true;
} else { } else {
$methods = [ 'GET', 'POST', 'PUT', 'DELETE', 'PATCH' ]; $methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'];
foreach ($methods as $method) { foreach ($methods as $method) {
$lowercaseMethod = strtolower($method); $lowercaseMethod = strtolower($method);
if ( if (

@ -52,7 +52,9 @@ class Dispatcher
/** /**
* Sets the dependency injection container handler. * Sets the dependency injection container handler.
* *
* @param ContainerInterface|(callable(string $classString, array<int, mixed> $params): (null|object)) $containerHandler * @template T of object
*
* @param ContainerInterface|(callable(class-string<T> $classString, array<int, mixed> $params): ?T) $containerHandler
* Dependency injection container. * Dependency injection container.
* *
* @throws InvalidArgumentException If $containerHandler is not a `callable` or instance of `Psr\Container\ContainerInterface`. * @throws InvalidArgumentException If $containerHandler is not a `callable` or instance of `Psr\Container\ContainerInterface`.
@ -231,7 +233,7 @@ class Dispatcher
if ($parametersNumber === 1) { if ($parametersNumber === 1) {
/** @disregard &$params in after filters are deprecated. */ /** @disregard &$params in after filters are deprecated. */
$callback = fn (array &$params, &$output) => $callback($output); $callback = fn(array &$params, &$output) => $callback($output);
} }
} }
@ -437,11 +439,12 @@ class Dispatcher
public function resolveContainerClass(string $class, array &$params) public function resolveContainerClass(string $class, array &$params)
{ {
// PSR-11 // PSR-11
if ( if (is_a($this->containerHandler, '\Psr\Container\ContainerInterface')) {
is_a($this->containerHandler, '\Psr\Container\ContainerInterface') try {
&& $this->containerHandler->has($class) return $this->containerHandler->get($class);
) { } catch (Throwable $exception) {
return $this->containerHandler->get($class); return null;
}
} }
// Just a callable where you configure the behavior (Dice, PHP-DI, etc.) // Just a callable where you configure the behavior (Dice, PHP-DI, etc.)

@ -211,8 +211,8 @@ class Request
$this->data->setData($data); $this->data->setData($data);
} }
} }
// Check PUT, PATCH, DELETE for application/x-www-form-urlencoded data // Check PUT, PATCH, DELETE for application/x-www-form-urlencoded data
} elseif (in_array($this->method, [ 'PUT', 'DELETE', 'PATCH' ], true) === true) { } elseif (in_array($this->method, ['PUT', 'DELETE', 'PATCH'], true) === true) {
$body = $this->getBody(); $body = $this->getBody();
if ($body !== '') { if ($body !== '') {
$data = []; $data = [];

@ -5,4 +5,5 @@ declare(strict_types=1);
// This file is only here so that the PHP8 attribute for doesn't throw an error in files // This file is only here so that the PHP8 attribute for doesn't throw an error in files
class ReturnTypeWillChange class ReturnTypeWillChange
{ {
//
} }

@ -7,6 +7,7 @@ parameters:
excludePaths: excludePaths:
- vendor - vendor
- flight/util/ReturnTypeWillChange.php - flight/util/ReturnTypeWillChange.php
- tests/named-arguments
paths: paths:
- flight - flight
- index.php - index.php

@ -22,6 +22,7 @@
<testsuites> <testsuites>
<testsuite name="default"> <testsuite name="default">
<directory>tests/</directory> <directory>tests/</directory>
<exclude>tests/named-arguments/</exclude>
</testsuite> </testsuite>
</testsuites> </testsuites>
<logging /> <logging />

@ -4,7 +4,6 @@ declare(strict_types=1);
namespace tests; namespace tests;
use ErrorException;
use Exception; use Exception;
use flight\database\PdoWrapper; use flight\database\PdoWrapper;
use flight\Engine; use flight\Engine;

@ -389,7 +389,7 @@ class FlightTest extends TestCase
html; html;
// if windows replace \n with \r\n // if windows replace \n with \r\n
$html = str_replace("\n", PHP_EOL, $html); $html = str_replace(["\n", "\r\n"], PHP_EOL, $html);
$this->expectOutputString($html); $this->expectOutputString($html);

@ -233,8 +233,8 @@ class ViewTest extends TestCase
html; html;
$html1 = str_replace("\n", PHP_EOL, $html1); $html1 = str_replace(["\n", "\r\n"], PHP_EOL, $html1);
$html2 = str_replace("\n", PHP_EOL, $html2); $html2 = str_replace(["\n", "\r\n"], PHP_EOL, $html2);
return [ return [
[ [

@ -105,15 +105,22 @@ PHP;
$app->handle(['runway', 'routes']); $app->handle(['runway', 'routes']);
$this->assertStringContainsString('Routes', file_get_contents(static::$ou)); $this->assertStringContainsString('Routes', file_get_contents(static::$ou));
$this->assertStringContainsString('+---------+-----------+-------+----------+----------------+ $expected = <<<'output'
| Pattern | Methods | Alias | Streamed | Middleware | +---------+-----------+-------+----------+----------------+
+---------+-----------+-------+----------+----------------+ | Pattern | Methods | Alias | Streamed | Middleware |
| / | GET, HEAD | | No | - | +---------+-----------+-------+----------+----------------+
| /post | POST | | No | Closure | | / | GET, HEAD | | No | - |
| /delete | DELETE | | No | - | | /post | POST | | No | Closure |
| /put | PUT | | No | - | | /delete | DELETE | | No | - |
| /patch | PATCH | | No | Bad Middleware | | /put | PUT | | No | - |
+---------+-----------+-------+----------+----------------+', $this->removeColors(file_get_contents(static::$ou))); | /patch | PATCH | | No | Bad Middleware |
+---------+-----------+-------+----------+----------------+
output;
$this->assertStringContainsString(
$expected,
$this->removeColors(file_get_contents(static::$ou))
);
} }
public function testGetPostRoute() public function testGetPostRoute()

@ -0,0 +1,8 @@
<?php
declare(strict_types=1);
class ExampleClass
{
//
}

@ -0,0 +1,128 @@
<?php
declare(strict_types=1);
namespace Tests\PHP8;
use DateTimeImmutable;
use ExampleClass;
use Flight;
use flight\Container;
use flight\Engine;
use flight\net\Route;
use PHPUnit\Framework\TestCase;
use stdClass;
final class FlightTest extends TestCase
{
private Engine $engine;
protected function setUp(): void
{
$this->engine = new Engine;
Flight::init();
Flight::setEngine($this->engine);
}
//////////////////
// CORE METHODS //
//////////////////
public function test_path(): void
{
Flight::path(dir: __DIR__);
$exampleObject = new ExampleClass();
self::assertInstanceOf(ExampleClass::class, $exampleObject);
}
public function test_stop_with_code(): void
{
Flight::stop(code: 500);
self::expectOutputString('');
self::assertSame(500, Flight::response()->status());
}
public function test_halt(): void
{
Flight::halt(actuallyExit: false, code: 500, message: 'Test');
self::expectOutputString('Test');
self::assertSame(500, Flight::response()->status());
}
public function test_register(): void
{
Flight::register(
class: stdClass::class,
name: 'customClass',
callback: static function (stdClass $object): void {
$object->property = 'value';
},
params: []
);
$object = Flight::customClass();
self::assertInstanceOf(stdClass::class, $object);
self::assertObjectHasProperty('property', $object);
self::assertSame('value', $object->property);
Flight::unregister(methodName: 'customClass');
}
public function test_register_container(): void
{
$dateTime = new DateTimeImmutable();
$controller = new class($dateTime) {
public function __construct(private DateTimeImmutable $dateTime)
{
//
}
public function test(): void
{
echo $this->dateTime->format('Y-m-d');
}
};
Flight::registerContainerHandler(
containerHandler: new Container()
);
Flight::request()->url = '/test';
Flight::route(
pass_route: true,
alias: 'testRoute',
callback: [$controller::class, 'test'],
pattern: '/test'
);
self::expectOutputString($dateTime->format('Y-m-d'));
Flight::start();
}
/////////////////////
// ROUTING METHODS //
/////////////////////
public function test_static_route(): void
{
Flight::request()->url = '/test';
$route = Flight::route(
pass_route: true,
alias: 'testRoute',
callback: function () {
echo 'test';
},
pattern: '/test'
);
self::assertInstanceOf(Route::class, $route);
self::expectOutputString('test');
Flight::start();
}
}
Loading…
Cancel
Save