Skip to content

Commit

Permalink
Moved the logic code to service file
Browse files Browse the repository at this point in the history
  • Loading branch information
axelerant-hardik committed Apr 29, 2024
1 parent 9186dc3 commit 3a52047
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 74 deletions.
87 changes: 13 additions & 74 deletions Drupal/modules/custom/weather/src/Plugin/Block/WeatherDisplay.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,16 @@

namespace Drupal\weather\Plugin\Block;

use Drupal\Component\Serialization\Json;
use Drupal\Core\Block\Attribute\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\weather\Form\WeatherSettingsForm;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\RequestException;
use Drupal\weather\Services\Weather;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* Provides a 'Hello' Block.
* Provides a "Today's Weather" Block.
*/
#[Block(
id: "weather_display",
Expand All @@ -25,18 +21,11 @@
class WeatherDisplay extends BlockBase implements ContainerFactoryPluginInterface {

/**
* The config factory service.
* The weather service.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
* @var \Drupal\weather\Services\Weather
*/
protected $config;

/**
* The Guzzle HTTP client service.
*
* @var \GuzzleHttp\ClientInterface
*/
protected $httpClient;
protected $weather;

/**
* {@inheritdoc}
Expand All @@ -47,22 +36,18 @@ class WeatherDisplay extends BlockBase implements ContainerFactoryPluginInterfac
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory service.
* @param \GuzzleHttp\ClientInterface $http_client
* The Guzzle HTTP client service.
* @param \Drupal\weather\Services\Weather $weather
* The weather service.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
ConfigFactoryInterface $config_factory,
ClientInterface $http_client,
Weather $weather,
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);

$this->config = $config_factory;
$this->httpClient = $http_client;
$this->weather = $weather;
}

/**
Expand All @@ -73,8 +58,7 @@ public static function create(ContainerInterface $container, array $configuratio
$configuration,
$plugin_id,
$plugin_definition,
$container->get('config.factory'),
$container->get('http_client'),
$container->get('weather')
);
}

Expand Down Expand Up @@ -113,15 +97,7 @@ public function blockSubmit($form, FormStateInterface $form_state) {
* {@inheritdoc}
*/
public function build() {
// Get weather settings.
$weather_settings = $this->config->get(WeatherSettingsForm::SETTINGS);

// Bail out if the config is empty.
if (empty($weather_settings)) {
return [];
}

// Get location details from session.
// Get city name from block configuration.
$city = $this->configuration['city'];
if (!$city) {
$city_not_found_message = $this->t('No city entered. Please enter a city to see the weather details');
Expand All @@ -130,45 +106,8 @@ public function build() {
];
}

// Endpoint that should be hit.
$request_url = $weather_settings->get('base_url') . '/current.json';
// Make a HTTP GET request to the endpoint.
try {
$request = $this->httpClient->request('GET', $request_url, [
'query' => [
'key' => $weather_settings->get('api_key'),
'q' => $city,
'units' => 'metric',
],
]);

// Parse the response.
$response = Json::decode($request->getBody());
$weather_data = [];
$weather_data['location'] = $response['location']['name'] . ', ' . $response['location']['region'] . ', ' . $response['location']['country'];
$weather_data['temperature'] = $response['current']['temp_c'];
$weather_data['feels_like'] = $response['current']['feelslike_c'];
$weather_data['weather_condition_icon'] = $response['current']['condition']['icon'];
$weather_data['weather_condition_text'] = $response['current']['condition']['text'];
$weather_data['wind'] = $response['current']['wind_kph'];
$weather_data['precipitation'] = $response['current']['precip_mm'];

return [
'#theme' => 'weather_display',
'#weather_data' => $weather_data,
'#cache' => [
'max-age' => 3600,
],
];
}
catch (RequestException $e) {
$error = $e->getResponse()->getBody()->getContents();
$error_response = Json::decode($error);

return [
'#markup' => '<div class="weather--error">' . $error_response['error']['message'] . '</div>',
];
}
// Show today's weather.
return $this->weather->getTodaysWeather($city);
}

}
104 changes: 104 additions & 0 deletions Drupal/modules/custom/weather/src/Services/Weather.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php

namespace Drupal\weather\Services;

use Drupal\Component\Serialization\Json;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\weather\Form\WeatherSettingsForm;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\RequestException;

/**
* Service class to handle weather related operations.
*/
class Weather {

/**
* The config factory service.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $config;

/**
* The Guzzle HTTP client service.
*
* @var \GuzzleHttp\ClientInterface
*/
protected $httpClient;

/**
* Constructs a new Weather object.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory service.
* @param \GuzzleHttp\ClientInterface $http_client
* The http client service.
*/
public function __construct(ConfigFactoryInterface $config_factory, ClientInterface $http_client,) {
$this->config = $config_factory;
$this->httpClient = $http_client;
}

/**
* Get Today's weather information.
*
* Make an http request to the weather endpoint, parse
* the response and display the details.
*
* @param string $city
* The city whose weather is to be displayed.
*
* @return mixed
* Response based on the API output.
*/
public function getTodaysWeather($city): mixed {
// Get weather settings.
$weather_settings = $this->config->get(WeatherSettingsForm::SETTINGS);
if (empty($weather_settings)) {
return [];
}

// Endpoint that should be hit.
$request_url = $weather_settings->get('base_url') . '/current.json';

// Make a HTTP GET request to the endpoint.
try {
$request = $this->httpClient->request('GET', $request_url, [
'query' => [
'key' => $weather_settings->get('api_key'),
'q' => $city,
'units' => 'metric',
],
]);

// Parse the response.
$response = Json::decode($request->getBody());
$weather_data = [];
$weather_data['location'] = $response['location']['name'] . ', ' . $response['location']['region'] . ', ' . $response['location']['country'];
$weather_data['temperature'] = $response['current']['temp_c'];
$weather_data['feels_like'] = $response['current']['feelslike_c'];
$weather_data['weather_condition_icon'] = $response['current']['condition']['icon'];
$weather_data['weather_condition_text'] = $response['current']['condition']['text'];
$weather_data['wind'] = $response['current']['wind_kph'];
$weather_data['precipitation'] = $response['current']['precip_mm'];

return [
'#theme' => 'weather_display',
'#weather_data' => $weather_data,
'#cache' => [
'max-age' => 3600,
],
];
}
catch (RequestException $e) {
$error = $e->getResponse()->getBody()->getContents();
$error_response = Json::decode($error);

return [
'#markup' => '<div class="weather--error">' . $error_response['error']['message'] . '</div>',
];
}
}

}
4 changes: 4 additions & 0 deletions Drupal/modules/custom/weather/weather.services.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
services:
weather:
class: Drupal\weather\Services\Weather
arguments: ['@config.factory', '@http_client']

0 comments on commit 3a52047

Please sign in to comment.