diff --git a/apps/weather_status/lib/Controller/WeatherStatusController.php b/apps/weather_status/lib/Controller/WeatherStatusController.php index d9db1aea5bfcf..da82bb4f03fdc 100644 --- a/apps/weather_status/lib/Controller/WeatherStatusController.php +++ b/apps/weather_status/lib/Controller/WeatherStatusController.php @@ -34,6 +34,10 @@ /** * @psalm-import-type WeatherStatusForecast from ResponseDefinitions + * @psalm-import-type WeatherStatusSuccess from ResponseDefinitions + * @psalm-import-type WeatherStatusLocation from ResponseDefinitions + * @psalm-import-type WeatherStatusLocationWithSuccess from ResponseDefinitions + * @psalm-import-type WeatherStatusLocationWithMode from ResponseDefinitions */ class WeatherStatusController extends OCSController { public function __construct( @@ -50,7 +54,7 @@ public function __construct( * * Try to use the address set in user personal settings as weather location * - * @return DataResponse + * @return DataResponse * * 200: Address updated */ @@ -66,7 +70,7 @@ public function usePersonalAddress(): DataResponse { * - use the user defined address * * @param int $mode New mode - * @return DataResponse + * @return DataResponse * * 200: Weather status mode updated */ @@ -83,7 +87,7 @@ public function setMode(int $mode): DataResponse { * @param string|null $address Any approximative or exact address * @param float|null $lat Latitude in decimal degree format * @param float|null $lon Longitude in decimal degree format - * @return DataResponse + * @return DataResponse * * 200: Location updated */ @@ -97,7 +101,7 @@ public function setLocation(?string $address, ?float $lat, ?float $lon): DataRes * * Get stored user location * - * @return DataResponse + * @return DataResponse * * 200: Location returned */ @@ -111,7 +115,7 @@ public function getLocation(): DataResponse { * * Get forecast for current location * - * @return DataResponse|DataResponse + * @return DataResponse|DataResponse * * 200: Forecast returned * 404: Forecast not found @@ -144,7 +148,7 @@ public function getFavorites(): DataResponse { * Set favorites list * * @param string[] $favorites Favorite addresses - * @return DataResponse + * @return DataResponse * * 200: Favorites updated */ diff --git a/apps/weather_status/lib/ResponseDefinitions.php b/apps/weather_status/lib/ResponseDefinitions.php index 1224a394e336f..d69afbbb3c262 100644 --- a/apps/weather_status/lib/ResponseDefinitions.php +++ b/apps/weather_status/lib/ResponseDefinitions.php @@ -67,6 +67,23 @@ * }, * }, * } + * + * @psalm-type WeatherStatusSuccess = array{ + * success: bool, + * } + * + * @psalm-type WeatherStatusMode = array{ + * mode: int, + * } + * @psalm-type WeatherStatusLocation = array{ + * lat?: string, + * lon?: string, + * address?: ?string, + * } + * + * @psalm-type WeatherStatusLocationWithSuccess = WeatherStatusLocation&WeatherStatusSuccess + * + * @psalm-type WeatherStatusLocationWithMode = WeatherStatusLocation&WeatherStatusMode */ class ResponseDefinitions { } diff --git a/apps/weather_status/lib/Service/WeatherStatusService.php b/apps/weather_status/lib/Service/WeatherStatusService.php index 7358f386151a9..ed416d09a87f2 100644 --- a/apps/weather_status/lib/Service/WeatherStatusService.php +++ b/apps/weather_status/lib/Service/WeatherStatusService.php @@ -27,6 +27,7 @@ namespace OCA\WeatherStatus\Service; use OCA\WeatherStatus\AppInfo\Application; +use OCA\WeatherStatus\ResponseDefinitions; use OCP\Accounts\IAccountManager; use OCP\Accounts\PropertyDoesNotExistException; use OCP\App\IAppManager; @@ -43,6 +44,11 @@ * Class WeatherStatusService * * @package OCA\WeatherStatus\Service + * + * @psalm-import-type WeatherStatusForecast from ResponseDefinitions + * @psalm-import-type WeatherStatusSuccess from ResponseDefinitions + * @psalm-import-type WeatherStatusLocationWithSuccess from ResponseDefinitions + * @psalm-import-type WeatherStatusLocationWithMode from ResponseDefinitions */ class WeatherStatusService { public const MODE_BROWSER_LOCATION = 1; @@ -73,7 +79,7 @@ public function __construct( * - ask the browser * - use the user defined address * @param int $mode New mode - * @return array success state + * @return WeatherStatusSuccess success state */ public function setMode(int $mode): array { $this->config->setUserValue($this->userId, Application::APP_ID, 'mode', strval($mode)); @@ -92,7 +98,7 @@ public function getFavorites(): array { /** * Set favorites list * @param string[] $favorites - * @return array success state + * @return WeatherStatusSuccess success state */ public function setFavorites(array $favorites): array { $this->config->setUserValue($this->userId, Application::APP_ID, 'favorites', json_encode($favorites)); @@ -102,7 +108,7 @@ public function setFavorites(array $favorites): array { /** * Try to use the address set in user personal settings as weather location * - * @return array with success state and address information + * @return WeatherStatusLocationWithSuccess with success state and address information */ public function usePersonalAddress(): array { $account = $this->accountManager->getAccount($this->userManager->get($this->userId)); @@ -124,7 +130,7 @@ public function usePersonalAddress(): array { * @param string|null $address Any approximative or exact address * @param float|null $lat Latitude in decimal degree format * @param float|null $lon Longitude in decimal degree format - * @return array with success state and address information + * @return WeatherStatusLocationWithSuccess with success state and address information */ public function setLocation(?string $address, ?float $lat, ?float $lon): array { if (!is_null($lat) && !is_null($lon)) { @@ -228,7 +234,7 @@ private function formatOsmAddress(array $json): ?string { * Set address and resolve it to get coordinates * * @param string $address Any approximative or exact address - * @return array with success state and address information (coordinates and formatted address) + * @return WeatherStatusLocationWithSuccess with success state and address information (coordinates and formatted address) */ public function setAddress(string $address): array { $addressInfo = $this->searchForAddress($address); @@ -256,7 +262,7 @@ public function setAddress(string $address): array { * Ask nominatim information about an unformatted address * * @param string Unformatted address - * @return array Full Nominatim result for the given address + * @return array{display_name?: string, lat?: string, lon?: string, error?: string} Full Nominatim result for the given address */ private function searchForAddress(string $address): array { $params = [ @@ -278,7 +284,7 @@ private function searchForAddress(string $address): array { /** * Get stored user location * - * @return array which contains coordinates, formatted address and current weather status mode + * @return WeatherStatusLocationWithMode which contains coordinates, formatted address and current weather status mode */ public function getLocation(): array { $lat = $this->config->getUserValue($this->userId, Application::APP_ID, 'lat', ''); @@ -296,7 +302,7 @@ public function getLocation(): array { /** * Get forecast for current location * - * @return array which contains success state and filtered forecast data + * @return WeatherStatusForecast[]|array{error: string}|WeatherStatusSuccess which contains success state and filtered forecast data */ public function getForecast(): array { $lat = $this->config->getUserValue($this->userId, Application::APP_ID, 'lat', ''); @@ -319,7 +325,7 @@ public function getForecast(): array { * @param float $lon Longitude of requested forecast, in decimal degree format * @param float $altitude Altitude of requested forecast, in meter * @param int $nbValues Number of forecast values (hours) - * @return array Filtered forecast data + * @return WeatherStatusForecast[]|array{error: string} Filtered forecast data */ private function forecastRequest(float $lat, float $lon, float $altitude, int $nbValues = 10): array { $params = [ diff --git a/apps/weather_status/openapi.json b/apps/weather_status/openapi.json index b0356acab52a3..0605016ea9758 100644 --- a/apps/weather_status/openapi.json +++ b/apps/weather_status/openapi.json @@ -185,6 +185,53 @@ } } }, + "Location": { + "type": "object", + "properties": { + "lat": { + "type": "string" + }, + "lon": { + "type": "string" + }, + "address": { + "type": "string", + "nullable": true + } + } + }, + "LocationWithMode": { + "allOf": [ + { + "$ref": "#/components/schemas/Location" + }, + { + "$ref": "#/components/schemas/Mode" + } + ] + }, + "LocationWithSuccess": { + "allOf": [ + { + "$ref": "#/components/schemas/Location" + }, + { + "$ref": "#/components/schemas/Success" + } + ] + }, + "Mode": { + "type": "object", + "required": [ + "mode" + ], + "properties": { + "mode": { + "type": "integer", + "format": "int64" + } + } + }, "OCSMeta": { "type": "object", "required": [ @@ -208,6 +255,17 @@ "type": "string" } } + }, + "Success": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + } + } } } }, @@ -271,15 +329,7 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "object", - "required": [ - "success" - ], - "properties": { - "success": { - "type": "boolean" - } - } + "$ref": "#/components/schemas/Success" } } } @@ -340,32 +390,7 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "object", - "required": [ - "success", - "lat", - "lon", - "address" - ], - "properties": { - "success": { - "type": "boolean" - }, - "lat": { - "type": "number", - "format": "float", - "nullable": true - }, - "lon": { - "type": "number", - "format": "float", - "nullable": true - }, - "address": { - "type": "string", - "nullable": true - } - } + "$ref": "#/components/schemas/LocationWithSuccess" } } } @@ -426,30 +451,7 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "object", - "required": [ - "lat", - "lon", - "address", - "mode" - ], - "properties": { - "lat": { - "type": "number", - "format": "float" - }, - "lon": { - "type": "number", - "format": "float" - }, - "address": { - "type": "string" - }, - "mode": { - "type": "integer", - "format": "int64" - } - } + "$ref": "#/components/schemas/LocationWithMode" } } } @@ -537,32 +539,7 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "object", - "required": [ - "success", - "lat", - "lon", - "address" - ], - "properties": { - "success": { - "type": "boolean" - }, - "lat": { - "type": "number", - "format": "float", - "nullable": true - }, - "lon": { - "type": "number", - "format": "float", - "nullable": true - }, - "address": { - "type": "string", - "nullable": true - } - } + "$ref": "#/components/schemas/LocationWithSuccess" } } } @@ -623,10 +600,25 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Forecast" - } + "oneOf": [ + { + "type": "array", + "items": { + "$ref": "#/components/schemas/Forecast" + } + }, + { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + ] } } } @@ -656,15 +648,7 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "object", - "required": [ - "success" - ], - "properties": { - "success": { - "type": "boolean" - } - } + "$ref": "#/components/schemas/Success" } } } @@ -799,15 +783,7 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "object", - "required": [ - "success" - ], - "properties": { - "success": { - "type": "boolean" - } - } + "$ref": "#/components/schemas/Success" } } }