You are here

function geolocation_address_link_entity_presave in Geolocation Address Link 8

Implements hook_entity_presave().

File

./geolocation_address_link.module, line 30
Contains geolocation_address_link.module.

Code

function geolocation_address_link_entity_presave(EntityInterface $entity) {
  $config = \Drupal::service('config.factory')
    ->get('geolocation_address_link.settings');
  $fields = (array) $config
    ->get('fields');
  $geocoder = \Drupal::service('geolocation_address_link.address2geo');
  foreach ($fields as $field) {

    // See if any fields on the entity need to be updated.
    list($entity_type, $bundle, $address_field, $geolocation_field) = explode(':', $field);
    if ($entity_type == $entity
      ->getEntityTypeId()) {
      if ($bundle == $entity
        ->bundle()) {

        // Get address field value(s), if any.
        if ($addresses = $entity
          ->get($address_field)
          ->getValue()) {
          $geolocations = $entity
            ->get($geolocation_field)
            ->getValue();

          // Don't try to geocode if the address field value hasn't changed and
          // the geolocation field has a value.
          if (!empty($geolocations) && isset($entity->original)) {
            $original = $entity->original;
            $original_addresses = $original
              ->get($address_field)
              ->getValue();
            $matches = TRUE;
            if (count($original_addresses) != count($addresses)) {
              $matches = FALSE;
            }
            else {
              foreach ($original_addresses as $delta => $value) {

                // We remove empty entries from the address arrays
                // and if their diff is not empty the address has
                // been updated.
                if (!empty(array_diff(array_filter($value), array_filter($addresses[$delta])))) {
                  $matches = FALSE;
                  break;
                }
              }
            }
            if ($matches) {
              return;
            }
          }
          $values = [];

          // Get the geocoded value for each address.
          foreach ($addresses as $delta => $address) {
            if ($geocoordinates = $geocoder
              ->geocode($address)) {

              // The original geolocation field might contain custom map settings in 'data'.
              // If so, we don't want to wipe them out.
              if (!empty($geolocations[$delta]['data'])) {
                $geocoordinates['data'] = array_merge($geolocations[$delta]['data'], $geocoordinates['data']);
              }
              $values[$delta] = $geocoordinates;
            }
          }

          // Update the geolocation field with the geocoder results.
          $entity
            ->set($geolocation_field, $values);
        }
      }
    }
  }
}