Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions src/Plugin/GraphQLCompose/FieldType/ViewsReferenceItem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

declare(strict_types=1);

namespace Drupal\stanford_fields\Plugin\GraphQLCompose\FieldType;

use Drupal\Core\Field\FieldItemInterface;
use Drupal\graphql\GraphQL\Execution\FieldContext;
use Drupal\graphql_compose\Plugin\GraphQL\DataProducer\FieldProducerItemInterface;
use Drupal\graphql_compose\Plugin\GraphQL\DataProducer\FieldProducerTrait;
use Drupal\graphql_compose\Plugin\GraphQLCompose\GraphQLComposeFieldTypeBase;
use Drupal\graphql_compose_views\Plugin\views\display\GraphQL;
use Drupal\views\Views;

/**
* {@inheritDoc}
*
* @codeCoverageIgnore Unclear how to test for this.
*
* @GraphQLComposeFieldType(
* id = "viewsreference",
* type_sdl = "ViewsReferenceType",
* )
*/
class ViewsReferenceItem extends GraphQLComposeFieldTypeBase implements FieldProducerItemInterface {

use FieldProducerTrait;

/**
* {@inheritdoc}
*/
public function resolveFieldItem(FieldItemInterface $item, FieldContext $context) {
if (empty($item->target_id) || empty($item->display_id)) {
return NULL;
}

$view = Views::getView($item->target_id);
$view->setDisplay($item->display_id);

if (!$view || !$view->access($item->display_id)) {
return NULL;
}

$context->addCacheableDependency($view);

/** @var \Drupal\graphql_compose_views\Plugin\views\display\GraphQL $display */
$display = $view->getDisplay();
$options = unserialize($item->data) ?? [];
$args = empty($options['argument']) ? NULL : explode('/', $options['argument'] ?? '');
$size = is_numeric($options['limit']) ? (int) $options['limit'] : NULL;
$offset = is_numeric($options['offset']) ? (int) $options['offset'] : NULL;

return [
'view' => $item->target_id,
'display' => $item->display_id,
'contextualFilter' => $args,
'pageSize' => $size,
'sort' => isset($options['sort']['field']) ? $options['sort'] : NULL,
'pager' => $options['pager'] ?? NULL,
'offset' => $offset,
'query' => $display instanceof GraphQL ? $display->getGraphQlQueryName() : NULL,
];
}

}
46 changes: 46 additions & 0 deletions src/Plugin/GraphQLCompose/SchemaType/ViewsReferenceSort.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Drupal\stanford_fields\Plugin\GraphQLCompose\SchemaType;

use Drupal\graphql_compose\Plugin\GraphQLCompose\GraphQLComposeSchemaTypeBase;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;

/**
* {@inheritdoc}
*
* @codeCoverageIgnore Unclear how to test for this.
*
* @GraphQLComposeSchemaType(
* id = "ViewsReferenceSort"
* )
*/
class ViewsReferenceSort extends GraphQLComposeSchemaTypeBase {

/**
* {@inheritdoc}
*/
public function getTypes(): array {
$types = [];

$types[] = new ObjectType([
'name' => $this->getPluginId(),
'description' => (string) $this->t('A reference to an embedded view'),
'fields' => fn() => [
'field' => [
'type' => Type::nonNull(Type::string()),
'description' => (string) $this->t('The machine name of the view.'),
],
'direction' => [
'type' => Type::nonNull(Type::string()),
'description' => (string) $this->t('The machine name of the display.'),
],
],
]);

return $types;
}

}
72 changes: 72 additions & 0 deletions src/Plugin/GraphQLCompose/SchemaType/ViewsReferenceType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

declare(strict_types=1);

namespace Drupal\stanford_fields\Plugin\GraphQLCompose\SchemaType;

use Drupal\graphql_compose\Plugin\GraphQLCompose\GraphQLComposeSchemaTypeBase;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;

/**
* {@inheritdoc}
*
* @codeCoverageIgnore Unclear how to test for this.
*
* @GraphQLComposeSchemaType(
* id = "ViewsReferenceType"
* )
*/
class ViewsReferenceType extends GraphQLComposeSchemaTypeBase {

/**
* {@inheritdoc}
*/
public function getTypes(): array {
$types = [];

$types[] = new ObjectType([
'name' => $this->getPluginId(),
'description' => (string) $this->t('A reference to an embedded view'),
'fields' => fn() => [
'view' => [
'type' => Type::nonNull(Type::string()),
'description' => (string) $this->t('The machine name of the view.'),
],
'display' => [
'type' => Type::nonNull(Type::string()),
'description' => (string) $this->t('The machine name of the display.'),
],
'contextualFilter' => [
'type' => Type::listOf(Type::nonNull(Type::string())),
'description' => (string) $this->t('The contextual filter values used.'),
],
'pageSize' => [
'type' => Type::int(),
'description' => (string) $this->t('How many results per page.'),
],

'sort' => [
'type' => static::type('ViewsReferenceSort'),
'description' => (string) $this->t('How many results per page.'),
],
'pager' => [
'type' => Type::string(),
'description' => (string) $this->t('How many results per page.'),
],
'offset' => [
'type' => Type::int(),
'description' => (string) $this->t('How many results per page.'),
],

'query' => [
'type' => Type::string(),
'description' => (string) $this->t('The name of the query used to fetch the data, if the view is a GraphQL display.'),
],
],
]);

return $types;
}

}
110 changes: 110 additions & 0 deletions src/Plugin/ViewsReferenceSetting/ViewsReferenceSort.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php

namespace Drupal\stanford_fields\Plugin\ViewsReferenceSetting;

use Drupal\Component\Plugin\PluginBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\views\ViewExecutable;
use Drupal\viewsreference\Plugin\ViewsReferenceSettingInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* The views reference setting pager plugin.
*
* @ViewsReferenceSetting(
* id = "sort",
* label = @Translation("Sorting"),
* default_value = null,
* )
*/
class ViewsReferenceSort extends PluginBase implements ViewsReferenceSettingInterface, ContainerFactoryPluginInterface {

use StringTranslationTrait;

/**
* {@inheritDoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('entity_type.manager')
);
}

/**
* @param array $configuration
* Plugin configuration.
* @param $plugin_id
* Plugin ID.
* @param $plugin_definition
* Plugin definition.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* Entity type manager service.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, protected EntityTypeManagerInterface $entityTypeManager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
}

/**
* {@inheritdoc}
*/
public function alterFormField(array &$form_field) {
$view = $this->configuration['view_name'];
$display_id = $this->configuration['display_id'];
if (!$view || !$display_id) {
return;
}
/** @var \Drupal\views\Entity\View $view */
$view = $this->entityTypeManager->getStorage('view')->load($view);

$display = $view->getDisplay($display_id);
$default = $view->getDisplay('default');
$sorts = $display['display_options']['sorts'] ?? $default['display_options']['sorts'];
$exposed_sorts = array_filter($sorts, fn($sort) => $sort['exposed']);
$sort_options = [];
foreach ($exposed_sorts as $sort) {
$sort_options[$sort['id']] = $sort['expose']['label'];
}

if (empty($sort_options)) {
$form_field['#access'] = FALSE;
}

$form_field['#type'] = 'container';
$form_field['field'] = [
'#type' => 'select',
'#title' => $this->t('Field'),
'#options' => $sort_options,
'#empty_option' => $this->t('Default Sort'),
'#default_value' => $form_field['#default_value']['field'] ?? NULL,
];

$form_field['direction'] = [
'#type' => 'select',
'#title' => $this->t('Sort Direction'),
'#options' => [
'ASC' => $this->t('Ascending'),
'DESC' => $this->t('Descending'),
],
'#default_value' => $form_field['#default_value']['direction'] ?? 'ASC',
];
unset($form_field['#default_value']);
}

/**
* {@inheritdoc}
*/
public function alterView(ViewExecutable $view, $value) {
if (!empty($value)) {
$view->setExposedInput([
'sort_by' => $value['field'],
'sort_order' => $value['direction'],
]);
}
}

}