Skip to content

Commit

Permalink
Fix server request for root services (#1169)
Browse files Browse the repository at this point in the history
  • Loading branch information
roxblnfk committed Nov 25, 2024
1 parent 67783c4 commit f2b3268
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 2 deletions.
4 changes: 3 additions & 1 deletion src/Core/src/Exception/Container/RecursiveProxyException.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@

namespace Spiral\Core\Exception\Container;

use Psr\Container\NotFoundExceptionInterface;

/**
* Recursion can occur due to improper container configuration or
* an unplanned exit from the scope by the execution thread.
*/
class RecursiveProxyException extends ContainerException
class RecursiveProxyException extends ContainerException implements NotFoundExceptionInterface
{
public function __construct(
public readonly string $alias,
Expand Down
12 changes: 12 additions & 0 deletions src/Framework/Bootloader/Http/HttpBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Spiral\Core\BinderInterface;
use Spiral\Core\Container;
use Spiral\Core\Container\Autowire;
use Spiral\Core\Exception\ScopeException;
use Spiral\Core\InvokerInterface;
use Spiral\Framework\Spiral;
use Spiral\Http\Config\HttpConfig;
Expand Down Expand Up @@ -48,6 +49,17 @@ public function defineDependencies(): array

public function defineSingletons(): array
{
$this->binder->bind(
RequestInterface::class,
new \Spiral\Core\Config\Proxy(
interface: RequestInterface::class,
fallbackFactory: static fn (ContainerInterface $c) => throw new ScopeException(
'Unable to receive current Server Request. '
. 'Try to define the service in the `http` scope or use the Poxy attribute.',
),
),
);

$httpBinder = $this->binder->getBinder(Spiral::Http);

$httpBinder->bindSingleton(Http::class, [self::class, 'httpCore']);
Expand Down
2 changes: 1 addition & 1 deletion src/Framework/Bootloader/Http/SessionBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function defineBindings(): array
SessionInterface::class,
new Proxy(SessionInterface::class, false, $this->resolveSession(...)),
);
$this->binder->bind(SessionInterface::class, new Proxy(SessionInterface::class, true), );
$this->binder->bind(SessionInterface::class, new Proxy(SessionInterface::class, true));

return [];
}
Expand Down
22 changes: 22 additions & 0 deletions src/Router/tests/ContainerScopeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use Spiral\Router\Target\Group;
use Spiral\Testing\Attribute\TestScope;
use Spiral\Tests\Router\Fixtures\TestController;
use Spiral\Tests\Router\Fixtures\UserContextBootloader;
use Spiral\Tests\Router\Fixtures\UserContextController;
use Spiral\Tests\Router\Stub\IdentityScopedMiddleware;

class ContainerScopeTest extends \Spiral\Testing\TestCase
Expand All @@ -20,6 +22,7 @@ public function defineBootloaders(): array
return [
RouterBootloader::class,
NyholmBootloader::class,
UserContextBootloader::class,
];
}

Expand All @@ -39,6 +42,25 @@ public function testRunOpenScopeSameTwice(): void
$this->fakeHttp()->get('/test/scopes')->assertBodySame('http-request, idenity, http, root');
}

public function testServerRequestInRootService(): void
{
$router = $this->getRouter();

$router->setRoute(
'group',
(new Route('/<controller>[/<action>]', new Group([
'context' => UserContextController::class,
]))),
);

$this->fakeHttp()->get('/context/scope?context')->assertBodySame('OK');
$this->fakeHttp()->get('/context/scope?context')->assertBodySame('OK');

$this->expectException(\Exception::class);
$this->expectExceptionMessage('Unable to resolve UserContext, invalid request.');
$this->fakeHttp()->get('/context/scope');
}

private function getRouter(): RouterInterface
{
return $this->getContainer()->get(RouterInterface::class);
Expand Down
15 changes: 15 additions & 0 deletions src/Router/tests/Fixtures/UserContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Spiral\Tests\Router\Fixtures;

final class UserContext
{
private function __construct() {}

public static function create(): self
{
return new self();
}
}
27 changes: 27 additions & 0 deletions src/Router/tests/Fixtures/UserContextBootloader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Spiral\Tests\Router\Fixtures;

use Psr\Http\Message\ServerRequestInterface;
use Spiral\Boot\Bootloader\Bootloader;

final class UserContextBootloader extends Bootloader
{
public function defineBindings(): array
{
return [
UserContext::class => [self::class, 'userContext'],
];
}

private function userContext(ServerRequestInterface $request): UserContext
{
return isset($request->getQueryParams()['context'])
? UserContext::create()
: throw new \Exception(
'Unable to resolve UserContext, invalid request.',
);
}
}
17 changes: 17 additions & 0 deletions src/Router/tests/Fixtures/UserContextController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace Spiral\Tests\Router\Fixtures;

class UserContextController
{
public function __construct(
private readonly UserContext $scope,
) {}

public function scope(): string
{
return $this->scope ? 'OK' : 'FAIL';
}
}

0 comments on commit f2b3268

Please sign in to comment.