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

View::getForm()   C

Complexity

Conditions 11
Paths 13

Size

Total Lines 67
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 12
Bugs 3 Features 1
Metric Value
c 12
b 3
f 1
dl 0
loc 67
rs 5.8904
cc 11
eloc 34
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
    // Force AJAX as we are embedding a form within a form, and exposed filter
105
    // actions will submit the entire EntityBrowserForm form, not the View.
106
    $view->setAjaxEnabled(TRUE);
107
108
    if (!empty($this->configuration['arguments'])) {
109
      if (!empty($aditional_widget_parameters['path_parts'])) {
110
        $arguments = [];
111
        // Map configuration arguments with original path parts.
112
        foreach ($this->configuration['arguments'] as $argument) {
113
          $arguments[] = isset($aditional_widget_parameters['path_parts'][$argument]) ? $aditional_widget_parameters['path_parts'][$argument] : '';
114
        }
115
        $view->setArguments(array_values($arguments));
116
      }
117
    }
118
119
    $form['view'] = $view->executeDisplay($this->configuration['view_display']);
120
121
    if (empty($view->field['entity_browser_select'])) {
122
      $url = Url::fromRoute('entity.view.edit_form',['view'=>$this->configuration['view']])->toString();
123
      if ($this->currentUser->hasPermission('administer views')) {
124
        return [
125
          '#markup' => t('Entity browser select form field not found on a view. <a href=":link">Go fix it</a>!', [':link' => $url]),
126
        ];
127
      }
128
      else {
129
        return [
130
          '#markup' => t('Entity browser select form field not found on a view. Go fix it!'),
131
        ];
132
      }
133
    }
134
135
    // When rebuilding makes no sense to keep checkboxes that were previously
136
    // selected.
137
    if (!empty($form['view']['entity_browser_select']) && $form_state->isRebuilding()) {
138
      foreach (Element::children($form['view']['entity_browser_select']) as $child) {
139
        $form['view']['entity_browser_select'][$child]['#process'][] = ['\Drupal\entity_browser\Plugin\EntityBrowser\Widget\View', 'processCheckbox'];
140
        $form['view']['entity_browser_select'][$child]['#process'][] = ['\Drupal\Core\Render\Element\Checkbox', 'processAjaxForm'];
141
        $form['view']['entity_browser_select'][$child]['#process'][] = ['\Drupal\Core\Render\Element\Checkbox', 'processGroup'];
142
      }
143
    }
144
145
    $form['view']['view'] = [
146
      '#markup' => \Drupal::service('renderer')->render($form['view']['view']),
147
    ];
148
149
    return $form;
150
  }
151
152
  /**
153
   * Sets the #checked property when rebuilding form.
154
   *
155
   * Every time when we rebuild we want all checkboxes to be unchecked.
156
   *
157
   * @see \Drupal\Core\Render\Element\Checkbox::processCheckbox()
158
   */
159
  public static function processCheckbox(&$element, FormStateInterface $form_state, &$complete_form) {
160
    $element['#checked'] = FALSE;
161
    return $element;
162
  }
163
164
  /**
165
   * {@inheritdoc}
166
   */
167
  public function validate(array &$form, FormStateInterface $form_state) {
168
    $user_input = $form_state->getUserInput();
169
    if (isset($user_input['entity_browser_select'])) {
170
      $selected_rows = array_values(array_filter($user_input['entity_browser_select']));
171
      foreach ($selected_rows as $row) {
172
        // Verify that the user input is a string and split it.
173
        // Each $row is in the format entity_type:id.
174
        if (is_string($row) && $parts = explode(':', $row, 2)) {
175
          // Make sure we have a type and id present.
176
          if (count($parts) == 2) {
177
            try {
178
              $storage = $this->entityManager->getStorage($parts[0]);
179
              if (!$storage->load($parts[1])) {
180
                $message = t('The @type Entity @id does not exist.', [
181
                  '@type' => $parts[0],
182
                  '@id' => $parts[1]
183
                ]);
184
                $form_state->setError($form['widget']['view']['entity_browser_select'], $message);
185
              }
186
            }
187
            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...
188
              $message = t('The Entity Type @type does not exist.', [
189
                '@type' => $parts[0],
190
              ]);
191
              $form_state->setError($form['widget']['view']['entity_browser_select'], $message);
192
            }
193
          }
194
        }
195
      }
196
    }
197
  }
198
199
  /**
200
   * {@inheritdoc}
201
   */
202
  public function submit(array &$element, array &$form, FormStateInterface $form_state) {
203
    $selected_rows = array_values(array_filter($form_state->getUserInput()['entity_browser_select']));
204
    $entities = [];
205
    foreach ($selected_rows as $row) {
206
      list($type, $id) = explode(':', $row);
207
      $storage = $this->entityManager->getStorage($type);
208
      if ($entity = $storage->load($id)) {
209
        $entities[] = $entity;
210
      }
211
    }
212
213
    $this->selectEntities($entities, $form_state);
214
  }
215
216
}
217