Completed
Pull Request — 8.x-1.x (#118)
by
unknown
03:24
created

EntityBrowserElement::getInfo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 16
rs 9.4286
cc 1
eloc 13
nc 1
nop 0
1
<?php
2
3
/**
4
 * @file
5
 * Contains \Drupal\entity_browser\src\Element\EntityBrowserElement.
6
 */
7
8
namespace Drupal\entity_browser\Element;
9
10
use Drupal\Component\Utility\Html;
11
use Drupal\Component\Utility\NestedArray;
12
use Drupal\Core\Field\FieldStorageDefinitionInterface;
13
use Drupal\Core\Form\FormStateInterface;
14
use Drupal\Core\Render\Element\FormElement;
15
use \Drupal\entity_browser\Entity\EntityBrowser;
16
17
/**
18
 * Provides an Entity Browser render element.
19
 *
20
 * Configuration options are:
21
 *
22
 * @FormElement("entity_browser")
23
 */
24
class EntityBrowserElement extends FormElement {
25
26
  /**
27
   * {@inheritdoc}
28
   */
29
  public function getInfo() {
30
    $class = get_class($this);
31
    return [
32
      '#input' => TRUE,
33
      '#multiple' => FALSE,
34
      '#process' => [[$class, 'processEntityBrowser']],
35
      '#size' => 60,
36
      '#pre_render' => [[$class, 'preRenderEntityBrowser']],
37
      '#theme' => 'entity_browser',
38
      '#theme_wrappers' => ['form_element'],
39
      '#tree' => TRUE,
40
      '#attached' => [
41
        'library' => ['entity_browser/entity_reference']
42
      ],
43
    ];
44
  }
45
46
  /**
47
   * Processes the entity browser element.
48
   */
49
  public static function processEntityBrowser(&$element, FormStateInterface $form_state, &$complete_form) {
50
    /** @var \Drupal\entity_browser\EntityBrowserInterface $entity_browser */
51
    $entity_browser = EntityBrowser::load($element['#entity_browser_id']);
52
53
    $element['entity_browser'] = $entity_browser->getDisplay()->displayEntityBrowser();
54
55
    if ($element['#cardinality'] == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED || count($element['#default_value']) < $element['cardinality']) {
56
      $element['#attached']['drupalSettings']['entity_browser'] = [
57
        'field_settings' => [
58
          $entity_browser->getDisplay()->getUuid() => [
59
            'cardinality' => $element['#cardinality'],
60
          ],
61
        ]
62
      ];
63
    }
64
65
    return $element;
66
  }
67
68
  /**
69
   * Prepares a #type 'entity_browser' render element for entity_browser.html.twig.
70
   *
71
   * @param array $element
72
   *   An associative array containing the properties of the element.
73
   *
74
   * @return array
75
   *   The $element with prepared variables ready for entity-browser.html.twig.
76
   */
77
  public static function preRenderEntityBrowser($element) {
78
    $hidden_id = Html::getUniqueId('edit-' . $element['#identifier'] . '-target-id');
79
    $details_id = Html::getUniqueId('edit-' . $element['#identifier']);
80
81
    $element['#theme_wrappers'][] = [
82
      '#id' => $details_id,
83
      '#type' => 'details',
84
      '#open' => !empty($ids),
0 ignored issues
show
Bug introduced by
The variable $ids seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
85
      'target_id' => [
86
        '#type' => 'hidden',
87
        '#id' => $hidden_id,
88
        // We need to repeat ID here as it is otherwise skipped when rendering.
89
        '#attributes' => ['id' => $hidden_id],
90
        '#default_value' => $element['#default_value'],
91
        // #ajax is officially not supported for hidden elements but if we
92
        // specify event manually it works.
93
        '#ajax' => [
94
          'callback' => [self::class, 'updateWidgetCallback'],
95
          'wrapper' => $details_id,
96
          'event' => 'entity_browser_value_updated',
97
        ],
98
      ],
99
    ];
100
101
    $element['#variables']['entity_browser'] = $element['entity_browser'];
102
103
    return $element;
104
  }
105
106
  /**
107
   * {@inheritdoc}
108
   */
109
  public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
110
    $return = [];
111
    return $return;
112
  }
113
114
  /**
115
   * AJAX form callback.
116
   */
117 View Code Duplication
  public static function updateWidgetCallback(array &$form, FormStateInterface $form_state) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
118
    $trigger = $form_state->getTriggeringElement();
119
    // AJAX requests can be triggered by hidden "target_id" element when entities
120
    // are added or by one of the "Remove" buttons. Depending on that we need to
121
    // figure out where root of the widget is in the form structure and use this
122
    // information to return correct part of the form.
123
    if (!empty($trigger['#ajax']['event']) && $trigger['#ajax']['event'] == 'entity_browser_value_updated') {
124
      $parents = array_slice($trigger['#array_parents'], 0, -2);
125
    }
126
    elseif ($trigger['#type'] == 'submit' && strpos($trigger['#name'], '_remove_')) {
127
      $parents = array_slice($trigger['#array_parents'], 0, -4);
128
    }
129
130
    return NestedArray::getValue($form, $parents);
0 ignored issues
show
Bug introduced by
The variable $parents does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
131
  }
132
}
133