You are here

function theme_entity_reference_layout_widget in Entity Reference with Layout 8

Themes the "ERL" field widget.

Parameters

array $variables: Contains the form element data from $element['entities'].

1 string reference to 'theme_entity_reference_layout_widget'
entity_reference_layout_theme in ./entity_reference_layout.module
Implements hook_theme().

File

./entity_reference_layout.module, line 149
Contains entity_reference_layout.module.

Code

function theme_entity_reference_layout_widget(array $variables) {
  $currentUser = \Drupal::service('current_user');
  $form = $variables['form'];
  $build = [
    '#type' => 'fieldset',
    '#id' => $form['#id'],
    '#attributes' => [
      'class' => [
        'erl-field',
      ],
    ],
    '#title' => $form['#title'],
    // These get moved around with JS.
    'add_more' => [
      '#weight' => 998,
    ] + $form['add_more'],
    // Container for layouts.
    'layout_items' => [
      '#type' => 'container',
      '#attributes' => [
        'class' => [
          'erl-layout-wrapper',
        ],
      ],
    ],
    // Container for disabled / orphaned items.
    'disabled' => [
      '#type' => 'fieldset',
      '#attributes' => [
        'class' => [
          'erl-disabled-items',
        ],
      ],
      '#weight' => 999,
      '#title' => t('Disabled Items'),
      'items' => [
        '#type' => 'container',
        '#attributes' => [
          'class' => [
            'erl-disabled-wrapper',
          ],
        ],
        'description' => [
          '#type' => 'html_tag',
          '#tag' => 'div',
          '#attributes' => [
            'class' => [
              'erl-disabled-items__description',
            ],
          ],
          '#value' => t('Drop items here that you want to keep disabled / hidden, without removing them permanently.'),
        ],
      ],
    ],
  ];

  // Add a Warning Message if this is a Translation Context.
  if (!empty($build["add_more"]["actions"]["#isTranslating"])) {
    $build['is_translating_warning'] = [
      '#type' => "html_tag",
      '#tag' => 'div',
      '#value' => t("This is Translation Context (editing a version not in the original language). <b>No new Layout Sections and Items can be added</b>."),
      '#weight' => -1100,
      '#attributes' => [
        'class' => [
          'is_translating_warning',
        ],
      ],
    ];
  }
  $new_items = [];
  $form_with_layout = [];
  $renderer = \Drupal::service('renderer');

  /* @var \Drupal\Core\Layout\LayoutPluginManager $layout_plugin_manager */
  $layout_plugin_manager = \Drupal::service('plugin.manager.core.layout');
  $items = [];
  foreach (Element::children($form) as $key) {
    if ($key !== 'add_more') {

      // If there is an open entity form,
      // move it to it's own section of the widget form.
      if (!empty($form[$key]['entity_form'])) {
        $build['entity_form'] = $form[$key]['entity_form'] + [
          '#weight' => 1000,
        ];
        $build['entity_form']['#attributes']['class'][] = 'erl-entity-form';
        unset($form[$key]['entity_form']);
      }

      // If there is an open remove confirmation form,
      // move it to it's own section of the widget form.
      if (!empty($form[$key]['remove_form'])) {
        $build['remove_form'] = $form[$key]['remove_form'] + [
          '#weight' => 1000,
        ];
        unset($form[$key]['remove_form']);
      }
      $items[] =& $form[$key];
    }
  }
  usort($items, '_erl_widget_sort_helper');
  $has_non_layout_items = FALSE;
  $section_key = NULL;
  foreach ($items as $key => &$item) {

    // Merge and add attributes.
    $attributes = entity_reference_layout_merge_attributes($item['#attributes'], $item['#layout_options']);
    $item['#attributes'] = $attributes;

    // Set the weight for sorted list items.
    $item['#weight'] = $key;

    // If this is a layout we'll populate regions below.
    $item['#regions'] = [
      '#attributes' => [
        'class' => [],
      ],
    ];

    // Add class for weight element.
    if (!empty($item['_weight'])) {
      $item['_weight']['#attributes']['class'] = [
        'erl-weight',
      ];

      // Move to top of container to ensure items are given the correct delta.
      $item['_weight']['#weight'] = -1000;
      $item['_weight']['#theme_wrappers'] = [
        'container' => [
          '#attributes' => [
            'class' => [
              'hidden',
            ],
          ],
        ],
      ];
    }

    // Stash new items for processing later.
    if (!empty($item['#is_new'])) {
      $new_items[] = $item;
    }
    elseif (!empty($item['layout']['#value'])) {
      $section_key = $key;
      $form_with_layout['section_' . $section_key] = $items[$section_key];
      $form_with_layout['section_' . $section_key]['#attributes']['class'][] = 'erl-layout';
      try {
        $layout_instance = $layout_plugin_manager
          ->createInstance($items[$section_key]['layout']['#value'], $items[$section_key]['config']['#value']);
        foreach ($layout_instance
          ->getPluginDefinition()
          ->getRegionNames() as $region_name) {
          $form_with_layout['section_' . $section_key]['#regions'][$region_name] = [
            '#attributes' => [
              'class' => [
                'erl-layout-region',
                'erl-layout-region--' . $region_name,
              ],
            ],
          ];
        }
      } catch (\Exception $e) {
        watchdog_exception('Erl, Layout Plugin Manager', $e);
      }
    }
    elseif (!empty($item['region']['#value']) && isset($form_with_layout['section_' . $section_key]['#regions'][$item['region']['#value']])) {
      $form_with_layout['section_' . $section_key]['#regions'][$item['region']['#value']][] = $item;
      $has_non_layout_items = TRUE;
    }
    else {
      $build['disabled']['items'][] = $item;
      $has_non_layout_items = TRUE;
    }
  }

  // Move new items into correct position, if applicable.
  foreach ($new_items as $key => $item) {
    $section_key = $item['#parent_weight'];

    // Layout items.
    if (empty($item['#new_region'])) {
      $item['#weight'] = $item['#parent_weight'] + 0.5;
      $form_with_layout['new_section_' . $key] = $item;
    }

    // Items to add into regions.
    if (isset($item['#new_region'])) {
      $region_name = $item['#new_region'];
      if (isset($form_with_layout['section_' . $section_key]['#regions'][$region_name])) {
        $form_with_layout['section_' . $section_key]['#regions'][$region_name][] = $item;
      }
    }
  }
  $show_layout_labels = \Drupal::config('entity_reference_layout.settings')
    ->get('show_layout_labels');
  foreach ($form_with_layout as $key => $section) {
    if (!empty($section['layout']['#value'])) {
      try {
        $layout_instance = $layout_plugin_manager
          ->createInstance($section['layout']['#value'], $section['config']['#value']);

        // Add a "Add Item" button, if is not a translation context.
        if (empty($build["add_more"]["actions"]["#isTranslating"])) {
          foreach (array_keys($section['#regions']) as $region) {
            $section['#regions'][$region]['button'] = [
              '#markup' => '<button class="erl-add-content__toggle">+<span class="visually-hidden">' . t('Add Item') . '</span></button>',
              '#allowed_tags' => [
                'button',
                'span',
              ],
              // Toggle is always last in region.
              '#weight' => 10000,
            ];
          }
        }
        $rendered_regions = $layout_instance
          ->build($section['#regions']);
        $section['#regions']['#attributes']['class'][] = 'erl-layout__regions';
        if ($show_layout_labels === 1) {
          $label = $layout_instance
            ->getPluginDefinition() ? $layout_instance
            ->getPluginDefinition()
            ->getLabel()
            ->__toString() : $section['#layout'];
          $section['layout']['label'] = [
            '#type' => 'label',
            '#title' => $label,
            '#title_display' => $label,
            '#attributes' => [
              'class' => [
                'paragraph-layout-label',
              ],
            ],
          ];
        }
        $section['preview']['content'] = [
          '#weight' => 1000,
          'regions' => $rendered_regions,
        ];
      } catch (\Exception $e) {
        watchdog_exception('Erl, Layout Plugin Manager', $e);
      }

      // Add a "Add Section" button, if is not a translation context.
      if ($currentUser
        ->hasPermission('manage entity reference layout sections') && empty($build["add_more"]["actions"]["#isTranslating"])) {

        // Add the "add section" button for js.
        $section['button'] = [
          '#markup' => '<div class="erl-add-content--single"><button class="erl-add-section"><span class="icon">+</span>' . t('Add Section') . '</button></div>',
          '#allowed_tags' => [
            'button',
            'span',
            'div',
          ],
        ];
      }
    }
    $build['layout_items'][] = $section;
  }
  if (count($form_with_layout) == 0) {
    $build['add_section_button'] = [
      '#markup' => '<div class="erl-first-section"><div class="erl-add-content--single"><button class="erl-add-section"><span class="icon">+</span>' . t('Add Section') . '</button></div></div>',
      '#allowed_tags' => [
        'button',
        'span',
        'div',
      ],
      '#weight' => -1,
    ];
  }
  $show_labels = \Drupal::config('entity_reference_layout.settings')
    ->get('show_paragraph_labels');
  if ($show_labels) {
    foreach ($build["layout_items"] as $key => $layout_item) {
      if (!isset($layout_item["preview"]["content"]["regions"])) {
        continue;
      }
      foreach ($build['layout_items'][$key]['preview']['content']['regions'] as $regionKey => $region) {
        if (!is_array($region)) {
          continue;
        }
        foreach ($region as $paragraphKey => $paragraph) {
          if (!isset($paragraph['#entity'])) {
            continue;
          }
          $entity = $paragraph['#entity'];
          $label = $entity
            ->getParagraphType()->label;
          $build['layout_items'][$key]['preview']['content']['regions'][$regionKey][$paragraphKey][] = [
            '#type' => 'label',
            '#title' => $label,
            '#title_display' => $label,
            '#attributes' => [
              'class' => [
                'paragraph-type-label',
              ],
            ],
          ];
        }
      }
    }
  }

  // If there are no items, don't show the disabled region.
  if (!$has_non_layout_items) {
    unset($build['disabled']);
  }

  // Add a container so Javascript can respond to empty state.
  if (count($items) == 0) {
    $build['empty_container'] = [
      '#type' => 'container',
      '#attributes' => [
        'class' => [
          'erl-empty',
        ],
      ],
    ];
  }
  $build['#attached']['library'][] = 'entity_reference_layout/erl_widget';
  return $renderer
    ->render($build);
}