public function GeofieldGoogleMapViewStyle::render in Geofield Map 8.2
Same name and namespace in other branches
- 8 src/Plugin/views/style/GeofieldGoogleMapViewStyle.php \Drupal\geofield_map\Plugin\views\style\GeofieldGoogleMapViewStyle::render()
Renders the View.
Overrides StylePluginBase::render
File
- src/
Plugin/ views/ style/ GeofieldGoogleMapViewStyle.php, line 802
Class
- GeofieldGoogleMapViewStyle
- Style plugin to render a View output as a Leaflet map.
Namespace
Drupal\geofield_map\Plugin\views\styleCode
public function render() {
$map_settings = $this->options;
$element = [];
// Performs some preprocess on the maps settings before sending to js.
$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 = [];
// Collect bubbleable metadata when doing early rendering.
$build_for_bubbleable_metadata = [];
// Get the Geofield field.
$geofield_name = $map_settings['data_source'];
// If the Geofield field is null, output a warning
// to the Geofield Map administrator.
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',
],
],
];
}
// It the Geofield field is not null, and there are results or a not null
// empty behaviour has been set, render the results.
if (!empty($geofield_name) && (!empty($this->view->result) || $map_settings['map_empty']['empty_behaviour'] == '1')) {
$this
->renderFields($this->view->result);
/* @var \Drupal\views\ResultRow $result */
foreach ($this->view->result as $id => $result) {
// For proper processing make sure the geofield_value is created as an
// array, also if single value.
$geofield_value = (array) $this
->getFieldValue($id, $geofield_name);
// In case the result is not null.
if (!empty($geofield_value)) {
if (empty($this->options['entity_source']) || $this->options['entity_source'] == '__base_table') {
if (!empty($result->_entity)) {
// Entity API provides a plain entity object.
$entity = $result->_entity;
}
elseif (isset($result->_object)) {
// Search API provides a TypedData EntityAdapter.
$entity_adapter = $result->_object;
if ($entity_adapter instanceof EntityAdapter) {
$entity = $entity_adapter
->getValue();
}
}
}
else {
if (!empty($result->_relationship_entities[$this->options['entity_source']])) {
$entity = $result->_relationship_entities[$this->options['entity_source']];
}
}
// We need to define this before.
$description = [];
// Render the entity with the selected view mode.
/* @var \Drupal\core\Entity\FieldableEntityInterface $entity */
if (isset($entity)) {
// Get and set (if not set) the Geofield cardinality.
/* @var \Drupal\Core\Field\FieldItemList $geofield_entity */
if (!isset($js_settings['map_settings']['geofield_cardinality'])) {
try {
$geofield_entity = $entity
->get($geofield_name);
$js_settings['map_settings']['geofield_cardinality'] = $geofield_entity
->getFieldDefinition()
->getFieldStorageDefinition()
->getCardinality();
} catch (\Exception $e) {
// In case of exception it means that $geofield_name field is
// not directly related to the $entity and might be the case of
// a geofield exposed through a relationship.
// In this case it is too complicate to get the geofield related
// entity, so apply a more general case of multiple/infinite
// geofield_cardinality.
// @see: https://www.drupal.org/project/leaflet/issues/3048089
$js_settings['map_settings']['geofield_cardinality'] = -1;
}
}
$entity_type = $entity
->getEntityTypeId();
$entity_type_langcode_attribute = $entity_type . '_field_data_langcode';
$view = $this->view;
// Set the langcode to be used for rendering the entity.
$rendering_language = $view->display_handler
->getOption('rendering_language');
$dynamic_renderers = [
'***LANGUAGE_entity_translation***' => 'TranslationLanguageRenderer',
'***LANGUAGE_entity_default***' => 'DefaultLanguageRenderer',
];
if (isset($dynamic_renderers[$rendering_language])) {
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
$langcode = isset($result->{$entity_type_langcode_attribute}) ? $result->{$entity_type_langcode_attribute} : $entity
->language()
->getId();
}
else {
if (strpos($rendering_language, '***LANGUAGE_') !== FALSE) {
$langcode = PluginBase::queryLanguageSubstitutions()[$rendering_language];
}
else {
// Specific langcode set.
$langcode = $rendering_language;
}
}
$description_field = isset($map_settings['map_marker_and_infowindow']['infowindow_field']) ? $map_settings['map_marker_and_infowindow']['infowindow_field'] : NULL;
if (isset($description_field)) {
/* @var \Drupal\Core\Field\FieldItemList $description_field_entity */
$description_field_entity = $entity->{$description_field};
// Assure the view_mode to eventually fallback into the
// (initially defined) $this->options['view_mode'].
$default_view_mode = !empty($this->options['view_mode']) ? $this->options['view_mode'] : (!empty($this->options['map_marker_and_infowindow']['view_mode']) ? $this->options['map_marker_and_infowindow']['view_mode'] : NULL);
switch ($description_field) {
case '#rendered_entity':
$build = $this->entityManager
->getViewBuilder($entity
->getEntityTypeId())
->view($entity, $default_view_mode, $langcode);
$render_context = new RenderContext();
$description[] = $this->renderer
->executeInRenderContext($render_context, function () use (&$build) {
return $this->renderer
->render($build, TRUE);
});
if (!$render_context
->isEmpty()) {
$render_context
->update($build_for_bubbleable_metadata);
}
break;
case '#rendered_view_fields':
// Normal rendering via view/row fields (with labels options,
// formatters, classes, etc.).
$renderedRow = [
$this->view->rowPlugin
->render($result),
];
$description[] = $this->renderer
->renderPlain($renderedRow);
break;
case '#rendered_entity_ajax':
$parameters = [
'entity_type' => $entity_type,
'entity' => $entity
->id(),
'view_mode' => $default_view_mode,
'langcode' => $langcode,
];
$url = Url::fromRoute('geofield_map.ajax_popup', $parameters);
$description[] = sprintf('<div class="geofield-google-map-ajax-popup" data-geofield-google-map-ajax-popup="%s" %s></div>', $url
->toString(), GeofieldMapAjaxPopupController::getPopupIdentifierAttribute($entity_type, $entity
->id(), $default_view_mode, $langcode));
$js_settings['map_settings']['ajaxPoup'] = TRUE;
break;
default:
// Check if the entity has a $description_field field.
if (isset($description_field_entity)) {
$description_field_cardinality = $description_field_entity
->getFieldDefinition()
->getFieldStorageDefinition()
->getCardinality();
foreach ($description_field_entity
->getValue() as $value) {
if ($description_field_cardinality == 1 || $map_settings['map_marker_and_infowindow']['multivalue_split'] == FALSE) {
$description[] = $this->rendered_fields[$id][$description_field];
break;
}
$description[] = isset($value['value']) ? $value['value'] : NULL;
}
}
elseif (isset($this->rendered_fields[$id][$description_field])) {
$description[] = $this->rendered_fields[$id][$description_field];
}
}
}
// Add Views fields to Json output as additional_data property.
$view_data = [];
foreach ($this->rendered_fields[$id] as $field_name => $rendered_field) {
if (!empty($rendered_field) && !$this->view->field[$field_name]->options['exclude']) {
/* @var \Drupal\Core\Render\Markup $rendered_field */
$view_data[$field_name] = $rendered_field
->__toString();
}
}
// Define a Tooltip for the Feature.
$tooltip_field = isset($map_settings['map_marker_and_infowindow']['tooltip_field']) ? $map_settings['map_marker_and_infowindow']['tooltip_field'] : NULL;
$tooltip = isset($entity) && !empty($tooltip_field) ? trim(html_entity_decode(strip_tags($this->rendered_fields[$id][$tooltip_field]), ENT_QUOTES)) : NULL;
// Define possible tokens.
$tokens = [];
foreach ($this->rendered_fields[$result->index] as $field_name => $field_value) {
$tokens[$field_name] = $field_value;
}
// Generate GeoJsonData.
$geojson_data = $this
->getGeoJsonData($geofield_value, $entity
->id(), $description, $tooltip, $view_data);
// Add Theming Icon based on the $theming plugin.
$theming = NULL;
if (isset($map_settings['map_marker_and_infowindow']['theming']) && $map_settings['map_marker_and_infowindow']['theming']['plugin_id'] != 'none') {
$theming = $map_settings['map_marker_and_infowindow']['theming'];
try {
/* @var \Drupal\geofield_map\MapThemerInterface $map_themer */
$map_themer = $this->mapThemerManager
->createInstance($theming['plugin_id'], [
'geofieldMapView' => $this,
]);
$map_theming = $theming[$map_themer
->getPluginId()]['values'];
foreach ($geojson_data as $k => $datum) {
if ($datum['geometry']->type === 'Point') {
$geojson_data[$k]['properties']['icon'] = $map_themer
->getIcon($datum, $this, $entity, $map_theming);
// Flag the data with theming, for later rendering logic.
$geojson_data[$k]['properties']['theming'] = TRUE;
}
}
} catch (PluginException $e) {
watchdog_exception('geofield_map', $e);
}
}
elseif ($map_settings['map_marker_and_infowindow']['icon_image_mode'] == 'icon_file' && strlen($map_settings['map_marker_and_infowindow']['icon_image_path']) > 0) {
foreach ($geojson_data as $k => $datum) {
if ($datum['geometry']->type === 'Point') {
$geojson_data[$k]['properties']['icon'] = $this
->viewsTokenReplace($this->options['map_marker_and_infowindow']['icon_image_path'], $tokens);
}
}
}
// Associate dynamic path properties (token based) to each feature,
// in case of not point.
foreach ($geojson_data as $k => $datum) {
if ($datum['geometry']->type !== 'Point') {
$geojson_data[$k]['properties']['path_options'] = str_replace([
"\n",
"\r",
], "", $this
->viewsTokenReplace($this->options['map_geometries_options'], $tokens));
}
}
// Generate incremental GeoJsonData.
$data = array_merge($data, $geojson_data);
}
}
}
$js_settings['data'] = [
'type' => 'FeatureCollection',
'features' => $data,
];
// Allow other modules to add/alter the map js settings.
$this->moduleHandler
->alter('geofield_map_googlemap_view_style', $js_settings, $this);
$element = geofield_map_googlemap_render($js_settings);
// Add the Core Drupal Ajax library for Ajax Popups.
if (isset($js_settings['map_settings']['ajaxPoup']) && $js_settings['map_settings']['ajaxPoup'] == TRUE) {
$build_for_bubbleable_metadata['#attached']['library'][] = 'core/drupal.ajax';
}
BubbleableMetadata::createFromRenderArray($element)
->merge(BubbleableMetadata::createFromRenderArray($build_for_bubbleable_metadata))
->applyTo($element);
}
return $element;
}