View source
<?php
namespace Drupal\layout_plugin_views\Plugin\views\row;
use Drupal\Component\Render\MarkupInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\RenderContext;
use Drupal\Core\Layout\LayoutPluginManagerInterface;
use Drupal\layout_plugin_views\Exceptions\NoMarkupGeneratedException;
use Drupal\layout_plugin_views\FieldsPluginOptions;
use Drupal\layout_plugin_views\RegionMap;
use Drupal\views\ResultRow;
use Symfony\Component\DependencyInjection\ContainerInterface;
class Fields extends \Drupal\views\Plugin\views\row\Fields {
private $regionMap;
private $layoutPluginManager;
private $pluginOptions;
public function __construct(array $configuration, $plugin_id, $plugin_definition, LayoutPluginManagerInterface $layout_plugin_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->layoutPluginManager = $layout_plugin_manager;
$this->pluginOptions = FieldsPluginOptions::fromFieldsPlugin($layout_plugin_manager, $this);
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('plugin.manager.core.layout'));
}
protected function defineOptions() {
$options = parent::defineOptions();
$options['layout']['default'] = '';
$options['default_region']['default'] = '';
$options['assigned_regions']['default'] = [];
return $options;
}
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
if ($this->pluginOptions
->hasValidSelectedLayout()) {
$layout_definition = $this->pluginOptions
->getSelectedLayoutDefinition();
}
elseif ($this->pluginOptions
->layoutFallbackIsPossible()) {
$layout_definition = $this->pluginOptions
->getFallbackLayoutDefinition();
}
if (!empty($layout_definition)) {
$form['layout'] = [
'#type' => 'select',
'#title' => $this
->t('Panel layout'),
'#options' => $this->layoutPluginManager
->getLayoutOptions(),
'#default_value' => $layout_definition
->id(),
];
$labels = $layout_definition
->getRegionLabels();
$form['default_region'] = [
'#type' => 'select',
'#title' => $this
->t('Default region'),
'#description' => $this
->t('Defines the region in which the fields will be rendered by default.'),
'#options' => $labels,
'#default_value' => $this->pluginOptions
->getDefaultRegion(),
];
$form['assigned_regions'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Assign regions'),
'#description' => $this
->t('You can use the dropdown menus above to select a region for each field to be rendered in.'),
];
foreach ($this->displayHandler
->getFieldLabels() as $field_name => $field_label) {
$form['assigned_regions'][$field_name] = [
'#type' => 'select',
'#options' => $labels,
'#title' => $field_label,
'#default_value' => $this->pluginOptions
->getAssignedRegion($field_name),
'#empty_option' => $this
->t('Default region'),
];
}
}
}
public function render($row) {
$build = $this
->renderFieldsIntoRegions($row);
return $this
->buildLayoutRenderArray($build);
}
protected function renderFieldsIntoRegions(ResultRow $row) {
$build = [];
foreach ($this
->getRegionMap()
->getNonEmptyRegionNames() as $region_name) {
try {
$fieldsToRender = $this
->getRegionMap()
->getFieldsForRegion($region_name);
$build[$region_name]['#markup'] = $this
->renderFields($row, $fieldsToRender);
} catch (NoMarkupGeneratedException $e) {
}
}
return $build;
}
protected function renderFields(ResultRow $row, array $fieldsToRender) {
$original_fields = $this
->getViewFieldDefinitions();
$this
->setViewFieldDefinitions($fieldsToRender);
$renderer = $this
->getRenderer();
$markup = $renderer
->executeInRenderContext(new RenderContext(), function () use ($row, $renderer) {
$render_array = parent::render($row);
return $renderer
->render($render_array);
});
$this
->setViewFieldDefinitions($original_fields);
if (empty($markup)) {
throw new NoMarkupGeneratedException();
}
return $markup;
}
protected function getViewFieldDefinitions() {
return $this->view->field;
}
protected function setViewFieldDefinitions(array $fieldDefinitions) {
$this->view->field = $fieldDefinitions;
}
private function getRegionMap() {
if (empty($this->regionMap)) {
$this->regionMap = new RegionMap($this, $this->pluginOptions);
}
return $this->regionMap;
}
protected function buildLayoutRenderArray(array $rendered_regions) {
if (!empty($rendered_regions)) {
$layout = $this->layoutPluginManager
->createInstance($this->pluginOptions
->getLayout(), []);
return $layout
->build($rendered_regions);
}
return $rendered_regions;
}
}