Search code examples
drupaldrupal-9

Validate the API key and the city name by the API request


I created a custom module where in the block I display the weather using data from https://openweathermap.org/

Code of this block:
https://phpsandbox.io/n/sweet-forest-1lew-1wmof

Also I have WeatherForm.php file with the form which adds in a configuration city and an API key for which it is necessary to display weather.

I needed to Add form validation:

  1. fields should not be empty
  2. City name should not contain numbers

I did it this way:

  public function validateForm(array &$form, FormStateInterface $form_state) {
    $pattern = '/[0-9]/';

    if (empty($form_state->getValue('weather_city'))) {
      $form_state->setErrorByName('weather_city', $this->t('Fields should not be empty'));
    }
    if (preg_match($pattern, $form_state->getValue('weather_city'))) {
      $form_state->setErrorByName('weather_city', $this->t('City name should not contain numbers'));
    }
  }

But I got these remark after the code review:

Also, will be good to validate the API key and the city name by the API request.

I found an example of how to implement this:

public function validateWeatherData(string $city_name, $api_key):bool {
  try {
    $url = "https://api.openweather.org/data/2.5/weather?q=$city_name&appid=$api_key";
    $response = $this->client->request('GET', $url);
    if ($response->getStatusCode() != 200) {
      throw new \Exception('Failed to retrieve data.');
    }
    $reg_ex = "#^[A-Za-z-]=$#";
    return preg_match($reg_ex, $city_name);
  }
  catch (GuzzleException $e) {
    return FALSE;
  }
}

But I don't know how to integrate the example code into my function validateForm. What my code should look like so that it also implements validate the API key and the city name by the API request?

All code of my Form:
https://phpsandbox.io/n/spring-mountain-gdnn-emozx


Solution

  • Why not use both, brainstorm with me something along the lines of..

    function validateWeatherData($city, $apikey) {
      try {
        $url = "https://api.openweather.org/data/2.5/weather?q=$city_name&appid=$api_key"; // Build the URL
        $response = file_get_contents($url); // You can use cURL here as well incase CORS blocks file_get_contents
            return $response; // Return the data from the call made above
      }
      catch (Exception $e) {
        return $e;
      }
    }
    
     function validateForm(array &$form, FormStateInterface $form_state) {
        $pattern = '/[0-9]/';
        if (empty($form_state->getValue('weather_city'))) {
          $form_state->setErrorByName('weather_city', $this->t('Fields should not be empty'));
              return false; // Failed to validate city, return false go back start again
        }
        if (preg_match($pattern, $form_state->getValue('weather_city'))) {
          $form_state->setErrorByName('weather_city', $this->t('City name should not contain numbers')); 
              return false; // Failed to validate city, return false go back start again
        }
            $apikey = "ABCDEFG"; // API key (can be conditional based on city via CASE/IF when needed)
            $weatherdata = validateWeatherData($form_state->getValue('weather_city'), $apikey); // Validate weather data
            return $weatherdata; // Return validateWeatherData's response or do something else with it
     }