Files
kupshop/bundles/KupShop/GraphQLBundle/Middleware/ModuleMiddleware.php
2025-08-02 16:30:27 +02:00

84 lines
3.2 KiB
PHP

<?php
declare(strict_types=1);
namespace KupShop\GraphQLBundle\Middleware;
use GraphQL\Type\Definition\FieldDefinition;
use GraphQL\Type\Definition\NonNull;
use GraphQL\Type\Definition\OutputType;
use KupShop\GraphQLBundle\ApiAdmin\Annotation\Module;
use TheCodingMachine\GraphQLite\InputField;
use TheCodingMachine\GraphQLite\InputFieldDescriptor;
use TheCodingMachine\GraphQLite\Middlewares\FieldHandlerInterface;
use TheCodingMachine\GraphQLite\Middlewares\FieldMiddlewareInterface;
use TheCodingMachine\GraphQLite\Middlewares\InputFieldHandlerInterface;
use TheCodingMachine\GraphQLite\Middlewares\InputFieldMiddlewareInterface;
use TheCodingMachine\GraphQLite\Parameters\ContainerParameter;
use TheCodingMachine\GraphQLite\QueryFieldDescriptor;
/**
* Generic module middleware for `FieldMiddlewareInterface` and `InputFieldMiddlewareInterface`.
*/
class ModuleMiddleware
{
protected function handleModule(
QueryFieldDescriptor|InputFieldDescriptor $fieldDescriptor,
FieldHandlerInterface|InputFieldHandlerInterface $fieldHandler): FieldDefinition|InputField|null
{
$annotations = $fieldDescriptor->getMiddlewareAnnotations();
/** @var Module $module */
$module = $annotations->getAnnotationByType(Module::class);
if ($module === null) {
return $fieldHandler->handle($fieldDescriptor);
}
// pokud je v module ulozen nazev constanty (stary zpusob pres anotace)
if ($module->constants) {
// Pokud nemame modul, tak field skryjeme
if (!\Modules::check($module->module, $module->submodule)) {
return $this->handleModuleDisabled($fieldDescriptor, $fieldHandler);
}
}
// pokud je to uz klasicky nazev modulu
elseif (!findModule($module->module, $module->submodule)) {
return $this->handleModuleDisabled($fieldDescriptor, $fieldHandler);
}
return $fieldHandler->handle($fieldDescriptor);
}
private function handleModuleDisabled(QueryFieldDescriptor|InputFieldDescriptor $fieldDescriptor, FieldHandlerInterface|InputFieldHandlerInterface $fieldHandler): ?FieldDefinition
{
// Hide the field in admin / pos APIs.
if (!$this->isPublicApi()) {
return null;
}
// If the declared return type is non-nullable -> redeclare it as nullable.
$type = $fieldDescriptor->getType();
if ($type instanceof NonNull) {
$type = $type->getWrappedType();
assert($type instanceof OutputType);
$fieldDescriptor->setType($type);
}
$fieldDescriptor->setParameters(array_filter($fieldDescriptor->getParameters(), fn ($param) => !($param instanceof ContainerParameter)));
// Override the resolver to always return null, if the module in annotation is not enabled.
$fieldDescriptor->setResolver(fn () => null);
return $fieldHandler->handle($fieldDescriptor);
}
private function isPublicApi(): bool
{
// pouzivam regexp, abych matchul /graphql a pripadne i URL s language prefixem (/en/graphql...)
$path = parse_url($_SERVER['REQUEST_URI'] ?? '', PHP_URL_PATH);
return (bool) preg_match('/^\/(\S{2}\/)?graphql/', $path);
}
}