From eef85d37f02bcd438209f7c3acde20d24f35f330 Mon Sep 17 00:00:00 2001 From: Roman Parpalak Date: Sat, 10 Aug 2024 18:55:10 +0300 Subject: [PATCH] Improved clearing service state bound to request context. --- .../src/Admin/AdminAjaxRequestHandler.php | 5 ++++- _include/src/Admin/AdminExtension.php | 3 ++- _include/src/Admin/AdminRequestHandler.php | 5 ++++- _include/src/CmsExtension.php | 3 ++- _include/src/Config/DynamicConfigProvider.php | 12 +++++++++--- _include/src/Framework/Application.php | 6 ++++-- _include/src/Framework/Container.php | 11 +++++++++++ .../Framework/StatefulServiceInterface.php | 19 +++++++++++++++++++ _include/src/Model/PermissionChecker.php | 10 +++++++++- 9 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 _include/src/Framework/StatefulServiceInterface.php diff --git a/_include/src/Admin/AdminAjaxRequestHandler.php b/_include/src/Admin/AdminAjaxRequestHandler.php index c6fe2def..cceae09f 100644 --- a/_include/src/Admin/AdminAjaxRequestHandler.php +++ b/_include/src/Admin/AdminAjaxRequestHandler.php @@ -18,6 +18,7 @@ use S2\Cms\Framework\Container as C; use S2\Cms\Framework\Exception\AccessDeniedException; use S2\Cms\Framework\Exception\NotFoundException; +use S2\Cms\Framework\StatefulServiceInterface; use S2\Cms\Model\ArticleManager; use S2\Cms\Model\AuthManager; use S2\Cms\Model\ExtensionCache; @@ -51,7 +52,9 @@ public function __construct( */ public function handle(Request $request): Response { - $this->container->clearByTag('request_context'); + array_map(static function (StatefulServiceInterface $service) { + $service->clearState(); + }, $this->container->getByTagIfInstantiated(StatefulServiceInterface::class)); $request->setSession(new Session()); $request->attributes->set(AuthManager::FORCE_AJAX_RESPONSE, true); diff --git a/_include/src/Admin/AdminExtension.php b/_include/src/Admin/AdminExtension.php index 28323e08..ce6be561 100644 --- a/_include/src/Admin/AdminExtension.php +++ b/_include/src/Admin/AdminExtension.php @@ -37,6 +37,7 @@ use S2\Cms\Extensions\ExtensionManagerAdapter; use S2\Cms\Framework\Container; use S2\Cms\Framework\ExtensionInterface; +use S2\Cms\Framework\StatefulServiceInterface; use S2\Cms\Model\ArticleManager; use S2\Cms\Model\ArticleProvider; use S2\Cms\Model\AuthManager; @@ -203,7 +204,7 @@ public function buildContainer(Container $container): void $container->set(PermissionChecker::class, function (Container $container) { return new PermissionChecker(); - }); + }, [StatefulServiceInterface::class]); $container->set(AuthManager::class, function (Container $container) { /** @var DynamicConfigProvider $provider */ diff --git a/_include/src/Admin/AdminRequestHandler.php b/_include/src/Admin/AdminRequestHandler.php index 5da2878a..509326c2 100644 --- a/_include/src/Admin/AdminRequestHandler.php +++ b/_include/src/Admin/AdminRequestHandler.php @@ -14,6 +14,7 @@ use S2\AdminYard\AdminPanel; use S2\Cms\Admin\Event\RedirectFromPublicEvent; use S2\Cms\Framework\Container; +use S2\Cms\Framework\StatefulServiceInterface; use S2\Cms\Model\AuthManager; use S2\Cms\Pdo\DbLayerException; use Symfony\Component\HttpFoundation\Request; @@ -39,7 +40,9 @@ public function __construct( */ public function handle(Request $request): Response { - $this->container->clearByTag('request_context'); + array_map(static function (StatefulServiceInterface $service) { + $service->clearState(); + }, $this->container->getByTagIfInstantiated(StatefulServiceInterface::class)); $request->setSession(new Session()); $this->requestStack->push($request); diff --git a/_include/src/CmsExtension.php b/_include/src/CmsExtension.php index 576e0f45..036e8dea 100644 --- a/_include/src/CmsExtension.php +++ b/_include/src/CmsExtension.php @@ -22,6 +22,7 @@ use S2\Cms\Framework\Container; use S2\Cms\Framework\Event\NotFoundEvent; use S2\Cms\Framework\ExtensionInterface; +use S2\Cms\Framework\StatefulServiceInterface; use S2\Cms\Http\RedirectDetector; use S2\Cms\Image\ThumbnailGenerator; use S2\Cms\Layout\LayoutMatcherFactory; @@ -149,7 +150,7 @@ public function buildContainer(Container $container): void $container->get('config_cache'), $container->getParameter('cache_dir'), ); - }, ['request_context']); + }, [StatefulServiceInterface::class]); // TODO not enough, parameters are set into many other services $container->set('translator', function (Container $container) { /** @var DynamicConfigProvider $provider */ diff --git a/_include/src/Config/DynamicConfigProvider.php b/_include/src/Config/DynamicConfigProvider.php index f25d96c8..3940428e 100644 --- a/_include/src/Config/DynamicConfigProvider.php +++ b/_include/src/Config/DynamicConfigProvider.php @@ -1,8 +1,8 @@ params = null; + } + /** * @throws InvalidArgumentException */ diff --git a/_include/src/Framework/Application.php b/_include/src/Framework/Application.php index c4f695d5..5c3b1142 100644 --- a/_include/src/Framework/Application.php +++ b/_include/src/Framework/Application.php @@ -4,7 +4,7 @@ * Handles HTTP requests after building container definitions and registering event listeners. * * @copyright 2024 Roman Parpalak - * @license MIT + * @license http://opensource.org/licenses/MIT MIT * @package S2 */ @@ -81,7 +81,9 @@ public function setCachedRoutesFilename(string $file): void */ public function handle(Request $request): Response { - $this->container->clearByTag('request_context'); + array_map(static function (StatefulServiceInterface $service) { + $service->clearState(); + }, $this->container->getByTagIfInstantiated(StatefulServiceInterface::class)); $attributes = $this->matchRequest($request); $controllerClass = $attributes['_controller']; diff --git a/_include/src/Framework/Container.php b/_include/src/Framework/Container.php index 66752df2..f4acd8d4 100644 --- a/_include/src/Framework/Container.php +++ b/_include/src/Framework/Container.php @@ -63,6 +63,17 @@ public function getByTag(string $tag): array } } + public function getByTagIfInstantiated(string $tag): array + { + try { + $services = array_map(fn(string $id) => $this->getIfInstantiated($id), $this->idsByTag[$tag] ?? []); + + return array_filter($services, static fn(mixed $service) => $service !== null); + } catch (NotFoundExceptionInterface | ContainerExceptionInterface $e) { + throw new \LogicException('Impossible exception occurred', 0, $e); + } + } + public function clear(string $id): void { if (!isset($this->bindings[$id])) { diff --git a/_include/src/Framework/StatefulServiceInterface.php b/_include/src/Framework/StatefulServiceInterface.php new file mode 100644 index 00000000..d5f1d771 --- /dev/null +++ b/_include/src/Framework/StatefulServiceInterface.php @@ -0,0 +1,19 @@ +user = null; + } + public function isGranted(string $permission): bool { return (bool)($this->user[$permission] ?? false);