Completed
Pull Request — 8.x-1.x (#143)
by
unknown
02:36
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
 *   description = @Translation("Uses a view to provide entity listing in a browser's widget.")
28
 * )
29
 */
30
class View extends WidgetBase implements ContainerFactoryPluginInterface {
31
32
  /**
33
   * The current user.
34
   *
35
   * @var \Drupal\Core\Session\AccountInterface
36
   */
37
  protected $currentUser;
38
39
  /**
40
   * {@inheritdoc}
41
   */
42
  public function defaultConfiguration() {
43
    return array(
44
      'view' => NULL,
45
      'view_display' => NULL,
46
    ) + parent::defaultConfiguration();
47
  }
48
49
  /**
50
   * {@inheritdoc}
51
   */
52 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...
53
    return new static(
54
      $configuration,
55
      $plugin_id,
56
      $plugin_definition,
57
      $container->get('event_dispatcher'),
58
      $container->get('entity.manager'),
59
      $container->get('current_user')
60
    );
61
  }
62
63
  /**
64
   * Constructs a new View object.
65
   *
66
   * @param array $configuration
67
   *   A configuration array containing information about the plugin instance.
68
   * @param string $plugin_id
69
   *   The plugin_id for the plugin instance.
70
   * @param mixed $plugin_definition
71
   *   The plugin implementation definition.
72
   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
73
   *   Event dispatcher service.
74
   * @param \Drupal\Core\Session\AccountInterface $current_user
75
   *   The current user.
76
   */
77
   public function __construct(array $configuration, $plugin_id, $plugin_definition, EventDispatcherInterface $event_dispatcher, EntityManagerInterface $entity_manager, AccountInterface $current_user) {
78
     parent::__construct($configuration, $plugin_id, $plugin_definition, $event_dispatcher, $entity_manager);
79
     $this->currentUser = $current_user;
80
  }
81
82
  /**
83
   * {@inheritdoc}
84
   */
85
  public function getForm(array &$original_form, FormStateInterface $form_state, array $aditional_widget_parameters) {
86
    $form = [];
87
    // TODO - do we need better error handling for view and view_display (in case
88
    // either of those is nonexistent or display not of correct type)?
89
90
    $form['#attached']['library'] = ['entity_browser/view'];
91
92
    /** @var \Drupal\views\ViewExecutable $view */
93
    $view = $this->entityManager
94
      ->getStorage('view')
95
      ->load($this->configuration['view'])
96
      ->getExecutable();
97
98
    // Check if the current user has access to this view.
99
    if (!$view->access($this->configuration['view_display'])) {
100
      return [
101
        '#markup' => t('You do not have access to this View.'),
102
      ];
103
    }
104
105
    if (!empty($this->configuration['arguments'])) {
106
      if (!empty($aditional_widget_parameters['path_parts'])) {
107
        $arguments = [];
108
        // Map configuration arguments with original path parts.
109
        foreach ($this->configuration['arguments'] as $argument) {
110
          $arguments[] = isset($aditional_widget_parameters['path_parts'][$argument]) ? $aditional_widget_parameters['path_parts'][$argument] : '';
111
        }
112
        $view->setArguments(array_values($arguments));
113
      }
114
    }
115
116
    $form['view'] = $view->executeDisplay($this->configuration['view_display']);
117
118
    if (empty($view->field['entity_browser_select'])) {
119
      $url = Url::fromRoute('entity.view.edit_form',['view'=>$this->configuration['view']])->toString();
120
      if ($this->currentUser->hasPermission('administer views')) {
121
        return [
122
          '#markup' => t('Entity browser select form field not found on a view. <a href=":link">Go fix it</a>!', [':link' => $url]),
123
        ];
124
      }
125
      else {
126
        return [
127
          '#markup' => t('Entity browser select form field not found on a view. Go fix it!'),
128
        ];
129
      }
130
    }
131
132
    // When rebuilding makes no sense to keep checkboxes that were previously
133
    // selected.
134
    if (!empty($form['view']['entity_browser_select']) && $form_state->isRebuilding()) {
135
      foreach (Element::children($form['view']['entity_browser_select']) as $child) {
136
        $form['view']['entity_browser_select'][$child]['#process'][] = ['\Drupal\entity_browser\Plugin\EntityBrowser\Widget\View', 'processCheckbox'];
137
        $form['view']['entity_browser_select'][$child]['#process'][] = ['\Drupal\Core\Render\Element\Checkbox', 'processAjaxForm'];
138
        $form['view']['entity_browser_select'][$child]['#process'][] = ['\Drupal\Core\Render\Element\Checkbox', 'processGroup'];
139
      }
140
    }
141
142
    $form['view']['view'] = [
143
      '#markup' => \Drupal::service('renderer')->render($form['view']['view']),
144
    ];
145
146
    return $form;
147
  }
148
149
  /**
150
   * Sets the #checked property when rebuilding form.
151
   *
152
   * Every time when we rebuild we want all checkboxes to be unchecked.
153
   *
154
   * @see \Drupal\Core\Render\Element\Checkbox::processCheckbox()
155
   */
156
  public static function processCheckbox(&$element, FormStateInterface $form_state, &$complete_form) {
157
    $element['#checked'] = FALSE;
158
    return $element;
159
  }
160
161
  /**
162
   * {@inheritdoc}
163
   */
164
  public function validate(array &$form, FormStateInterface $form_state) {
165
    $user_input = $form_state->getUserInput();
166
    if (isset($user_input['entity_browser_select'])) {
167
      $selected_rows = array_values(array_filter($user_input['entity_browser_select']));
168
      foreach ($selected_rows as $row) {
169
        // Verify that the user input is a string and split it.
170
        // Each $row is in the format entity_type:id.
171
        if (is_string($row) && $parts = explode(':', $row, 2)) {
172
          // Make sure we have a type and id present.
173
          if (count($parts) == 2) {
174
            try {
175
              $storage = $this->entityManager->getStorage($parts[0]);
176
              if (!$storage->load($parts[1])) {
177
                $message = t('The @type Entity @id does not exist.', [
178
                  '@type' => $parts[0],
179
                  '@id' => $parts[1]
180
                ]);
181
                $form_state->setError($form['widget']['view']['entity_browser_select'], $message);
182
              }
183
            }
184
            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...
185
              $message = t('The Entity Type @type does not exist.', [
186
                '@type' => $parts[0],
187
              ]);
188
              $form_state->setError($form['widget']['view']['entity_browser_select'], $message);
189
            }
190
          }
191
        }
192
      }
193
    }
194
  }
195
196
  /**
197
   * {@inheritdoc}
198
   */
199
  public function submit(array &$element, array &$form, FormStateInterface $form_state) {
200
    $selected_rows = array_values(array_filter($form_state->getUserInput()['entity_browser_select']));
201
    $entities = [];
202
    foreach ($selected_rows as $row) {
203
      list($type, $id) = explode(':', $row);
204
      $storage = $this->entityManager->getStorage($type);
205
      if ($entity = $storage->load($id)) {
206
        $entities[] = $entity;
207
      }
208
    }
209
210
    $this->selectEntities($entities, $form_state);
211
  }
212
213
  /**
214
   * {@inheritdoc}
215
   */
216
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
217
    $options = [];
218
    // Get only those enabled Views that have entity_browser displays.
219
    $displays = Views::getApplicableViews('entity_browser_display');
220
    foreach ($displays as $display) {
221
      list($view_id, $display_id) = $display;
222
      $view = $this->entityManager->getStorage('view')->load($view_id);
223
      $options[$view_id . '.' . $display_id] = $this->t('@view : @display', array('@view' => $view->label(), '@display' => $view->get('display')[$display_id]['display_title']));
224
    }
225
226
    $form['view'] = [
227
      '#type' => 'select',
228
      '#title' => $this->t('View : View display'),
229
      '#default_value' => $this->configuration['view'] . '.' . $this->configuration['view_display'],
230
      '#options' => $options,
231
    ];
232
233
    return $form;
234
  }
235
236
  /**
237
   * {@inheritdoc}
238
   */
239
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
240
    $values = $form_state->getValues()['table'][$this->uuid()]['form'];
241
242
    if (!empty($values['view'])) {
243
      list($view_id, $display_id) = explode('.', $values['view']);
244
      $this->configuration['view'] = $view_id;
245
      $this->configuration['view_display'] = $display_id;
246
    }
247
  }
248
249
250
}
251