You are here

public function StyledGoogleMapStyle::render in Styled Google Map 8.2

Render the display in this style.

Overrides StylePluginBase::render

File

src/Plugin/views/style/StyledGoogleMapStyle.php, line 779

Class

StyledGoogleMapStyle
Views area StyledGoogleMapStyle handler.

Namespace

Drupal\styled_google_map\Plugin\views\style

Code

public function render($results = []) {

  // We check if the views result are empty, or if the settings of this area
  // force showing this area even if the view is empty.
  if (!empty($this->view->live_preview)) {
    $output['preview'] = [
      '#markup' => '<p>' . $this
        ->t('This is a preview of styled google map plugin. No map is displayed.') . '</p>',
    ];
    $output['maps'] = [
      '#markup' => '<p>' . $this
        ->t('This map has @num points', [
        '@num' => count($results),
      ]) . '</p>',
    ];
    return $output;
  }
  $locations = [];
  $heat_map_coords = [];
  if (!empty($results)) {

    // Get all geofield locations.
    foreach ($results as $row_index => $row) {
      $sourceHandlerOutput = [];

      // Render all fields first, so they are available for token replacement.

      /** @var \Drupal\views\Plugin\views\field\Field $handler */
      foreach ($this->displayHandler
        ->getHandlers('field') as $field => $handler) {
        $handler->view->row_index = $row_index;
        $output = $handler
          ->advancedRender($row);
        $placeholders = $handler
          ->postRender($row, $output);
        $output = ViewsRenderPipelineMarkup::create(str_replace(array_keys($placeholders), array_values($placeholders), $output));
        $sourceHandlerOutput[$field] = $output;
      }
      $location = [];
      if (!empty($this->options['data_source']) && !empty($sourceHandlerOutput[$this->options['data_source']])) {

        // Add geofield data.
        try {
          $geom = geoPHP::load($sourceHandlerOutput[$this->options['data_source']]);
          if (!empty($geom)) {

            /** @var \Geometry $centroid */
            $centroid = $geom
              ->getCentroid();
            $point = [];
            $point['lon'] = $centroid
              ->getX();
            $point['lat'] = $centroid
              ->getY();
            $location = $location + $point;
            if ($this->options['heatmap_settings']['heatmap_enabled']) {
              $heat_map_coords[] = $point + [
                'weight' => 0,
              ];
            }
          }
          else {
            continue;
          }
        } catch (\Exception $e) {
          continue;
        }
        if (!empty($this->options['default_pin_source'])) {
          $location['pin'] = file_create_url($this->options['default_pin_source']);
          if (!empty($this->options['main']['styled_google_map_view_active_pin'])) {
            $location['active_pin'] = file_create_url($this->options['main']['styled_google_map_view_active_pin']);
          }
        }

        // Add pin image url.
        if (!empty($this->options['pin_source']) && !empty($sourceHandlerOutput[$this->options['pin_source']])) {

          /** @var \Drupal\views\Plugin\views\field\FieldHandlerInterface $sourceHandler */
          $sourceHandler = $this->displayHandler
            ->getHandler('field', $this->options['pin_source']);
          $fileTargetId = $sourceHandler
            ->render($row);
          if ($fileTargetId instanceof ViewsRenderPipelineMarkup) {
            $image = File::load($fileTargetId
              ->__toString());
            $location['pin'] = file_create_url($image
              ->getFileUri());

            // Add the active pin image.
            if (!empty($this->options['active_pin_source']) && !empty($sourceHandlerOutput[$this->options['active_pin_source']])) {

              /** @var \Drupal\views\Plugin\views\field\FieldHandlerInterface $sourceHandler */
              $sourceHandler = $this->displayHandler
                ->getHandler('field', $this->options['active_pin_source']);
              $fileTargetId = $sourceHandler
                ->render($row);
              if ($fileTargetId instanceof ViewsRenderPipelineMarkup) {
                $image = File::load($fileTargetId
                  ->__toString());
                $location['active_pin'] = file_create_url($image
                  ->getFileUri());
              }
            }
            elseif (empty($this->options['main']['styled_google_map_view_active_pin'])) {
              $location['active_pin'] = file_create_url($image
                ->getFileUri());
            }
            else {
              $location['active_pin'] = file_create_url($this->options['main']['styled_google_map_view_active_pin']);
            }
          }
          elseif (!empty($this->options['default_pin_source'])) {
            $location['pin'] = file_create_url($this->options['default_pin_source']);
          }
        }

        // Add marker Label.
        if (!empty($this->options['marker_label']) && isset($sourceHandlerOutput[$this->options['marker_label']])) {
          $markerLabelRenderArray = [
            '#markup' => $sourceHandlerOutput[$this->options['marker_label']],
          ];
          $marker = \Drupal::service('renderer')
            ->renderPlain($markerLabelRenderArray);
          $marker = strip_tags($marker);
          $location = $location + [
            'marker_label' => [
              'text' => $marker,
              'color' => $this->options['marker_label_settings']['color'],
              'fontFamily' => $this->options['marker_label_settings']['fontFamily'],
              'fontSize' => $this->options['marker_label_settings']['fontSize'],
              'fontWeight' => $this->options['marker_label_settings']['fontWeight'],
            ],
          ];
        }

        // Add pin popup html.
        if (!empty($this->options['popup_source']) && !empty($sourceHandlerOutput[$this->options['popup_source']])) {
          $popupRenderArray = [
            '#markup' => $sourceHandlerOutput[$this->options['popup_source']],
          ];
          $location = $location + [
            'popup' => \Drupal::service('renderer')
              ->renderPlain($popupRenderArray),
          ];
        }

        // Add category.
        if (!empty($this->options['category_source']) && !empty($sourceHandlerOutput[$this->options['category_source']])) {
          $categoryRenderArray = [
            '#markup' => $sourceHandlerOutput[$this->options['category_source']],
          ];
          $category = \Drupal::service('renderer')
            ->renderPlain($categoryRenderArray);
          $location = $location + [
            'category' => Html::cleanCssIdentifier($category),
          ];
        }
      }
      if ($location) {
        $locations[] = $location;
      }

      // Gather heatmap weights.
      if (!empty($this->options['heatmap_settings']['data_source']) && !empty($sourceHandlerOutput[$this->options['heatmap_settings']['data_source']])) {
        $weightRenderArray = [
          '#markup' => $sourceHandlerOutput[$this->options['heatmap_settings']['data_source']],
        ];
        $weight = \Drupal::service('renderer')
          ->renderPlain($weightRenderArray);
        $heat_map_coords[$row_index]['weight'] = $weight;
      }
    }
  }

  // Add custom settings.
  $cluster = [];
  if ($this->options['cluster_settings']['cluster_enabled']) {
    $cluster_pin_image = file_create_url($this->options['cluster_settings']['pin_image']);
    $cluster = [
      'pin_image' => $cluster_pin_image,
    ] + $this->options['cluster_settings'];
  }

  // Spider settings.
  $spider = [];
  if ($this->options['spider_settings']['spider_enabled']) {
    $spider_pin_image = file_create_url($this->options['spider_settings']['pin_image']);
    $spider = [
      'pin_image' => $spider_pin_image,
    ] + $this->options['spider_settings'];
  }

  // Heat map settings.
  $heat_map = [];
  if ($this->options['heatmap_settings']['heatmap_enabled'] && !empty($heat_map_coords)) {
    $heat_map = [
      'data' => $heat_map_coords,
    ] + $this->options['heatmap_settings'];
    if (!empty($heat_map['gradient'])) {
      $heat_map['gradient'] = explode("\r\n", $heat_map['gradient']);
    }
  }

  // @TODO: sanitize all options.
  $rand = rand();
  $map_id = $this->view->dom_id . $rand;
  $map_settings = [
    'id' => 'map_' . $map_id,
    'locations' => $locations,
    'settings' => [
      'gestureHandling' => $this->options['main']['styled_google_map_gesture_handling'],
      'height' => $this->options['main']['styled_google_map_view_height'],
      'width' => $this->options['main']['styled_google_map_view_width'],
      'maptypecontrol' => $this->options['main']['styled_google_map_view_maptypecontrol'],
      'scalecontrol' => $this->options['main']['styled_google_map_view_scalecontrol'],
      'rotatecontrol' => $this->options['main']['styled_google_map_view_rotatecontrol'],
      'draggable' => $this->options['main']['styled_google_map_view_draggable'],
      'mobile_draggable' => $this->options['main']['styled_google_map_view_mobile_draggable'],
      'streetviewcontrol' => $this->options['main']['styled_google_map_view_streetviewcontrol'],
      'style' => [
        'maptype' => $this->options['main']['styled_google_map_view_maptype'],
        'style' => $this->options['main']['styled_google_map_view_style'],
        'pin_width' => $this->options['main']['styled_google_map_view_pin_width'],
        'pin_height' => $this->options['main']['styled_google_map_view_pin_height'],
      ],
      'zoom' => [
        'default' => $this->options['main']['styled_google_map_view_zoom_default'],
        'max' => $this->options['main']['styled_google_map_view_zoom_max'],
        'min' => $this->options['main']['styled_google_map_view_zoom_min'],
      ],
      'zoomcontrol' => $this->options['main']['styled_google_map_view_zoomcontrol'],
      'fullscreen' => $this->options['main']['styled_google_map_view_fullscreen'],
      'marker_label' => [
        'color' => $this->options['marker_label_settings']['color'],
        'fontFamily' => $this->options['marker_label_settings']['fontFamily'],
        'fontSize' => $this->options['marker_label_settings']['fontSize'],
        'fontWeight' => $this->options['marker_label_settings']['fontWeight'],
      ],
      'popup' => [
        'open_event' => $this->options['popup']['open_event'] ? $this->options['popup']['open_event'] : 'click',
        'second_click' => $this->options['popup']['second_click'] ? $this->options['popup']['second_click'] : 0,
        'disable_animation' => $this->options['popup']['styled_google_map_view_disable_animation'] ? TRUE : FALSE,
        'disable_autopan' => $this->options['popup']['styled_google_map_view_disable_auto_pan'] ? TRUE : FALSE,
        'hide_close_button' => $this->options['popup']['styled_google_map_view_hide_close_button'] ? TRUE : FALSE,
        'shadow_style' => $this->options['popup']['styled_google_map_view_shadow_style'],
        'padding' => $this->options['popup']['styled_google_map_view_padding'],
        'close_button_source' => !empty($this->options['popup']['close_button_source']) ? file_create_url($this->options['popup']['close_button_source']) : FALSE,
        'border_radius' => $this->options['popup']['styled_google_map_view_border_radius'],
        'border_width' => $this->options['popup']['styled_google_map_view_border_width'],
        'border_color' => $this->options['popup']['styled_google_map_view_border_color'],
        'background_color' => $this->options['popup']['styled_google_map_view_background_color'],
        'min_width' => $this->options['popup']['styled_google_map_view_min_width'],
        'max_width' => $this->options['popup']['styled_google_map_view_max_width'],
        'min_height' => $this->options['popup']['styled_google_map_view_min_height'],
        'max_height' => $this->options['popup']['styled_google_map_view_max_height'],
        'arrow_style' => $this->options['popup']['styled_google_map_view_arrow_style'],
        'arrow_size' => $this->options['popup']['styled_google_map_view_arrow_size'],
        'arrow_position' => $this->options['popup']['styled_google_map_view_arrow_position'],
        'classes' => [
          'container' => $this->options['popup_classes']['styled_google_map_view_content_container_class'],
          'background' => $this->options['popup_classes']['styled_google_map_view_background_class'],
          'arrow' => $this->options['popup_classes']['styled_google_map_view_arrow_class'],
          'arrow_outer' => $this->options['popup_classes']['styled_google_map_view_arrow_outer_class'],
          'arrow_inner' => $this->options['popup_classes']['styled_google_map_view_arrow_inner_class'],
        ],
      ],
    ],
  ];

  // If cluster feature is enabled.
  if (!empty($cluster)) {
    $map_settings['settings']['cluster'] = $cluster;
  }

  // If spiderfier feature is enabled.
  if (!empty($spider)) {
    $map_settings['settings']['spider'] = $spider;
  }

  // If heat map feature is enabled.
  if (!empty($heat_map)) {
    $map_settings['settings']['heat_map'] = $heat_map;
  }

  // Check if the custom map center option is enabled.
  if (!empty($this->options['main']['styled_google_map_default_map_center'])) {
    $map_settings['settings']['map_center'] = [
      'center_coordinates' => [
        'lat' => $this->options['main']['styled_google_map_default_map_center']['lat'],
        'lon' => $this->options['main']['styled_google_map_default_map_center']['lon'],
      ],
    ];
  }

  // Allow other modules to change the styled_google_map settings.
  $alter_vars = [
    'map_settings' => $map_settings,
    'context' => [
      'view' => $this->view,
      'options' => $this->options,
    ],
  ];
  \Drupal::moduleHandler()
    ->alter('styled_google_map_views_style', $alter_vars);
  $map_settings = $alter_vars['map_settings'];

  // Prepare the output of the view style.
  $output = [];
  $output['#attached']['drupalSettings']['styled_google_map'] = [
    'map_' . $map_id => 'map_' . $map_id,
  ];
  $output['#attached']['drupalSettings']['maps'] = [
    'idmap_' . $map_id => $map_settings,
  ];

  // Output a div placeholder for the Styled Google Map.
  $output['styled_google_map']['#markup'] = '<div class="styled_map" id="map_' . $map_id . '"></div>';

  // Attach the Styled Google Map javascript file.
  $output['#attached']['library'][] = 'styled_google_map/styled-google-map';
  if (!empty($cluster)) {
    $output['#attached']['library'][] = 'styled_google_map/google-map-clusters';
  }
  if (!empty($spider)) {
    $output['#attached']['library'][] = 'styled_google_map/spiderfier';
  }
  if (!empty($heat_map)) {
    $output['#attached']['library'][] = 'styled_google_map/heatmap';
  }
  return $output;
}