Completed
Pull Request — 8.x-1.x (#129)
by Samuel
03:16
created

View::getForm()   C

Complexity

Conditions 11
Paths 13

Size

Total Lines 63
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 13
Bugs 3 Features 1
Metric Value
c 13
b 3
f 1
dl 0
loc 63
rs 6.1137
cc 11
eloc 33
nc 13
nop 3

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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