ulmus-api-weather/src/ApiHandler.php
2026-07-01 14:37:46 -04:00

82 lines
2.7 KiB
PHP

<?php
namespace Ulmus\Api\Weather;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\{ RequestInterface, ResponseInterface };
use Ulmus\Api\ApiHandlerInterface;
use Ulmus\Api\Attribute\Obj\Api\{ Read, Collection };
use Ulmus\Api\Common\Uri;
use Ulmus\Api\Response\JsonResponse;
use Ulmus\Api\Stream\JsonStream;
use Ulmus\Api\Stream\Stream;
use Ulmus\Repository\RepositoryInterface;
class ApiHandler implements ApiHandlerInterface
{
public function __construct(
protected ? string $unitScale,
) {}
public function executingRequest(RepositoryInterface $repository, \Ulmus\Api\Attribute\Obj\Api\ApiAction $attribute) : void
{
$repository->bindUrl('apiBase', $repository->entityClass::API_BASE_URL);
}
public function handleRequest(RequestInterface $request, \Ulmus\Api\Attribute\Obj\Api\ApiAction $attribute) : RequestInterface
{
if ($this->unitScale) {
$uriParams['unitScale'] = $this->unitScale;
}
if ($attribute->fields) {
$uriParams['fields'] = implode(',', $attribute->fields);
}
if ($uriParams ?? false) {
$request = $request->withUri(
( new Uri($request->getUri()) )->withQuery($uriParams)
);
}
return $request;
}
public function handleResponse(ResponseInterface $response, \Ulmus\Api\Attribute\Obj\Api\ApiAction $attribute) : ResponseInterface
{
try {
$json = $response->getParsedBody();
if (! empty($json['forecast']) ) {
foreach($json['forecast'] as &$forecast) {
$forecast['date'] = $this->adjustTimezone($forecast['date']);
}
if ($attribute instanceof Collection) {
$response = $response->withParsedBody($json['forecast']);
}
}
if (! empty($json['nowcast'])) {
$json['nowcast']['timestamp'] = new \DateTime($json['nowcast']['timestamp'], new \DateTimeZone('UTC'))->setTimezone(new \DateTimeZone('America/Toronto'))->format('Y-m-d H:i:s');
if ($attribute instanceof Read) {
$response = $response->withParsedBody($json['nowcast']);
}
}
}
catch(\Throwable $e) {
$msg = $json['errorMessage'] ?? $e->getMessage();
$code = $json['errorCode'] ?? $e->getCode();
throw new \Exception(sprintf("WeatherSource error: '%s'", $msg), $code);
}
return JsonResponse::fromResponse($response);
}
protected function adjustTimezone(string $datetime) : string
{
return new \DateTime("@" . strtotime($datetime))->format('Y-m-d H:i:s');
}
}