You are here

function ip_geoloc_plugin_style_extract_locations in IP Geolocation Views & Maps 7

Same name and namespace in other branches
  1. 8 src/Plugin/views/style/ip_geoloc_plugin_style.inc \ip_geoloc_plugin_style_extract_locations()

Extract an array of locations from the supplied views_plugin_style.

Parameters

string $views_plugin_style: the style of views plugin

bool $enable_balloons:

Return value

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

3 calls to ip_geoloc_plugin_style_extract_locations()
ip_geoloc_plugin_style_leaflet::render in views/ip_geoloc_plugin_style_leaflet.inc
Transform the View result in a list of marker locations and render on map.
ip_geoloc_plugin_style_map::render in views/ip_geoloc_plugin_style_map.inc
Transform the View result in a list of markers and render these on a map.
ip_geoloc_plugin_style_openlayers::render in views/ip_geoloc_plugin_style_openlayers.inc
Transform the View result in a list of markers and render these on a map.

File

views/ip_geoloc_plugin_style.inc, line 594
ip_geoloc_plugin_style.inc

Code

function ip_geoloc_plugin_style_extract_locations($views_plugin_style, $enable_balloons = TRUE) {
  $latitudes = $views_plugin_style->options['ip_geoloc_views_plugin_latitude'];
  if (!is_array($latitudes)) {
    $latitudes = array(
      $latitudes,
    );
  }
  $longitude = trim($views_plugin_style->options['ip_geoloc_views_plugin_longitude']);
  $view =& $views_plugin_style->view;
  $view_id = $view->name;
  $display_id = $views_plugin_style->display->id;
  if ($views_plugin_style->display->handler
    ->is_defaulted('style_options')) {

    //$display_id = 'default';
  }
  $differentiator = FALSE;
  if (!empty($views_plugin_style->options['differentiator']['differentiator_field'])) {
    $differentiator = $views_plugin_style->options['differentiator']['differentiator_field'];
    $is_tax_term = ip_geoloc_is_taxonomy_term($differentiator);
    $diff_color_ass = variable_get('ip_geoloc_' . $view_id . '_color_mappings', array());
    if (empty($diff_color_ass[$display_id])) {
      $diff_color_ass[$display_id] = array(
        $differentiator => array(),
      );
    }
  }
  if (!empty($views_plugin_style->options['cluster_aggregation']['aggregation_field'])) {
    $aggregation_field = $views_plugin_style->options['cluster_aggregation']['aggregation_field'];
    if (isset($view->field[$aggregation_field]->definition['type'])) {
      $is_count = substr($view->field[$aggregation_field]->definition['type'], 0, 4) == 'list';
    }
  }
  $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];
    }
  }
  $marker_class_fields = array();
  if (!empty($views_plugin_style->options['class_names']['marker_class_names'])) {
    foreach ($views_plugin_style->options['class_names']['marker_class_names'] as $marker_class_field_name) {
      $marker_class_fields[$marker_class_field_name] = $view->field[$marker_class_field_name];
    }
  }
  $locations = array();
  $error_count = $first_error = 0;
  $loc_field_names = $loc_field_aliases = array();
  foreach ($latitudes as $latitude) {
    if (isset($view->field[$latitude])) {

      //$loc_field_names[] = $view->field[$latitude]->definition['field_name'];

      // Search API [#2603450]
      $loc_field_names[] = $view->field[$latitude]->field;
      $loc_field_aliases[] = $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
    ->render_grouping($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'];
  }
  $separator = '<br/>';
  if (is_a($views_plugin_style, 'ip_geoloc_plugin_style_map')) {

    // Google Map options come as a JSON string.
    if ($map_options = json_decode($views_plugin_style->options['map_options'])) {
      if (isset($map_options->separator)) {
        $separator = filter_xss_admin($map_options->separator);
      }
    }
  }
  elseif (isset($views_plugin_style->options['map_options']['separator'])) {
    $separator = filter_xss_admin($views_plugin_style->options['map_options']['separator']);
  }
  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']);
      $loc_field_name = reset($loc_field_names);
      $loc_field_alias = reset($loc_field_aliases);
      $j = 0;
      $row = reset($set['rows']);
      foreach ($latitudes as $latitude) {
        $base = _ip_geoloc_plugin_style_get_base1($row, $loc_field_name, $loc_field_alias);
        $location = new stdClass();
        $is_location = FALSE;
        if (_ip_geoloc_plugin_style_extract_lat_lng($location, $row, $latitude, $longitude, $base)) {
          $is_location = TRUE;
        }
        else {
          if (isset($row->_entity_properties)) {
            $longitude_alias = $view->field[$longitude]->field_alias;
            if (isset($row->_entity_properties[$loc_field_alias])) {
              $location->latitude = $row->_entity_properties[$loc_field_alias];
            }
            if (isset($row->_entity_properties[$longitude_alias])) {
              $location->longitude = $row->_entity_properties[$longitude_alias];
            }
            if (isset($location->latitude) && isset($location->longitude)) {
              $is_location = TRUE;
            }
          }
        }
        if ($is_location) {
          if (isset($row->node_title)) {
            $location->title = $row->node_title;
          }

          // Remaining row values go into the balloon.
          if ($enable_balloons && !empty($views_plugin_style->rendered_fields[$i])) {
            $location->balloon_text = $views_plugin_style->rendered_fields[$i][$group_field];
            foreach ($set['rows'] as $i => $row) {
              $rendered_fields = $views_plugin_style->rendered_fields[$i];
              unset($rendered_fields[$group_field]);
              $location->balloon_text .= $separator . implode($separator, $rendered_fields);
            }
          }
          if (!empty($diff_color_ass[$display_id][$differentiator])) {
            _ip_geoloc_plugin_style_set_marker_color($location, $row, $differentiator, $is_tax_term, $view->args, $diff_color_ass[$display_id][$differentiator]);
          }

          // Amongst other things this sets the row node/entity id on $location.
          _ip_geoloc_plugin_style_decorate($location, $row, $tooltip_field, $tag_field);
          if (isset($aggregation_field)) {
            $value = ip_geoloc_get_view_result($views_plugin_style, $aggregation_field, $i);
            $location->aggregation_value = empty($is_count) ? reset($value) : count($value);
          }
          $locations[$j ? "{$i}.{$j}" : $i] = $location;
          $j++;
        }
        $loc_field_name = next($loc_field_names);
        $loc_field_alias = next($loc_field_aliases);
      }
      if ($j === 0 && $error_count++ === 0) {
        $first_error = $i;
      }
    }
    else {
      foreach ($view->result as $i => $row) {

        // This is required for some Views functions.
        $view->row_index = $i;
        $loc_field_name = reset($loc_field_names);
        $loc_field_alias = reset($loc_field_aliases);
        $j = 0;
        foreach ($latitudes as $latitude) {
          $base = _ip_geoloc_plugin_style_get_base1($row, $loc_field_name, $loc_field_alias);
          $location = new stdClass();
          $is_location = FALSE;
          if (_ip_geoloc_plugin_style_extract_lat_lng($location, $row, $latitude, $longitude, $base)) {
            $is_location = TRUE;
          }
          else {
            if (isset($row->_entity_properties)) {
              $longitude_alias = $view->field[$longitude]->field_alias;
              if (isset($row->_entity_properties[$loc_field_alias])) {
                $location->latitude = $row->_entity_properties[$loc_field_alias];
              }
              if (isset($row->_entity_properties[$longitude_alias])) {
                $location->longitude = $row->_entity_properties[$longitude_alias];
              }
              if (isset($location->latitude) && isset($location->longitude)) {
                $is_location = TRUE;
              }
            }
          }
          if ($is_location) {
            if (isset($row->node_title)) {
              $location->title = $row->node_title;
            }

            // Remaining row values go into the balloon.
            if ($enable_balloons && !empty($views_plugin_style->rendered_fields[$i])) {
              $location->balloon_text = implode($separator, $views_plugin_style->rendered_fields[$i]);
            }
            if (!empty($diff_color_ass[$display_id][$differentiator])) {
              _ip_geoloc_plugin_style_set_marker_color($location, $row, $differentiator, $is_tax_term, $view->args, $diff_color_ass[$display_id][$differentiator]);
            }
            _ip_geoloc_plugin_style_decorate($location, $row, $tooltip_field, $tag_field);
            foreach ($marker_class_fields as $marker_class_name_field => $marker_class_field) {
              $single_values = ip_geoloc_get_view_result($views_plugin_style, $marker_class_field->definition, $i);

              // HTML classnames can contain any character and are concatenated
              // by spaces However CSS selectors allow limited chars.
              // drupal_html_class() converts spaces and underscores to '-'.
              foreach ($single_values as $single_value) {
                $location->marker_classes[] = drupal_html_class($marker_class_name_field) . '__' . drupal_html_class($single_value);
              }
            }
            if (isset($aggregation_field)) {
              $value = ip_geoloc_get_view_result($views_plugin_style, $aggregation_field, $i);
              $location->aggregation_value = empty($is_count) ? reset($value) : count($value);
            }
            $locations[$j ? "{$i}.{$j}" : $i] = $location;
            $j++;
          }
          $loc_field_name = next($loc_field_names);
          $loc_field_alias = next($loc_field_aliases);
        }
        if ($j === 0 && $error_count++ === 0) {
          $first_error = $i;
          if (isset($row->nid)) {
            $id = 'nid #' . $row->nid;
          }
          if (isset($row->node_title)) {
            $id .= ': ' . $row->node_title;
          }
        }
      }
    }
  }
  global $user;
  if ($error_count > 0 && (($is_debug = ip_geoloc_debug_flag()) || $user->uid == 1)) {
    $row_count = count($view->result);
    $title = empty($views_plugin_style->display->display_options['title']) ? $view
      ->get_human_name() . ' (' . $views_plugin_style->display->display_title . ')' : $views_plugin_style->display->display_options['title'];
    $t_args = array(
      '%view_title' => $title,
      '@total' => $row_count,
      '@error_count' => $error_count,
      '@first' => $first_error + 1,
      '%id' => isset($id) ? " ({$id})" : '',
      '%latitudes' => implode(' ' . t('or') . ' ', $latitudes),
    );
    $msg = $error_count >= $row_count ? t('None of the @total result rows in view %view_title had their %latitudes set. Therefore those rows could not be displayed as locations on the map. Are you using the correct field names?', $t_args) : t('Out of a total of @total result rows in view %view_title, @error_count rows did not have their %latitudes set and therefore could not be shown on the map. The first row that could not be located was row #@first%id. You can improve execution efficiency by using the Views UI to add an "is not empty" filter for %latitudes.', $t_args);
    drupal_set_message($msg);
    if ($is_debug) {
      $row_contents = t('First error row:') . '<br/>';
      foreach ((array) $view->result[$first_error] as $field_name => $value) {
        if ($field_name != '_field_data') {
          $output = filter_xss_admin(print_r($value, TRUE));
          $output = drupal_substr($output, 0, 255) . (strlen($output) > 255 ? '...' : '');
          $row_contents .= "<strong>{$field_name}</strong> = {$output}<br/>";
        }
      }
      drupal_set_message($row_contents);
    }
  }

  // Allow other modules to implement
  // hook_ip_geoloc_marker_locations_alter(&$locations, &$view)
  drupal_alter('ip_geoloc_marker_locations', $locations, $view);
  return $locations;
}