You are here

GridStackLayout.php in GridStack 8.2

File

src/Plugin/Layout/GridStackLayout.php
View source
<?php

namespace Drupal\gridstack\Plugin\Layout;

use Drupal\Core\Render\Element;
use Drupal\gridstack\GridStackDefault;
use Drupal\gridstack\Entity\GridStack;

/**
 * Provides a GridStack class for Layout plugins.
 */
class GridStackLayout extends GridStackLayoutBase {

  /**
   * {@inheritdoc}
   */
  public function build(array $regions) {
    ksort($regions);
    $settings = $this
      ->getConfiguration();
    $definition = $this
      ->getPluginDefinition();
    $name = $definition
      ->get('optionset');
    $optionset = GridStack::loadWithFallback($name);
    $variant = $this->manager
      ->getEngine($settings, 'variant')
      ->override($optionset, $settings);

    // Provides settings.
    $settings['optionset'] = $name;
    $settings['_stylizer'] = TRUE;
    $settings = array_filter($settings);
    $build = [
      'items' => $this
        ->interpolateItems($optionset, $settings, $regions),
      'optionset' => $optionset,
      'settings' => $settings,
      'layout' => $definition,
      'variant' => $variant,
    ];

    // Still a check in case it is removed by another alter.
    if ($library = $this->pluginDefinition
      ->getLibrary()) {
      $build['attached']['library'][] = $library;
    }

    // Must pass the layout blueprint to Layout Builder regardless empty.
    return $this->manager
      ->build($build);
  }

  /**
   * Interpolate data from Layout Builder to match original construct.
   *
   * We do this because we don't manually put regions into templates.
   * Instead structured with nested grids, if any, to have one template for any
   * known layout possibility: one or two dimensional layouts.
   * With everything being cached at D8, this shouldn't make much different than
   * hard-coded layouts at YML files which still need parsing anyway.
   */
  protected function interpolateItems($optionset, array &$settings, array $regions = []) {
    $id = 'box';
    $items = [];
    $config = isset($settings['regions']) ? $settings['regions'] : [];
    unset($settings['regions']);
    foreach (array_keys($optionset
      ->getLastBreakpoint()) as $delta) {
      $rid = GridStackDefault::regionId($delta);
      $box = [];

      // Remove top level settings to avoid leaking due to similarity.
      $box['settings'] = array_diff_key($settings, GridStackDefault::regionSettings());
      $box['settings'] = isset($config[$rid]) ? array_merge($box['settings'], $config[$rid]) : $box['settings'];
      if ($grids = $optionset
        ->getNestedGridsByDelta($delta)) {
        foreach (array_keys($grids) as $nid) {
          $rid = GridStackDefault::regionId($delta . '_' . $nid);

          // @todo recheck $box['settings'] = array_diff_key($box['settings'], GridStackDefault::regionSettings());
          // Preserves indices even if empty so to layout for Layout Builder.
          $box[$id][$nid][$id] = isset($regions[$rid]) && !Element::isEmpty($regions[$rid]) ? $regions[$rid] : [];
          $box[$id][$nid]['settings'] = isset($config[$rid]) ? array_merge($box['settings'], $config[$rid]) : $box['settings'];
        }
      }
      else {

        // Preserves indices even if empty so to layout for Layout Builder.
        $box[$id] = isset($regions[$rid]) && !Element::isEmpty($regions[$rid]) ? $regions[$rid] : [];
      }
      $items[] = $box;
      unset($box);
    }
    return $items;
  }

}

Classes

Namesort descending Description
GridStackLayout Provides a GridStack class for Layout plugins.