Completed
Pull Request — 8.x-1.x (#143)
by
unknown
02:38
created

View::validate()   C

Complexity

Conditions 8
Paths 10

Size

Total Lines 31
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 31
rs 5.3846
c 1
b 0
f 0
cc 8
eloc 18
nc 10
nop 2
1
<?php
2
3
/**
4
 * Contains \Drupal\entity_browser\Plugin\EntityBrowser\Widget\View.
5
 */
6
7
namespace Drupal\entity_browser\Plugin\EntityBrowser\Widget;
8
9
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
10
use Drupal\Core\Form\FormStateInterface;
11
use Drupal\Core\Render\Element;
12
use Drupal\entity_browser\WidgetBase;
13
use Drupal\Core\Url;
14
use Drupal\views\Views;
15
use Symfony\Component\DependencyInjection\ContainerInterface;
16
use Drupal\Core\Session\AccountInterface;
17
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
18
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
19
use Drupal\Core\Entity\EntityManagerInterface;
20
21
/**
22
 * Uses a view to provide entity listing in a browser's widget.
23
 *
24
 * @EntityBrowserWidget(
25
 *   id = "view",
26
 *   label = @Translation("View"),
27
 *   provider = "views",
28
 *   description = @Translation("Uses a view to provide entity listing in a browser's widget.")
29
 * )
30
 */
31
class View extends WidgetBase implements ContainerFactoryPluginInterface {
32
33
  /**
34
   * The current user.
35
   *
36
   * @var \Drupal\Core\Session\AccountInterface
37
   */
38
  protected $currentUser;
39
40
  /**
41
   * {@inheritdoc}
42
   */
43
  public function defaultConfiguration() {
44
    return array(
45
      'view' => NULL,
46
      'view_display' => NULL,
47
    ) + parent::defaultConfiguration();
48
  }
49
50
  /**
51
   * {@inheritdoc}
52
   */
53 View Code Duplication
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
54
    return new static(
55
      $configuration,
56
      $plugin_id,
57
      $plugin_definition,
58
      $container->get('event_dispatcher'),
59
      $container->get('entity.manager'),
60
      $container->get('current_user')
61
    );
62
  }
63
64
  /**
65
   * Constructs a new View object.
66
   *
67
   * @param array $configuration
68
   *   A configuration array containing information about the plugin instance.
69
   * @param string $plugin_id
70
   *   The plugin_id for the plugin instance.
71
   * @param mixed $plugin_definition
72
   *   The plugin implementation definition.
73
   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
74
   *   Event dispatcher service.
75
   * @param \Drupal\Core\Session\AccountInterface $current_user
76
   *   The current user.
77
   */
78
   public function __construct(array $configuration, $plugin_id, $plugin_definition, EventDispatcherInterface $event_dispatcher, EntityManagerInterface $entity_manager, AccountInterface $current_user) {
79
     parent::__construct($configuration, $plugin_id, $plugin_definition, $event_dispatcher, $entity_manager);
80
     $this->currentUser = $current_user;
81
  }
82
83
  /**
84
   * {@inheritdoc}
85
   */
86
  public function getForm(array &$original_form, FormStateInterface $form_state, array $aditional_widget_parameters) {
87
    $form = [];
88
    // TODO - do we need better error handling for view and view_display (in case
89
    // either of those is nonexistent or display not of correct type)?
90
91
    $form['#attached']['library'] = ['entity_browser/view'];
92
93
    /** @var \Drupal\views\ViewExecutable $view */
94
    $view = $this->entityManager
95
      ->getStorage('view')
96
      ->load($this->configuration['view'])
97
      ->getExecutable();
98
99
    // Check if the current user has access to this view.
100
    if (!$view->access($this->configuration['view_display'])) {
101
      return [
102
        '#markup' => t('You do not have access to this View.'),
103
      ];
104
    }
105
106
    if (!empty($this->configuration['arguments'])) {
107
      if (!empty($aditional_widget_parameters['path_parts'])) {
108
        $arguments = [];
109
        // Map configuration arguments with original path parts.
110
        foreach ($this->configuration['arguments'] as $argument) {
111
          $arguments[] = isset($aditional_widget_parameters['path_parts'][$argument]) ? $aditional_widget_parameters['path_parts'][$argument] : '';
112
        }
113
        $view->setArguments(array_values($arguments));
114
      }
115
    }
116
117
    $form['view'] = $view->executeDisplay($this->configuration['view_display']);
118
119
    if (empty($view->field['entity_browser_select'])) {
120
      $url = Url::fromRoute('entity.view.edit_form',['view'=>$this->configuration['view']])->toString();
121
      if ($this->currentUser->hasPermission('administer views')) {
122
        return [
123
          '#markup' => t('Entity browser select form field not found on a view. <a href=":link">Go fix it</a>!', [':link' => $url]),
124
        ];
125
      }
126
      else {
127
        return [
128
          '#markup' => t('Entity browser select form field not found on a view. Go fix it!'),
129
        ];
130
      }
131
    }
132
133
    // When rebuilding makes no sense to keep checkboxes that were previously
134
    // selected.
135
    if (!empty($form['view']['entity_browser_select']) && $form_state->isRebuilding()) {
136
      foreach (Element::children($form['view']['entity_browser_select']) as $child) {
137
        $form['view']['entity_browser_select'][$child]['#process'][] = ['\Drupal\entity_browser\Plugin\EntityBrowser\Widget\View', 'processCheckbox'];
138
        $form['view']['entity_browser_select'][$child]['#process'][] = ['\Drupal\Core\Render\Element\Checkbox', 'processAjaxForm'];
139
        $form['view']['entity_browser_select'][$child]['#process'][] = ['\Drupal\Core\Render\Element\Checkbox', 'processGroup'];
140
      }
141
    }
142
143
    $form['view']['view'] = [
144
      '#markup' => \Drupal::service('renderer')->render($form['view']['view']),
145
    ];
146
147
    return $form;
148
  }
149
150
  /**
151
   * Sets the #checked property when rebuilding form.
152
   *
153
   * Every time when we rebuild we want all checkboxes to be unchecked.
154
   *
155
   * @see \Drupal\Core\Render\Element\Checkbox::processCheckbox()
156
   */
157
  public static function processCheckbox(&$element, FormStateInterface $form_state, &$complete_form) {
158
    $element['#checked'] = FALSE;
159
    return $element;
160
  }
161
162
  /**
163
   * {@inheritdoc}
164
   */
165
  public function validate(array &$form, FormStateInterface $form_state) {
166
    $user_input = $form_state->getUserInput();
167
    if (isset($user_input['entity_browser_select'])) {
168
      $selected_rows = array_values(array_filter($user_input['entity_browser_select']));
169
      foreach ($selected_rows as $row) {
170
        // Verify that the user input is a string and split it.
171
        // Each $row is in the format entity_type:id.
172
        if (is_string($row) && $parts = explode(':', $row, 2)) {
173
          // Make sure we have a type and id present.
174
          if (count($parts) == 2) {
175
            try {
176
              $storage = $this->entityManager->getStorage($parts[0]);
177
              if (!$storage->load($parts[1])) {
178
                $message = t('The @type Entity @id does not exist.', [
179
                  '@type' => $parts[0],
180
                  '@id' => $parts[1]
181
                ]);
182
                $form_state->setError($form['widget']['view']['entity_browser_select'], $message);
183
              }
184
            }
185
            catch (PluginNotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class Drupal\Component\Plugin\...PluginNotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
186
              $message = t('The Entity Type @type does not exist.', [
187
                '@type' => $parts[0],
188
              ]);
189
              $form_state->setError($form['widget']['view']['entity_browser_select'], $message);
190
            }
191
          }
192
        }
193
      }
194
    }
195
  }
196
197
  /**
198
   * {@inheritdoc}
199
   */
200
  public function submit(array &$element, array &$form, FormStateInterface $form_state) {
201
    $selected_rows = array_values(array_filter($form_state->getUserInput()['entity_browser_select']));
202
    $entities = [];
203
    foreach ($selected_rows as $row) {
204
      list($type, $id) = explode(':', $row);
205
      $storage = $this->entityManager->getStorage($type);
206
      if ($entity = $storage->load($id)) {
207
        $entities[] = $entity;
208
      }
209
    }
210
211
    $this->selectEntities($entities, $form_state);
212
  }
213
214
  /**
215
   * {@inheritdoc}
216
   */
217
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
218
    $options = [];
219
    // Get only those enabled Views that have entity_browser displays.
220
    $displays = Views::getApplicableViews('entity_browser_display');
221
    foreach ($displays as $display) {
222
      list($view_id, $display_id) = $display;
223
      $view = $this->entityManager->getStorage('view')->load($view_id);
224
      $options[$view_id . '.' . $display_id] = $this->t('@view : @display', array('@view' => $view->label(), '@display' => $view->get('display')[$display_id]['display_title']));
225
    }
226
227
    $form['view'] = [
228
      '#type' => 'select',
229
      '#title' => $this->t('View : View display'),
230
      '#default_value' => $this->configuration['view'] . '.' . $this->configuration['view_display'],
231
      '#options' => $options,
232
      '#required' => TRUE,
233
    ];
234
235
    return $form;
236
  }
237
238
  /**
239
   * {@inheritdoc}
240
   */
241
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
242
    $values = $form_state->getValues()['table'][$this->uuid()]['form'];
243
244
    if (!empty($values['view'])) {
245
      list($view_id, $display_id) = explode('.', $values['view']);
246
      $this->configuration['view'] = $view_id;
247
      $this->configuration['view_display'] = $display_id;
248
    }
249
  }
250
251
252
}
253