You are here

public function ViewsLayoutStyle::render in Views Layout 8

Render the display in this style.

Overrides StylePluginBase::render

File

src/Plugin/views/style/ViewsLayoutStyle.php, line 215

Class

ViewsLayoutStyle
Style plugin for the timeline view.

Namespace

Drupal\views_layout\Plugin\views\style

Code

public function render() {
  if (empty($this->view->rowPlugin)) {
    debug('Drupal\\views\\Plugin\\views\\style\\ViewsLayout: Something is wrong, this plugin is missing.');
    return;
  }
  $options = $this->options;
  $layoutName = $options['layout_name'];
  if (empty($layoutName)) {
    debug('Drupal\\views\\Plugin\\views\\style\\ViewsLayout: No layout was selected for this view.');
    return;
  }
  $layoutRegions = !empty($options['layout_regions'][$layoutName]) ? array_values(array_filter($options['layout_regions'][$layoutName])) : [];
  if (empty($layoutRegions)) {
    debug('Drupal\\views\\Plugin\\views\\style\\ViewsLayout: No regions were selected for this layout.');
    return;
  }
  $definitions = $this->layoutPluginManager
    ->getDefinitions('layout_builder');
  $definition = $definitions[$layoutName];
  $allRegions = array_keys($definition
    ->getRegionLabels());
  $skippedRegions = array_diff($allRegions, $layoutRegions);
  $skipProcessing = $options['skip_processing'];
  $skipText = $options['skip_text'];
  $skipCallback = $options['callback'];

  // Set up layout iterator to keep track of layout position.
  $layoutIterator = new \ArrayIterator($allRegions);

  // Create a layout instance.
  $configuration = [];
  $layoutInstance = $this->layoutPluginManager
    ->createInstance($layoutName, $configuration);

  // Iterate through the views rows and construct as many layout render arrays
  // as the rows allow.
  $newRows = [];
  $layoutRenderArray = [];
  foreach ($this->view->result as $key => $row) {

    // Process skipped regions.
    while (in_array($layoutIterator
      ->current(), $skippedRegions)) {
      if ($skipProcessing == 'text') {
        $renderedRow = [
          '#type' => 'processed_text',
          '#text' => $skipText['value'],
          '#format' => $skipText['format'],
        ];
        $layoutRenderArray[$layoutIterator
          ->current()] = [
          $renderedRow,
        ];
      }
      elseif ($skipProcessing == 'callback' && function_exists($skipCallback)) {
        $renderedRow = $skipCallback($layoutName, $layoutIterator
          ->current(), $this->view);
        $layoutRenderArray[$layoutIterator
          ->current()] = [
          $renderedRow,
        ];
      }
      $layoutIterator
        ->next();
    }

    // Add the the current row to the build.
    // Check for end of array in case a skipped region is the last region.
    if ($layoutIterator
      ->valid()) {
      $renderedRow = $this->view->rowPlugin
        ->render($row);
      $layoutRenderArray[$layoutIterator
        ->current()] = [
        $renderedRow,
      ];
      $layoutIterator
        ->next();
    }

    // When we hit the end of all regions in a layout, stop and build a
    // Views row. We might not be done with all the results yet so we
    // can't break out of our foreach loop.
    if (!$layoutIterator
      ->valid()) {
      $newRows[] = $layoutInstance
        ->build($layoutRenderArray);
      $layoutRenderArray = [];
      $layoutIterator
        ->rewind();
    }
  }

  // If we hit the end of the view results before we hit the end of the
  // layout, and we're not skipping the results, we need to process the
  // remaining regions in the layout.
  if ($layoutIterator
    ->valid() && !empty($skipProcessing)) {
    do {
      if ($skipProcessing == 'text') {
        $renderedRow = [
          '#type' => 'processed_text',
          '#text' => $skipText['value'],
          '#format' => $skipText['format'],
        ];
        $layoutRenderArray[$layoutIterator
          ->current()] = [
          $renderedRow,
        ];
      }
      elseif ($skipProcessing == 'callback' && function_exists($skipCallback)) {
        $renderedRow = $skipCallback($layoutName, $layoutIterator
          ->current(), $this->view);
        $layoutRenderArray[$layoutIterator
          ->current()] = [
          $renderedRow,
        ];
      }
      $layoutIterator
        ->next();
    } while ($layoutIterator
      ->valid());
  }

  // We might have an unrendered layout left. Be sure to pick it up.
  if (!empty($layoutRenderArray)) {
    $newRows[] = $layoutInstance
      ->build($layoutRenderArray);
  }

  // Return the render array.
  $build = array(
    '#theme' => $this
      ->themeFunctions(),
    '#view' => $this->view,
    '#options' => $this->options,
    '#rows' => $newRows,
  );
  return $build;
}