<?php
namespace App\Controller;
use App\Entity\City;
use App\Entity\Weather;
use App\Repository\WeatherRepository;
use App\Service\OpenWeather;
use App\Type\WeatherType;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
/**
* Contactsubject controller.
*
* @Route("/")
*/
class MapController extends AbstractController
{
private $openWeather;
private $em;
public function __construct(OpenWeather $openWeather, EntityManagerInterface $em)
{
$this->openWeather = $openWeather;
$this->em = $em;
}
/**
* @Route("/", name="index", methods={"GET"})
*/
public function index()
{
$weather = new Weather();
$form = $this->createForm(WeatherType::class, $weather);
return $this->render('map/index.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @Route("get-weather", name="getWeather", methods={"POST"})
* @param Request $request
* @return JsonResponse
* @throws ClientExceptionInterface
* @throws DecodingExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
public function getWeather(Request $request)
{
if ($request->isXMLHttpRequest()) {
$lat = $request->request->get('weather')['lat'];
$lng = $request->request->get('weather')['lng'];
$form = $this->createForm(WeatherType::class);
$form->handleRequest($request);
if ($form->isValid()) {
$weather = $this->openWeather->fetchCurrentWeatherByCoordinates($lat, $lng);
if ($weather) {
$this->saveResults($weather);
return new JsonResponse($weather);
} else {
return new JsonResponse(['status' => 'error', 'message' => 'Open Weather Map error']);
}
} else {
return new JsonResponse($form->getErrors());
}
}
return new JsonResponse(['status' => 'error', 'message' => 'Error']);
}
}
/**
* @Route("results", name="results", methods={"GET"})
* @param PaginatorInterface $paginator
* @param Request $request
* @param WeatherRepository $repository
* @return Response
*/
public function results(PaginatorInterface $paginator, Request $request, WeatherRepository $repository)
{
$results = $repository->paginationList();
$pagination = $paginator->paginate(
$results, /* query NOT result */
$request->query->getInt('page', 1), /*page number*/
Weather::PAGE_LIMIT /*limit per page*/
);
return $this->render('map/results.html.twig', [
'pagination' => $pagination,
'temperatureStats' => $repository->findTemperatureStats(),
'commonCity' => $repository->findCommonCity()
]);
}
private function saveResults($result)
{
$city = $this->em->getRepository(City::class)->findOneBy(['openWeatherId' => $result['id']]);
$city = new City();
$city->setName($result['name']);
$city->setOpenWeatherId($result['id']);
$this->em->persist($city);
}
$weather = new Weather();
$weather->setLat($result['coord']['lat']);
$weather->setLng($result['coord']['lon']);
$weather->setDescription($result['weather'][0]['description']);
$weather->setCloudiness($result['clouds']['all']);
$weather->setTemperature($result['main']['temp']);
$weather->setWindSpeed($result['wind']['speed']);
$weather->setCity($city);
$this->em->persist($weather);
}
}