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