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

View::getForm()   C

Complexity

Conditions 11
Paths 13

Size

Total Lines 67
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

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