You are here

public function IpGeoLocViewsPluginStyle::pluginStyleExtractLocations in IP Geolocation Views & Maps 8

Extract an array of locations from the supplied views_plugin_style.

Parameters

string $views_plugin_style: The style of views plugin.

Return value

array Array of location objects, each containing lat/long and balloon_text

File

src/Services/IpGeoLocViewsPluginStyle.php, line 631

Class

IpGeoLocViewsPluginStyle
Class IpGeoLocViewsPluginStyle.

Namespace

Drupal\ip_geoloc\Services

Code

public function pluginStyleExtractLocations($views_plugin_style) {
  $latitude = trim($views_plugin_style->options['ip_geoloc_views_plugin_latitude']);
  $longitude = trim($views_plugin_style->options['ip_geoloc_views_plugin_longitude']);
  $view =& $views_plugin_style->view;
  $view_id = $view->storage
    ->getOriginalId();
  $display_id = $view
    ->getDisplay()->display['id'];
  $differentiator = FALSE;
  if (!empty($views_plugin_style->options['differentiator']['differentiator_field'])) {
    $differentiator = $views_plugin_style->options['differentiator']['differentiator_field'];
    $differentiator_color_associations = $this->config
      ->get('ip_geoloc_' . $view_id . '_color_mappings') ? $this->config
      ->get('ip_geoloc_' . $view_id . '_color_mappings') : [];
    if (empty($differentiator_color_associations[$display_id])) {
      $differentiator_color_associations[$display_id] = [
        $differentiator => [],
      ];
    }
  }
  $tooltip_field = FALSE;
  if (isset($views_plugin_style->options['tooltips']['marker_tooltip'])) {
    $marker_tooltip = $views_plugin_style->options['tooltips']['marker_tooltip'];
    if (isset($view->field[$marker_tooltip])) {
      $tooltip_field = $view->field[$marker_tooltip];
    }
  }
  $tag_field = FALSE;
  if (isset($views_plugin_style->options['tags']['marker_tag'])) {
    $marker_tag = $views_plugin_style->options['tags']['marker_tag'];
    if (isset($view->field[$marker_tag])) {
      $tag_field = $view->field[$marker_tag];
    }
  }
  $locations = [];
  $error_count = $first_error = 0;
  $loc_field_name = $loc_field_alias = NULL;
  if (isset($view->field[$latitude])) {
    $loc_field_name = $view->field[$latitude]->definition['field_name'];

    // @NEW
    if ($view->field[$latitude]->field_alias == 'unknown') {
      $loc_field_alias = $loc_field_name;
    }
    else {
      $loc_field_alias = $view->field[$latitude]->field_alias;
    }

    // Example: $loc_field_name == 'field_geo'; $loc_field_alias == 'nid';.
  }

  // Group the rows according to the grouping instructions, if specified.
  $sets = $views_plugin_style
    ->renderGrouping($views_plugin_style->view->result, $views_plugin_style->options['grouping'], TRUE);
  if (!empty($views_plugin_style->options['grouping'])) {

    // @todo - Add support for multiple grouping fields?
    $group_field = $views_plugin_style->options['grouping'][0]['field'];
  }
  $rendered_fields = $views_plugin_style
    ->getRenderedFields();
  foreach ($sets as $set) {

    // Render as a grouping set.
    if (!empty($set['group'])) {

      // This is required for some Views functions.
      $view->row_index = $i = key($set['rows']);
      $row = reset($set['rows']);
      $base = $this
        ->pluginStyleGetBase1($row, $loc_field_name, $loc_field_alias);
      if ($location = $this
        ->pluginStyleExtractLatLng($row, $latitude, $longitude, $base)) {

        // Remaining row values go into the balloon.
        if (!empty($rendered_fields[$i])) {
          $location->balloon_text = $rendered_fields[$i][$group_field];
          foreach ($set['rows'] as $i => $row) {
            $rendered_field = $rendered_fields[$i];
            unset($rendered_field[$group_field]);
            $location->balloon_text .= '<br />' . implode('<br/>', $rendered_field);
          }
        }
        if (!empty($differentiator_color_associations[$display_id][$differentiator])) {
          $this
            ->pluginStyleSetMarkerColor($location, $row, $differentiator, $differentiator_color_associations[$display_id][$differentiator]);
        }
        $this
          ->pluginStyleDecorate($location, $row, $tooltip_field, $tag_field);
        $locations[] = $location;
      }
      elseif ($error_count++ == 0) {
        $first_error = $i;
      }
    }
    else {
      foreach ($view->result as $i => $row) {

        // This is required for some Views functions.
        $view->row_index = $i;
        $base = $this
          ->pluginStyleGetBase1($row, $loc_field_name, $loc_field_alias);
        if ($location = $this
          ->pluginStyleExtractLatLng($row, $latitude, $longitude, $base)) {

          // Remaining row values go into the balloon.
          if (!empty($rendered_fields[$i])) {
            $location->balloon_text = implode('<br/>', $rendered_fields[$i]);
          }
          if (!empty($differentiator_color_associations[$display_id][$differentiator])) {
            $this
              ->pluginStyleSetMarkerColor($location, $row, $differentiator, $differentiator_color_associations[$display_id][$differentiator]);
          }
          $this
            ->pluginStyleDecorate($location, $row, $tooltip_field, $tag_field);
          $locations[] = $location;
        }
        elseif ($error_count++ == 0) {
          $first_error = $i;
        }
      }
    }
  }
  $user = \Drupal::currentUser();
  if ($error_count > 0 && $user
    ->id() == 1) {
    $row_count = count($view->result);
    $title = empty($views_plugin_style->display->display_options['title']) ? $view
      ->getTitle() . ' (' . $views_plugin_style->display->display_title . ')' : $views_plugin_style->display->display_options['title'];
    $t_args = [
      '%view_title' => $title,
      '@total' => $row_count,
      '@error_count' => $error_count,
      '@first' => $first_error + 1,
      '%latitude' => $latitude,
    ];
    $msg = $error_count >= $row_count ? t('None of the @total result rows in view %view_title had their %latitude lat/lng set. Therefore the map could not be displayed. Is %latitude the correct field name?', $t_args) : t('Out of a total of @total result rows in view %view_title, @error_count rows did not have their %latitude lat/lng set and therefore could not be shown on the map. The first row that could not be located was row #@first. You can improve execution efficiency by using the Views UI to apply an "is not empty" filter criterion to %latitude.', $t_args);
    $row_contents = t('First error row:') . '<br/>';
    foreach ((array) $view->result[$first_error] as $field_name => $value) {

      // @TODO review this print
      // $row_contents .= "<strong>$field_name</strong> = " . print_r($value, TRUE) . '<br/>';
    }
    $this->messenger
      ->addMessage($msg, 'warning');
    $this->messenger
      ->addMessage($row_contents, 'warning');
    $this->messenger
      ->addMessage(t('The above messages are shown only to user 1.'), 'warning');
  }

  // Allow other modules to implement
  // hook_ip_geoloc_marker_locations_alter(&$locations, &$view)
  // @TODO check drupal_alter for drupal 8
  // drupal_alter('ip_geoloc_marker_locations', $locations, $view);.
  \Drupal::moduleHandler()
    ->alter('ip_geoloc_marker_locations', $locations, $view);
  return $locations;
}