From f5ac3a4be8ee69aa23b2beec13614031aa9206c1 Mon Sep 17 00:00:00 2001
From: MatthieuScarset <m@matthieuscarset.com>
Date: Sun, 6 May 2018 19:48:53 -0400
Subject: [PATCH 1/1] Add ConfigViewsSelection plugin

---
 .../ConfigViewsSelection.php                  | 123 ++++++++++++++++++
 src/Plugin/views/query/ConfigViewQuery.php    |   1 +
 2 files changed, 124 insertions(+)
 create mode 100644 src/Plugin/EntityReferenceSelection/ConfigViewsSelection.php

diff --git a/src/Plugin/EntityReferenceSelection/ConfigViewsSelection.php b/src/Plugin/EntityReferenceSelection/ConfigViewsSelection.php
new file mode 100644
index 0000000..4d3cb5a
--- /dev/null
+++ b/src/Plugin/EntityReferenceSelection/ConfigViewsSelection.php
@@ -0,0 +1,123 @@
+<?php
+
+namespace Drupal\config_view\Plugin\EntityReferenceSelection;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\views\Views;
+use Drupal\views\Plugin\EntityReferenceSelection\ViewsSelection;
+
+/**
+ * Plugin implementation of the 'selection' entity_reference.
+ *
+ * @EntityReferenceSelection(
+ *   id = "config_views",
+ *   label = @Translation("Views: Filter by a entity reference Config View"),
+ *   group = "config_views",
+ *   weight = 0
+ * )
+ */
+class ConfigViewsSelection extends ViewsSelection implements ContainerFactoryPluginInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return [
+      'view' => [
+        'view_name' => NULL,
+        'display_name' => NULL,
+        'arguments' => [],
+      ],
+    ] + parent::defaultConfiguration();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $form = parent::buildConfigurationForm($form, $form_state);
+
+    $view_settings = $this->getConfiguration()['view'];
+    $displays = Views::getApplicableViews('entity_reference_display');
+    // Filter views that list the entity type we want, and group the separate
+    // displays by view.
+    $entity_type = $this->entityManager->getDefinition($this->configuration['target_type']);
+    $view_storage = $this->entityManager->getStorage('view');
+
+    $options = [];
+    foreach ($displays as $data) {
+      list($view_id, $display_id) = $data;
+      $view = $view_storage->load($view_id);
+      $display = $view->get('display');
+      $options[$view_id . ':' . $display_id] = $view_id . ' - ' . $display[$display_id]['display_title'];
+    }
+
+    // The value of the 'view_and_display' select below will need to be split
+    // into 'view_name' and 'view_display' in the final submitted values, so
+    // we massage the data at validate time on the wrapping element (not
+    // ideal).
+    $form['view']['#element_validate'] = [[get_called_class(), 'settingsFormValidate']];
+
+    if ($options) {
+      $default = !empty($view_settings['view_name']) ? $view_settings['view_name'] . ':' . $view_settings['display_name'] : NULL;
+      $form['view']['view_and_display'] = [
+        '#type' => 'select',
+        '#title' => $this->t('View used to select the entities'),
+        '#required' => TRUE,
+        '#options' => $options,
+        '#default_value' => $default,
+        '#description' => '<p>' . $this->t('Choose the view and display that select the entities that can be referenced.<br />Only views with a display of type "Entity Reference" are eligible.') . '</p>',
+      ];
+
+      $default = !empty($view_settings['arguments']) ? implode(', ', $view_settings['arguments']) : '';
+      $form['view']['arguments'] = [
+        '#type' => 'textfield',
+        '#title' => $this->t('View arguments'),
+        '#default_value' => $default,
+        '#required' => FALSE,
+        '#description' => $this->t('Provide a comma separated list of arguments to pass to the view.'),
+      ];
+    }
+    else {
+      if ($this->currentUser->hasPermission('administer views') && $this->moduleHandler->moduleExists('views_ui')) {
+        $form['view']['no_view_help'] = [
+          '#markup' => '<p>' . $this->t('No eligible views were found. <a href=":create">Create a view</a> with an <em>Entity Reference</em> display, or add such a display to an <a href=":existing">existing view</a>.', [
+            ':create' => Url::fromRoute('views_ui.add')->toString(),
+            ':existing' => Url::fromRoute('entity.view.collection')->toString(),
+          ]) . '</p>',
+        ];
+      }
+      else {
+        $form['view']['no_view_help']['#markup'] = '<p>' . $this->t('No eligible views were found.') . '</p>';
+      }
+    }
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
+    $display_name = $this->getConfiguration()['view']['display_name'];
+    $arguments = $this->getConfiguration()['view']['arguments'];
+    $result = [];
+    if ($this->initializeView($match, $match_operator, $limit)) {
+      // Get the results.
+      $result = $this->view->executeDisplay($display_name, $arguments);
+    }
+
+    $return = [];
+    if ($result) {
+      foreach ($this->view->result as $row) {
+        // @todo Matthieu.
+        if (isset($row->_relationship_objects['']) && $config_entity = $row->_relationship_objects['']) {
+          $entity = reset($config_entity);  
+          $return[$entity->getEntityTypeId()][$entity->getOriginalId()] = $entity->label();
+        }
+      }
+    }
+    return $return;
+  }
+
+}
diff --git a/src/Plugin/views/query/ConfigViewQuery.php b/src/Plugin/views/query/ConfigViewQuery.php
index a0196cd..275e4cb 100644
--- a/src/Plugin/views/query/ConfigViewQuery.php
+++ b/src/Plugin/views/query/ConfigViewQuery.php
@@ -796,6 +796,7 @@ class ConfigViewQuery extends QueryPluginBase {
    *   When correct operator is not provided.
    */
   private function addConjunctionGroupandConditions() {
+    $this->setGroupOperator();
     $this->query->conjunction = $this->groupOperator;
 
     foreach ($this->conditions as $gr => $cnd) {
-- 
2.17.0