View source
<?php
namespace Drupal\leaflet_views\Plugin\views\row;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\Plugin\views\row\RowPluginBase;
use Drupal\views\ResultRow;
use Drupal\views\ViewExecutable;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\views\Entity\Render\EntityTranslationRenderTrait;
use Drupal\views\ViewsData;
use Drupal\Leaflet\LeafletService;
class LeafletMarker extends RowPluginBase implements ContainerFactoryPluginInterface {
use EntityTranslationRenderTrait;
protected $usesOptions = TRUE;
protected $usesFields = TRUE;
protected $entityTypeId;
protected $entityType;
public $entityManager;
protected $languageManager;
protected $entityFieldManager;
protected $entityDisplay;
protected $renderer;
protected $viewsData;
protected $leafletService;
protected $fieldTypeManager;
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_manager, LanguageManagerInterface $language_manager, EntityFieldManagerInterface $entity_field_manager, EntityDisplayRepositoryInterface $entity_display, RendererInterface $renderer, ViewsData $view_data, LeafletService $leaflet_service, FieldTypePluginManagerInterface $field_type_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityManager = $entity_manager;
$this->languageManager = $language_manager;
$this->entityFieldManager = $entity_field_manager;
$this->entityDisplay = $entity_display;
$this->renderer = $renderer;
$this->viewsData = $view_data;
$this->leafletService = $leaflet_service;
$this->fieldTypeManager = $field_type_manager;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('entity_type.manager'), $container
->get('language_manager'), $container
->get('entity_field.manager'), $container
->get('entity_display.repository'), $container
->get('renderer'), $container
->get('views.views_data'), $container
->get('leaflet.service'), $container
->get('plugin.manager.field.field_type'));
}
public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
parent::init($view, $display, $options);
$this->entityTypeId = $view
->getBaseEntityType()
->id();
$this->entityType = $this->entityManager
->getDefinition($this->entityTypeId);
}
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$fields = [];
$fields_geo_data = [];
foreach ($this->displayHandler
->getHandlers('field') as $field_id => $handler) {
$label = $handler
->adminLabel() ?: $field_id;
$fields[$field_id] = $label;
if (is_a($handler, 'Drupal\\views\\Plugin\\views\\field\\EntityField')) {
$field_storage_definitions = $this->entityFieldManager
->getFieldStorageDefinitions($handler
->getEntityType());
$field_storage_definition = $field_storage_definitions[$handler->definition['field_name']];
$type = $field_storage_definition
->getType();
$definition = $this->fieldTypeManager
->getDefinition($type);
if (is_a($definition['class'], '\\Drupal\\geofield\\Plugin\\Field\\FieldType\\GeofieldItem', TRUE)) {
$fields_geo_data[$field_id] = $label;
}
}
}
if (!count($fields_geo_data)) {
$form['error'] = [
'#markup' => $this
->t('Please add at least one geofield to the view.'),
];
return;
}
$form['data_source'] = [
'#type' => 'select',
'#title' => $this
->t('Data Source'),
'#description' => $this
->t('Which field contains geodata?'),
'#options' => $fields_geo_data,
'#default_value' => $this->options['data_source'],
'#required' => TRUE,
];
$form['name_field'] = [
'#type' => 'select',
'#title' => $this
->t('Title Field'),
'#description' => $this
->t('Choose the field which will appear as a title on tooltips.'),
'#options' => $fields,
'#default_value' => $this->options['name_field'],
'#empty_value' => '',
];
$desc_options = $fields;
if ($this->entityTypeId) {
$desc_options += [
'#rendered_entity' => '<' . $this
->t('Rendered @entity entity', [
'@entity' => $this->entityTypeId,
]) . '>',
];
}
$form['description_field'] = [
'#type' => 'select',
'#title' => $this
->t('Description Field'),
'#description' => $this
->t('Choose the field or rendering method which will appear as a description on tooltips or popups.'),
'#options' => $desc_options,
'#default_value' => $this->options['description_field'],
'#empty_value' => '',
];
if ($this->entityTypeId) {
$view_mode_options = [];
foreach ($this->entityDisplay
->getViewModes($this->entityTypeId) as $key => $view_mode) {
$view_mode_options[$key] = $view_mode['label'];
}
$form['view_mode'] = [
'#type' => 'select',
'#title' => $this
->t('View mode'),
'#description' => $this
->t('View modes are ways of displaying entities.'),
'#options' => $view_mode_options,
'#default_value' => !empty($this->options['view_mode']) ? $this->options['view_mode'] : 'full',
'#states' => [
'visible' => [
':input[name="row_options[description_field]"]' => [
'value' => '#rendered_entity',
],
],
],
];
}
}
public function render($row) {
$geofield_value = $this->view
->getStyle()
->getFieldValue($row->index, $this->options['data_source']);
if (empty($geofield_value)) {
return FALSE;
}
$result = $this->leafletService
->leafletProcessGeofield($geofield_value);
return $this
->renderLeafletMarkers($result, $row);
}
protected function renderLeafletMarkers(array $points, ResultRow $row) {
$popup_body = '';
if ($this->options['description_field'] === '#rendered_entity' && is_object($row->_entity)) {
$entity = $row->_entity;
$build = $this
->getEntityManager()
->getViewBuilder($entity
->getEntityTypeId())
->view($entity, $this->options['view_mode']);
$popup_body = $this->renderer
->renderPlain($build);
}
elseif ($this->options['description_field']) {
$popup_body = $this->view
->getStyle()
->getField($row->index, $this->options['description_field']);
}
$label = $this->view
->getStyle()
->getField($row->index, $this->options['name_field']);
foreach ($points as &$point) {
$point['popup'] = $popup_body;
$point['label'] = $label;
$this
->alterLeafletMarker($point, $row);
\Drupal::moduleHandler()
->alter('leaflet_views_feature', $point, $row, $this);
}
return $points;
}
protected function alterLeafletMarker(array &$point, ResultRow $row) {
}
public function getEntityTypeId() {
return $this->entityType
->id();
}
protected function getEntityManager() {
return $this->entityManager;
}
protected function getLanguageManager() {
return $this->languageManager;
}
protected function getView() {
return $this->view;
}
public function query() {
parent::query();
$this
->getEntityTranslationRenderer()
->query($this->view
->getQuery());
}
public function preRender($result) {
parent::preRender($result);
if ($result) {
$this
->getEntityTranslationRenderer()
->preRender($result);
}
}
public function validate() {
$errors = parent::validate();
if (empty($this->options['data_source'])) {
$errors[] = $this
->t('Row @row requires the data source to be configured.', [
'@row' => $this->definition['title'],
]);
}
return $errors;
}
protected function defineOptions() {
$options = parent::defineOptions();
$options['data_source'] = [
'default' => '',
];
$options['name_field'] = [
'default' => '',
];
$options['description_field'] = [
'default' => '',
];
$options['view_mode'] = [
'default' => 'teaser',
];
return $options;
}
}