ViewsSchemaProvider.php in GraphQL 8.2
File
src/SchemaProvider/ViewsSchemaProvider.php
View source
<?php
namespace Drupal\graphql\SchemaProvider;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\TypedData\TypedDataManager;
use Drupal\graphql\TypeResolverInterface;
use Drupal\graphql\Utility\StringHelper;
use Drupal\views\ViewEntityInterface;
use Fubhy\GraphQL\Language\Node;
use Fubhy\GraphQL\Type\Definition\Types\ListModifier;
use Fubhy\GraphQL\Type\Definition\Types\NonNullModifier;
use Fubhy\GraphQL\Type\Definition\Types\ObjectType;
use Fubhy\GraphQL\Type\Definition\Types\Type;
class ViewsSchemaProvider extends SchemaProviderBase {
protected $entityManager;
protected $typeResolver;
protected $typedDataManager;
protected $moduleHandler;
public function __construct(EntityManagerInterface $entityManager, TypedDataManager $typedDataManager, TypeResolverInterface $typeResolver, ModuleHandlerInterface $moduleHandler) {
$this->entityManager = $entityManager;
$this->typeResolver = $typeResolver;
$this->typedDataManager = $typedDataManager;
$this->moduleHandler = $moduleHandler;
}
protected function getDataTableMap() {
$map = [];
foreach ($this->entityManager
->getDefinitions() as $entityTypeId => $entityType) {
if ($dataTable = $entityType
->getDataTable()) {
$map[$dataTable] = $entityType
->id();
}
}
return $map;
}
public function getQuerySchema() {
if (!$this->moduleHandler
->moduleExists('views')) {
return [];
}
$fields = [];
$map = $this
->getDataTableMap();
foreach ($this->entityManager
->getStorage('view')
->loadMultiple() as $view) {
$baseTable = $view
->get('base_table');
if (!isset($map[$baseTable])) {
continue;
}
$viewId = $view
->id();
foreach ($view
->get('display') as $displayId => $display) {
if ($display['display_plugin'] !== 'graphql') {
continue;
}
$executable = $view
->getExecutable();
$executable
->setDisplay($displayId);
$filters = $executable
->getDisplay()
->getOption('filters');
$filters = array_reduce(array_filter($filters, function (array $filter) {
return !empty($filter['exposed']);
}), function (array $carry, array $filter) {
$type = $filter['expose']['required'] ? new NonNullModifier(Type::stringType()) : Type::stringType();
$type = $filter['expose']['multiple'] ? new ListModifier($type) : $type;
$type = $filter['expose']['required'] ? new NonNullModifier($type) : $type;
$carry[$filter['expose']['identifier']] = [
'type' => $type,
];
return $carry;
}, []);
$definition = $this->typedDataManager
->createDataDefinition("entity:{$map[$baseTable]}");
if (!($resolved = $this->typeResolver
->resolveRecursive($definition))) {
continue;
}
$fields["{$viewId}:{$displayId}"] = [
'type' => new ListModifier($resolved),
'resolve' => [
__CLASS__,
'getViewResults',
],
'args' => $filters,
'resolveData' => [
'view' => $viewId,
'display' => $displayId,
],
];
}
}
$names = StringHelper::formatPropertyNameList(array_keys($fields));
return array_combine($names, $fields);
}
public static function getViewResults($source, array $args = NULL, $root, Node $field, $a, $b, $c, $data) {
$storage = \Drupal::entityManager()
->getStorage('view');
if (!($view = $storage
->load($data['view']))) {
return NULL;
}
$executable = $view
->getExecutable();
$executable
->setDisplay($data['display']);
$executable
->setExposedInput(array_filter($args));
$executable
->execute();
$result = [];
foreach ($executable->result as $row) {
$entity = $row->_entity;
$result[$entity
->id()] = $entity
->getTypedData();
}
return $result;
}
}