diff --git a/Classes/Controller/MediaController.php b/Classes/Controller/MediaController.php index 6168ce868..530c307df 100644 --- a/Classes/Controller/MediaController.php +++ b/Classes/Controller/MediaController.php @@ -14,8 +14,17 @@ * source code. */ +use GraphQL\Error\SyntaxError; +use GraphQL\GraphQL; +use GraphQL\Language\AST\TypeDefinitionNode; +use GraphQL\Language\Parser; +use GraphQL\Type\Definition\ResolveInfo; +use GraphQL\Utils\BuildSchema; use Neos\Flow\Annotations as Flow; +use Neos\Flow\Mvc\View\JsonView; use Neos\Fusion\View\FusionView; +use Neos\Media\Domain\Model\Tag; +use Neos\Media\Domain\Repository\TagRepository; use Neos\Neos\Controller\Module\AbstractModuleController; /** @@ -38,12 +47,72 @@ class MediaController extends AbstractModuleController */ protected $viewFormatToObjectNameMap = [ 'html' => FusionView::class, + 'json' => JsonView::class, ]; + /** + * @Flow\InjectConfiguration(path="graphql.schema") + * @var string + */ + protected $schemaPath; + + /** + * @Flow\Inject + * @var TagRepository + */ + protected $tagRepository; + /** * Renders the media ui application */ public function indexAction(): void { } + + /** + * @Flow\SkipCsrfProtection + * @throws SyntaxError|\JsonException + */ + public function queryAction(): void { + $input = $this->request->getHttpRequest()->getParsedBody(); + $query = $input['query'] ?? null; + $variableValues = $input['variables'] ?? []; + + // TODO: Make sure the file exists + $contents = file_get_contents($this->schemaPath); + + // TODO: Add resolvers + $typeConfigDecorator = function (array $typeConfig, TypeDefinitionNode $typeDefinitionNode): array { + $name = $typeConfig['name']; + switch ($name) { + case 'Query': + $typeConfig['resolveField'] = function ($source, $args, $context, ResolveInfo $info) { + if ($info->fieldName === 'tags') { + return $this->tagRepository->findAll()->toArray(); +// return array_map(static fn (Tag $tag) => [ +// 'id' => $tag->getLabel(), +// 'label' => $tag->getLabel(), +// ], $this->tagRepository->findAll()->toArray()); + } + if ($info->fieldName === 'tag') { + $tag = $this->tagRepository->findByIdentifier($args['id']); + return [ + 'id' => $tag->getLabel(), + 'label' => $tag->getLabel(), + ]; + } + }; + break; + } + return $typeConfig; + }; + +// // TODO: Add error handling +// // TODO: Add caching + $schema = BuildSchema::build($contents, $typeConfigDecorator); + + $ast = Parser::parse($query); + + $this->view->assign('value', GraphQL::executeQuery($schema, $ast)); + } } diff --git a/Configuration/Routes.yaml b/Configuration/Routes.yaml index ce99b0e77..ffd2a1c53 100644 --- a/Configuration/Routes.yaml +++ b/Configuration/Routes.yaml @@ -5,3 +5,12 @@ package: 't3n.GraphQL' variables: 'endpoint': 'media-assets' + +- name: 'Media GraphQL API' + uriPattern: 'neos/graphql2' + defaults: + '@package': 'Flowpack.Media.Ui' + '@controller': 'Media' + '@format': 'json' + '@action': 'query' + httpMethods: ['GET', 'POST'] diff --git a/Configuration/Settings.yaml b/Configuration/Settings.yaml index 6f687b629..1ef2ef997 100644 --- a/Configuration/Settings.yaml +++ b/Configuration/Settings.yaml @@ -2,3 +2,5 @@ Flowpack: Media: Ui: maximumFileUploadLimit: 10 + graphql: + schema: 'resource://Flowpack.Media.Ui/Private/GraphQL/schema.root.graphql' diff --git a/Resources/Private/GraphQL/.graphqlconfig b/Resources/Private/GraphQL/.graphqlconfig new file mode 100644 index 000000000..e4540f339 --- /dev/null +++ b/Resources/Private/GraphQL/.graphqlconfig @@ -0,0 +1,16 @@ +{ + "name": "Untitled GraphQL Schema", + "schemaPath": "schema.graphql", + "extensions": { + "endpoints": { + "Default GraphQL Endpoint": { + "url": "http://helzle.it.test/neos/graphql2", + "headers": { + "user-agent": "JS GraphQL", + "Cookie": "Neos_Session=KfhWNQJBRfO4keZGYpr7Tpf209gXXffT" + }, + "introspect": false + } + } + } +} diff --git a/composer.json b/composer.json index a7799357d..fe08f0bbf 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,8 @@ "neos/neos": "^5.2 || ~7.0 || ~8.0 || dev-master", "neos/neos-ui": "^5.2 || ~7.0 || ~8.0 || dev-master", "t3n/graphql": "^2.1 || ^3.0.2", - "t3n/graphql-upload": "^1.0 || ^2.0" + "t3n/graphql-upload": "^1.0 || ^2.0", + "webonyx/graphql-php": "*" }, "suggest": { "phpstan/phpstan": "For running code quality checks",