Skip to content

Commit

Permalink
Improved clearing service state bound to request context.
Browse files Browse the repository at this point in the history
  • Loading branch information
parpalak committed Aug 10, 2024
1 parent cc64ec0 commit eef85d3
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 10 deletions.
5 changes: 4 additions & 1 deletion _include/src/Admin/AdminAjaxRequestHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion _include/src/Admin/AdminExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down
5 changes: 4 additions & 1 deletion _include/src/Admin/AdminRequestHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion _include/src/CmsExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down
12 changes: 9 additions & 3 deletions _include/src/Config/DynamicConfigProvider.php
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
<?php
/**
* @copyright 2024 Roman Parpalak
* @license MIT
* @package S2
* @license MIT
* @package S2
*/

declare(strict_types=1);

namespace S2\Cms\Config;

use Psr\Cache\InvalidArgumentException;
use S2\Cms\Framework\StatefulServiceInterface;
use S2\Cms\Pdo\DbLayer;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;

class DynamicConfigProvider
class DynamicConfigProvider implements StatefulServiceInterface
{
private const DYNAMIC_CONFIG_CACHE_KEY = 'dynamic_config';
private ?array $params = null;
Expand All @@ -27,6 +28,11 @@ public function __construct(

}

public function clearState(): void
{
$this->params = null;
}

/**
* @throws InvalidArgumentException
*/
Expand Down
6 changes: 4 additions & 2 deletions _include/src/Framework/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/

Expand Down Expand Up @@ -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'];
Expand Down
11 changes: 11 additions & 0 deletions _include/src/Framework/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -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])) {
Expand Down
19 changes: 19 additions & 0 deletions _include/src/Framework/StatefulServiceInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
/**
* @copyright 2024 Roman Parpalak
* @license http://opensource.org/licenses/MIT MIT
* @package S2
*/

declare(strict_types=1);

namespace S2\Cms\Framework;

/**
* Special interface for the services which internal state is dependent on the request
* and must be cleared between requests.
*/
interface StatefulServiceInterface
{
public function clearState(): void;
}
10 changes: 9 additions & 1 deletion _include/src/Model/PermissionChecker.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@

namespace S2\Cms\Model;

class PermissionChecker
use S2\Cms\Framework\StatefulServiceInterface;

class PermissionChecker implements StatefulServiceInterface
{
public const PERMISSION_VIEW = 'view';
public const PERMISSION_VIEW_HIDDEN = 'view_hidden';
Expand All @@ -21,13 +23,19 @@ class PermissionChecker

private ?array $user = null;


public function setUser(?array $user): void
{
if ($user !== null) {
$this->user = $user;
}
}

public function clearState(): void
{
$this->user = null;
}

public function isGranted(string $permission): bool
{
return (bool)($this->user[$permission] ?? false);
Expand Down

0 comments on commit eef85d3

Please sign in to comment.