View source
<?php
namespace Drupal\geofield_map\Plugin\views\style;
use Drupal\geofield_map\GeofieldMapFieldTrait;
use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\Plugin\views\style\DefaultStyle;
use Drupal\views\ViewExecutable;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
use Drupal\Core\Utility\LinkGeneratorInterface;
use Drupal\geofield\GeoPHP\GeoPHPInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Render\RendererInterface;
class GeofieldGoogleMapViewStyle extends DefaultStyle implements ContainerFactoryPluginInterface {
use GeofieldMapFieldTrait;
protected $emptyMapOptions = [
'0' => 'View No Results Behaviour',
'1' => 'Empty Map Centered at the Default Center',
];
protected $config;
protected $entityType;
protected $entityInfo;
protected $entityManager;
protected $entityFieldManager;
protected $entityDisplay;
protected $link;
protected $geoPhpWrapper;
protected $currentUser;
protected $renderer;
public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_manager, EntityFieldManagerInterface $entity_field_manager, EntityDisplayRepositoryInterface $entity_display, LinkGeneratorInterface $link_generator, GeoPHPInterface $geophp_wrapper, AccountInterface $current_user, RendererInterface $renderer) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityManager = $entity_manager;
$this->entityFieldManager = $entity_field_manager;
$this->entityDisplay = $entity_display;
$this->config = $config_factory;
$this->link = $link_generator;
$this->geoPhpWrapper = $geophp_wrapper;
$this->currentUser = $current_user;
$this->renderer = $renderer;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('config.factory'), $container
->get('entity_type.manager'), $container
->get('entity_field.manager'), $container
->get('entity_display.repository'), $container
->get('link_generator'), $container
->get('geofield.geophp'), $container
->get('current_user'), $container
->get('renderer'));
}
public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
parent::init($view, $display, $options);
$base_tables = array_keys($view
->getBaseTables());
$base_table = reset($base_tables);
foreach ($this->entityManager
->getDefinitions() as $key => $info) {
if ($info
->getDataTable() == $base_table) {
$this->entityType = $key;
$this->entityInfo = $info;
return;
}
}
}
protected $usesRowPlugin = FALSE;
protected $usesRowClass = FALSE;
protected $usesGrouping = FALSE;
protected $usesFields = TRUE;
protected $defaultFieldLabels = TRUE;
public function evenEmpty() {
return TRUE;
}
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$default_settings = self::defineOptions();
$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']];
if ($field_storage_definition
->getType() == 'geofield') {
$fields_geo_data[$field_id] = $label;
}
}
}
if (empty($fields_geo_data)) {
$form['error'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => $this
->t('Please add at least one Geofield to the View and come back here to set it as Data Source.'),
'#attributes' => [
'class' => [
'geofield-map-warning',
],
],
'#attached' => [
'library' => [
'geofield_map/geofield_map_general',
],
],
];
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,
];
$desc_options = array_merge([
'0' => $this
->t('- Any - No Infowindow'),
], $fields);
if ($this->entityType) {
$desc_options += [
'#rendered_entity' => $this
->t('- Rendered @entity entity -', [
'@entity' => $this->entityType,
]),
];
}
$this->options['infowindow_content_options'] = $desc_options;
if ($this->entityType) {
$view_mode_options = [];
foreach ($this->entityDisplay
->getViewModes($this->entityType) as $key => $view_mode) {
$view_mode_options[$key] = $view_mode['label'];
}
$form['view_mode'] = [
'#fieldset' => 'map_marker_and_infowindow',
'#type' => 'select',
'#title' => $this
->t('View mode'),
'#description' => $this
->t('View mode the entity will be displayed in the Infowindow.'),
'#options' => $view_mode_options,
'#default_value' => !empty($this->options['view_mode']) ? $this->options['view_mode'] : 'full',
'#states' => [
'visible' => [
':input[name="style_options[map_marker_and_infowindow][infowindow_field]"]' => [
'value' => '#rendered_entity',
],
],
],
];
}
$form = $form + $this
->generateGmapSettingsForm($form, $form_state, $this->options, $default_settings);
}
public function render() {
$map_settings = $this->options;
$element = [];
$this
->preProcessMapSettings($map_settings);
$js_settings = [
'mapid' => Html::getUniqueId("geofield_map_view_" . $this->view
->id() . '_' . $this->view->current_display),
'map_settings' => $map_settings,
'data' => [],
];
$data = [];
$geofield_name = $map_settings['data_source'];
if (empty($geofield_name) && $this->currentUser
->hasPermission('configure geofield_map')) {
$element = [
'#markup' => '<div class="geofield-map-warning">' . $this
->t("The Geofield field hasn't not been correctly set for this View. <br>Add at least one Geofield to the View and set it as Data Source in the Geofield Google Map View Display Settings.") . "</div>",
'#attached' => [
'library' => [
'geofield_map/geofield_map_general',
],
],
];
}
if (!empty($geofield_name) && (!empty($this->view->result) || $map_settings['map_empty']['empty_behaviour'] == '1')) {
$this
->renderFields($this->view->result);
foreach ($this->view->result as $id => $result) {
$geofield_value = $this
->getFieldValue($id, $geofield_name);
if (empty($geofield_value)) {
$geofield_value = $this->rendered_fields[$id][$geofield_name];
}
if (!empty($geofield_value)) {
$geofield_value = is_array($geofield_value) ? $geofield_value : [
$geofield_value,
];
$description_field = isset($map_settings['map_marker_and_infowindow']['infowindow_field']) ? $map_settings['map_marker_and_infowindow']['infowindow_field'] : NULL;
$description = [];
$entity = $result->_entity;
if (isset($description_field) && $description_field === '#rendered_entity' && is_object($result)) {
$build = $this->entityManager
->getViewBuilder($entity
->getEntityTypeId())
->view($entity, $map_settings['view_mode'], $entity
->language()
->getId());
$description[] = $this->renderer
->renderPlain($build);
}
elseif (isset($description_field)) {
$description_field_name = strtolower($map_settings['map_marker_and_infowindow']['infowindow_field']);
if (isset($entity->{$description_field_name})) {
foreach ($entity->{$description_field_name}
->getValue() as $value) {
if ($map_settings['map_marker_and_infowindow']['multivalue_split'] == FALSE) {
$description[] = $this->rendered_fields[$id][$description_field];
break;
}
$description[] = isset($value['value']) ? $value['value'] : '';
}
}
elseif (isset($this->rendered_fields[$id][$description_field])) {
$description[] = $this->rendered_fields[$id][$description_field];
}
}
$view_data = [];
foreach ($this->rendered_fields[$id] as $field_name => $rendered_field) {
if (!empty($rendered_field) && !$this->view->field[$field_name]->options['exclude']) {
$view_data[$field_name] = $rendered_field
->__toString();
}
}
$data = array_merge($data, $this
->getGeoJsonData($geofield_value, $description, $view_data));
}
}
$js_settings['data'] = [
'type' => 'FeatureCollection',
'features' => $data,
];
$element = geofield_map_googlemap_render($js_settings);
}
return $element;
}
protected function defineOptions() {
$options = parent::defineOptions();
$options['data_source'] = [
'default' => '',
];
$options['name_field'] = [
'default' => '',
];
$options['description_field'] = [
'default' => '',
];
$options['view_mode'] = [
'default' => 'full',
];
$geofield_google_map_default_settings = [];
foreach (self::getDefaultSettings() as $k => $setting) {
$geofield_google_map_default_settings[$k] = [
'default' => $setting,
];
}
return $options + $geofield_google_map_default_settings;
}
}