Skip to content

Commit dc78c26

Browse files
committed
Allow to explicitly attach a GraphQL views display to an entity type and / or its bundles.
1 parent a78f8fd commit dc78c26

File tree

3 files changed

+99
-2
lines changed

3 files changed

+99
-2
lines changed

src/Plugin/Deriver/Fields/ViewDeriver.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
namespace Drupal\graphql_views\Plugin\Deriver\Fields;
44

55
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
6+
use Drupal\graphql\Utility\StringHelper;
67
use Drupal\graphql_views\Plugin\Deriver\ViewDeriverBase;
8+
use Drupal\views\Plugin\views\display\DisplayPluginInterface;
79
use Drupal\views\Views;
810

911
/**
@@ -35,7 +37,7 @@ public function getDerivativeDefinitions($basePluginDefinition) {
3537
$arguments += $this->getPagerArguments($display);
3638
$arguments += $this->getSortArguments($display, $id);
3739
$arguments += $this->getFilterArguments($display, $id);
38-
$types = $this->getTypes($info);
40+
$types = $this->getTypes($display, $info);
3941

4042
$this->derivatives[$id] = [
4143
'id' => $id,

src/Plugin/views/display/GraphQL.php

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ public function displaysExposed() {
8484
protected function defineOptions() {
8585
$options = parent::defineOptions();
8686

87+
// Allow to attach the view to entity types / bundles.
88+
// Similar to the EVA module.
89+
$options['entity_type']['default'] = '';
90+
$options['bundles']['default'] = [];
91+
8792
// Set the default plugins to 'graphql'.
8893
$options['style']['contains']['type']['default'] = 'graphql';
8994
$options['exposed_form']['contains']['type']['default'] = 'graphql';
@@ -206,6 +211,30 @@ public function optionsSummary(&$categories, &$options) {
206211
'title' => $this->t('Query name'),
207212
'value' => views_ui_truncate($this->getGraphQLQueryName(), 24),
208213
];
214+
215+
if ($entity_type = $this->getOption('entity_type')) {
216+
$entity_info = \Drupal::entityManager()->getDefinition($entity_type);
217+
$type_name = $entity_info->get('label');
218+
219+
$bundle_names = [];
220+
$bundle_info = \Drupal::entityManager()->getBundleInfo($entity_type);
221+
foreach ($this->getOption('bundles') as $bundle) {
222+
$bundle_names[] = $bundle_info[$bundle]['label'];
223+
}
224+
}
225+
226+
$options['entity_type'] = [
227+
'category' => 'graphql',
228+
'title' => $this->t('Entity type'),
229+
'value' => empty($type_name) ? $this->t('None') : $type_name,
230+
];
231+
232+
$options['bundles'] = [
233+
'category' => 'graphql',
234+
'title' => $this->t('Bundles'),
235+
'value' => empty($bundle_names) ? $this->t('All') : implode(', ', $bundle_names),
236+
];
237+
209238
}
210239

211240
/**
@@ -223,6 +252,41 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
223252
'#default_value' => $this->getGraphQLQueryName(),
224253
];
225254
break;
255+
256+
case 'entity_type':
257+
$entity_info = \Drupal::entityManager()->getDefinitions();
258+
$entity_names = [NULL => $this->t('None')];
259+
foreach ($entity_info as $type => $info) {
260+
// is this a content/front-facing entity?
261+
if ($info instanceof \Drupal\Core\Entity\ContentEntityType) {
262+
$entity_names[$type] = $info->get('label');
263+
}
264+
}
265+
266+
$form['#title'] .= $this->t('Entity type');
267+
$form['entity_type'] = [
268+
'#type' => 'radios',
269+
'#required' => FALSE,
270+
'#title' => $this->t('Attach this display to the following entity type'),
271+
'#options' => $entity_names,
272+
'#default_value' => $this->getOption('entity_type'),
273+
];
274+
break;
275+
276+
case 'bundles':
277+
$options = [];
278+
$entity_type = $this->getOption('entity_type');
279+
foreach (\Drupal::entityManager()->getBundleInfo($entity_type) as $bundle => $info) {
280+
$options[$bundle] = $info['label'];
281+
}
282+
$form['#title'] .= $this->t('Bundles');
283+
$form['bundles'] = [
284+
'#type' => 'checkboxes',
285+
'#title' => $this->t('Attach this display to the following bundles. If no bundles are selected, the display will be attached to all.'),
286+
'#options' => $options,
287+
'#default_value' => $this->getOption('bundles'),
288+
];
289+
break;
226290
}
227291
}
228292

@@ -236,6 +300,27 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) {
236300
case 'graphql_query_name':
237301
$this->setOption($section, $form_state->getValue($section));
238302
break;
303+
case 'entity_type':
304+
$new_entity = $form_state->getValue('entity_type');
305+
$old_entity = $this->getOption('entity_type');
306+
$this->setOption('entity_type', $new_entity);
307+
308+
if ($new_entity != $old_entity) {
309+
// Each entity has its own list of bundles and view modes. If there's
310+
// only one on the new type, we can select it automatically. Otherwise
311+
// we need to wipe the options and start over.
312+
$new_entity_info = \Drupal::entityManager()->getDefinition($new_entity);
313+
$new_bundles_keys = \Drupal::entityManager()->getBundleInfo($new_entity);
314+
$new_bundles = array();
315+
if (count($new_bundles_keys) == 1) {
316+
$new_bundles[] = $new_bundles_keys[0];
317+
}
318+
$this->setOption('bundles', $new_bundles);
319+
}
320+
break;
321+
case 'bundles':
322+
$this->setOption('bundles', array_values(array_filter($form_state->getValue('bundles'))));
323+
break;
239324
}
240325
}
241326

src/ViewDeriverHelperTrait.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,17 @@ protected function getPagerArguments(DisplayPluginInterface $display) {
117117
* @return array
118118
* An array of additional types the view can be embedded in.
119119
*/
120-
protected function getTypes(array $arguments, array $types = ['Root']) {
120+
protected function getTypes(DisplayPluginInterface $display, array $arguments, array $types = ['Root']) {
121+
122+
if (($entity_type = $display->getOption('entity_type'))) {
123+
$types = array_merge($types, [StringHelper::camelCase($entity_type)]);
124+
125+
if (($bundles = $display->getOption('bundles'))) {
126+
$types = array_merge($types, array_map(function ($bundle) use ($entity_type) {
127+
return StringHelper::camelCase($entity_type, $bundle);
128+
}, $bundles));
129+
}
130+
}
121131

122132
if (empty($arguments)) {
123133
return $types;

0 commit comments

Comments
 (0)