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

View::getForm()   C

Complexity

Conditions 11
Paths 13

Size

Total Lines 67
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 13
Bugs 3 Features 1
Metric Value
c 13
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\Utility\Html;
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 submit(array &$element, array &$form, FormStateInterface $form_state) {
168
    $selected_rows = array_values(array_filter($form_state->getUserInput()['entity_browser_select']));
169
    $entities = [];
170
    foreach ($selected_rows as $row) {
171
      list($type, $id) = explode(':', Html::escape($row));
172
      $entities[] = $this->entityManager->getStorage($type)->load($id);
173
    }
174
175
    $this->selectEntities($entities, $form_state);
176
  }
177
178
}
179