Skip to content

Commit

Permalink
Allow to explicitly attach a GraphQL views display to an entity type …
Browse files Browse the repository at this point in the history
…and / or its bundles.
  • Loading branch information
das-peter committed Jan 7, 2020
1 parent a78f8fd commit dc78c26
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 2 deletions.
4 changes: 3 additions & 1 deletion src/Plugin/Deriver/Fields/ViewDeriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
namespace Drupal\graphql_views\Plugin\Deriver\Fields;

use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Drupal\graphql\Utility\StringHelper;
use Drupal\graphql_views\Plugin\Deriver\ViewDeriverBase;
use Drupal\views\Plugin\views\display\DisplayPluginInterface;
use Drupal\views\Views;

/**
Expand Down Expand Up @@ -35,7 +37,7 @@ public function getDerivativeDefinitions($basePluginDefinition) {
$arguments += $this->getPagerArguments($display);
$arguments += $this->getSortArguments($display, $id);
$arguments += $this->getFilterArguments($display, $id);
$types = $this->getTypes($info);
$types = $this->getTypes($display, $info);

$this->derivatives[$id] = [
'id' => $id,
Expand Down
85 changes: 85 additions & 0 deletions src/Plugin/views/display/GraphQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ public function displaysExposed() {
protected function defineOptions() {
$options = parent::defineOptions();

// Allow to attach the view to entity types / bundles.
// Similar to the EVA module.
$options['entity_type']['default'] = '';
$options['bundles']['default'] = [];

// Set the default plugins to 'graphql'.
$options['style']['contains']['type']['default'] = 'graphql';
$options['exposed_form']['contains']['type']['default'] = 'graphql';
Expand Down Expand Up @@ -206,6 +211,30 @@ public function optionsSummary(&$categories, &$options) {
'title' => $this->t('Query name'),
'value' => views_ui_truncate($this->getGraphQLQueryName(), 24),
];

if ($entity_type = $this->getOption('entity_type')) {
$entity_info = \Drupal::entityManager()->getDefinition($entity_type);
$type_name = $entity_info->get('label');

$bundle_names = [];
$bundle_info = \Drupal::entityManager()->getBundleInfo($entity_type);
foreach ($this->getOption('bundles') as $bundle) {
$bundle_names[] = $bundle_info[$bundle]['label'];
}
}

$options['entity_type'] = [
'category' => 'graphql',
'title' => $this->t('Entity type'),
'value' => empty($type_name) ? $this->t('None') : $type_name,
];

$options['bundles'] = [
'category' => 'graphql',
'title' => $this->t('Bundles'),
'value' => empty($bundle_names) ? $this->t('All') : implode(', ', $bundle_names),
];

}

/**
Expand All @@ -223,6 +252,41 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
'#default_value' => $this->getGraphQLQueryName(),
];
break;

case 'entity_type':
$entity_info = \Drupal::entityManager()->getDefinitions();
$entity_names = [NULL => $this->t('None')];
foreach ($entity_info as $type => $info) {
// is this a content/front-facing entity?
if ($info instanceof \Drupal\Core\Entity\ContentEntityType) {
$entity_names[$type] = $info->get('label');
}
}

$form['#title'] .= $this->t('Entity type');
$form['entity_type'] = [
'#type' => 'radios',
'#required' => FALSE,
'#title' => $this->t('Attach this display to the following entity type'),
'#options' => $entity_names,
'#default_value' => $this->getOption('entity_type'),
];
break;

case 'bundles':
$options = [];
$entity_type = $this->getOption('entity_type');
foreach (\Drupal::entityManager()->getBundleInfo($entity_type) as $bundle => $info) {
$options[$bundle] = $info['label'];
}
$form['#title'] .= $this->t('Bundles');
$form['bundles'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Attach this display to the following bundles. If no bundles are selected, the display will be attached to all.'),
'#options' => $options,
'#default_value' => $this->getOption('bundles'),
];
break;
}
}

Expand All @@ -236,6 +300,27 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) {
case 'graphql_query_name':
$this->setOption($section, $form_state->getValue($section));
break;
case 'entity_type':
$new_entity = $form_state->getValue('entity_type');
$old_entity = $this->getOption('entity_type');
$this->setOption('entity_type', $new_entity);

if ($new_entity != $old_entity) {
// Each entity has its own list of bundles and view modes. If there's
// only one on the new type, we can select it automatically. Otherwise
// we need to wipe the options and start over.
$new_entity_info = \Drupal::entityManager()->getDefinition($new_entity);
$new_bundles_keys = \Drupal::entityManager()->getBundleInfo($new_entity);
$new_bundles = array();
if (count($new_bundles_keys) == 1) {
$new_bundles[] = $new_bundles_keys[0];
}
$this->setOption('bundles', $new_bundles);
}
break;
case 'bundles':
$this->setOption('bundles', array_values(array_filter($form_state->getValue('bundles'))));
break;
}
}

Expand Down
12 changes: 11 additions & 1 deletion src/ViewDeriverHelperTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,17 @@ protected function getPagerArguments(DisplayPluginInterface $display) {
* @return array
* An array of additional types the view can be embedded in.
*/
protected function getTypes(array $arguments, array $types = ['Root']) {
protected function getTypes(DisplayPluginInterface $display, array $arguments, array $types = ['Root']) {

if (($entity_type = $display->getOption('entity_type'))) {
$types = array_merge($types, [StringHelper::camelCase($entity_type)]);

if (($bundles = $display->getOption('bundles'))) {
$types = array_merge($types, array_map(function ($bundle) use ($entity_type) {
return StringHelper::camelCase($entity_type, $bundle);
}, $bundles));
}
}

if (empty($arguments)) {
return $types;
Expand Down

0 comments on commit dc78c26

Please sign in to comment.