You are here

protected function ParserService::parseForecast in Weather 2.0.x

Same name and namespace in other branches
  1. 8 src/Service/ParserService.php \Drupal\weather\Service\ParserService::parseForecast()

Parses an XML forecast supplied by yr.no.

Parameters

string $xml: XML to be parsed.

string $geoid: The GeoID for which the forecasts should be parsed.

Return value

bool TRUE on success, FALSE on failure.

Throws

\Drupal\Core\Entity\EntityStorageException

1 call to ParserService::parseForecast()
ParserService::downloadForecast in src/Service/ParserService.php
Downloads a new forecast from yr.no.

File

src/Service/ParserService.php, line 168

Class

ParserService
Parsing of XML weather forecasts from yr.no.

Namespace

Drupal\weather\Service

Code

protected function parseForecast($xml, $geoid = '') {

  // In case the parsing fails, do not output all error messages.
  $use_errors = libxml_use_internal_errors(TRUE);
  $fc = simplexml_load_string($xml);

  // Restore previous setting of error handling.
  libxml_use_internal_errors($use_errors);
  if ($fc === FALSE) {
    return FALSE;
  }

  // Update weather_places table with downloaded information, if necessary.
  $this
    ->updatePlaces($fc);

  // Extract meta information.
  // @todo Extract GeoID of returned XML data.
  // This might differ from the data we have in the database. An example
  // was Heraklion (ID 261745), which got the forecast for
  // Nomós Irakleíou (ID 261741).
  if ($geoid == '') {
    $geoid = $fc->location->location['geobase'] . "_" . $fc->location->location['geobaseid'];
  }
  $meta['geoid'] = $geoid;
  $meta['utc_offset'] = (int) $fc->location->timezone['utcoffsetMinutes'];

  // Calculate the UTC time.
  $utctime = strtotime((string) $fc->meta->lastupdate . ' UTC') - 60 * $meta['utc_offset'];
  $meta['last_update'] = gmdate('Y-m-d H:i:s', $utctime);

  // Calculate the UTC time.
  $utctime = strtotime((string) $fc->meta->nextupdate . ' UTC') - 60 * $meta['utc_offset'];
  $meta['next_update'] = gmdate('Y-m-d H:i:s', $utctime);
  $meta['next_download_attempt'] = $meta['next_update'];

  // Write/Update information for this location.
  $forecastInfo = $this->weatherForecastInfoStorage
    ->load($meta['geoid']);
  if ($forecastInfo instanceof WeatherForecastInformationInterface) {
    foreach ($meta as $field => $value) {
      $forecastInfo->{$field} = $value;
    }
    $forecastInfo
      ->save();
  }
  else {
    $this->weatherForecastInfoStorage
      ->create($meta)
      ->save();
  }

  // Remove all forecasts for this location.
  $outdated = $this->weatherForecastStorage
    ->loadByProperties([
    'geoid' => $meta['geoid'],
  ]);
  $this->weatherForecastStorage
    ->delete($outdated);

  // Cycle through all forecasts and write them to the table.
  foreach ($fc->forecast->tabular->time as $time) {
    $forecast = [];
    $forecast['geoid'] = $meta['geoid'];
    $forecast['time_from'] = str_replace('T', ' ', (string) $time['from']);
    $forecast['time_to'] = str_replace('T', ' ', (string) $time['to']);
    $forecast['period'] = (string) $time['period'];
    $forecast['symbol'] = (string) $time->symbol['var'];

    // Remove moon phases, which are not supported.
    // This is in the format "mf/03n.56", where 56 would be the
    // percentage of the moon phase.
    if (strlen($forecast['symbol']) > 3) {
      $forecast['symbol'] = substr($forecast['symbol'], 3, 3);
    }
    $forecast['precipitation'] = (double) $time->precipitation['value'];
    $forecast['wind_direction'] = (int) $time->windDirection['deg'];
    $forecast['wind_speed'] = (double) $time->windSpeed['mps'];
    $forecast['temperature'] = (int) $time->temperature['value'];
    $forecast['pressure'] = (int) $time->pressure['value'];

    // Create Forecast if not exists.
    $fcExists = $this->weatherForecastStorage
      ->loadByProperties([
      'geoid' => $meta['geoid'],
      'time_from' => $forecast['time_from'],
    ]);
    if (!$fcExists) {
      $this->weatherForecastStorage
        ->create($forecast)
        ->save();
    }
  }
  return TRUE;
}