From 59a34746d046d772624353a0a77c88bb5ede6152 Mon Sep 17 00:00:00 2001 From: Frederico27 Date: Wed, 22 May 2024 01:38:45 +0900 Subject: [PATCH] render deploy --- app/City.php | 24 ++ app/Helper/HelperUtil.php | 215 ++++++++++++++++++ app/Http/Controllers/Controller.php | 7 +- .../Controllers/CurrentWeatherController.php | 132 +++++++++++ .../Controllers/DailyWeatherController.php | 86 +++++++ .../Controllers/HourlyWeatherController.php | 86 +++++++ app/Http/Middleware/Authenticate.php | 10 +- app/Http/Middleware/EncryptCookies.php | 2 +- .../PreventRequestsDuringMaintenance.php | 17 ++ .../Middleware/RedirectIfAuthenticated.php | 18 +- app/Http/Middleware/TrimStrings.php | 3 +- app/Http/Middleware/TrustHosts.php | 20 ++ app/Http/Middleware/TrustProxies.php | 4 +- app/Http/Middleware/ValidateSignature.php | 22 ++ app/Http/Middleware/VerifyCsrfToken.php | 9 +- app/Http/Resources/CityResource.php | 32 +++ app/Http/Resources/CityResourceCollection.php | 21 ++ app/Http/Resources/CityResourceDaily.php | 32 +++ .../Resources/CityResourceDailyCollection.php | 21 ++ app/Http/Resources/CityResourceHourly.php | 33 +++ .../CityResourceHourlyCollection.php | 21 ++ app/Models/City.php | 24 ++ app/Models/User.php | 45 ++++ database/factories/UserFactory.php | 61 +++-- .../2014_10_12_000000_create_users_table.php | 18 +- ...000_create_password_reset_tokens_table.php | 28 +++ ..._08_19_000000_create_failed_jobs_table.php | 32 +++ ...01_create_personal_access_tokens_table.php | 33 +++ .../2024_04_01_020626_add_city_table.php | 30 +++ database/seeds/CitySeed.php | 120 ++++++++++ database/seeds/DatabaseSeeder.php | 14 +- routes/api.php | 15 +- 32 files changed, 1163 insertions(+), 72 deletions(-) create mode 100644 app/City.php create mode 100644 app/Helper/HelperUtil.php create mode 100644 app/Http/Controllers/CurrentWeatherController.php create mode 100644 app/Http/Controllers/DailyWeatherController.php create mode 100644 app/Http/Controllers/HourlyWeatherController.php create mode 100644 app/Http/Middleware/PreventRequestsDuringMaintenance.php create mode 100644 app/Http/Middleware/TrustHosts.php create mode 100644 app/Http/Middleware/ValidateSignature.php create mode 100644 app/Http/Resources/CityResource.php create mode 100644 app/Http/Resources/CityResourceCollection.php create mode 100644 app/Http/Resources/CityResourceDaily.php create mode 100644 app/Http/Resources/CityResourceDailyCollection.php create mode 100644 app/Http/Resources/CityResourceHourly.php create mode 100644 app/Http/Resources/CityResourceHourlyCollection.php create mode 100644 app/Models/City.php create mode 100644 app/Models/User.php create mode 100644 database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php create mode 100644 database/migrations/2019_08_19_000000_create_failed_jobs_table.php create mode 100644 database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php create mode 100644 database/migrations/2024_04_01_020626_add_city_table.php create mode 100644 database/seeds/CitySeed.php diff --git a/app/City.php b/app/City.php new file mode 100644 index 000000000..0cc1ea33c --- /dev/null +++ b/app/City.php @@ -0,0 +1,24 @@ +get($url)->getBody()->getContents(); + $response = json_decode($response); + + return $response; + } + + public static function convertDailyTime($response) + { + $data = $response; + + foreach ($data as $sun) { + $result[] = Carbon::parse($sun)->setTimezone('UTC')->format('Y-m-d H:i:s'); + } + + return $result; + } + + public static function concateArray($response, $format) + { + $data = $response; + + foreach ($data as $sun) { + $result[] = $sun . " " . $format; + } + + return $result; + } + + //resource of data wraping + public static function wrapData(City $city, $response): stdClass + { + //array store the response + $response_result = [ + 'id' => $city->id, + 'munisipiu' => $city->name, + "tempu" => Carbon::parse($response->current->time)->setTimezone('UTC')->format('Y-m-d H:i:s'), + "temperatura_2m" => $response->current->temperature_2m . "°C", + "umidade_2m" => $response->current->relative_humidity_2m . "%", + "presipitasaun" => $response->current->precipitation . "mm", + "udan" => $response->current->rain . "mm", + "kodigu_klima" => $response->current->weather_code, + "kalohan_taka" => $response->current->cloud_cover . "%", + "presaun_tasi" => $response->current->pressure_msl . " hpa", + "presaun_rai" => $response->current->surface_pressure . " hpa", + "velosidade_anin_10m" => $response->current->wind_speed_10m . " km/h" + ]; + + //convert an array to object + $object_response = (object) $response_result; + + //return the data + return $object_response; + } + + public static function wrapDailyData(City $city, $response): stdClass + { + + $response_result = [ + 'id' => $city->id, + 'munisipiu' => $city->name, + "tempu" => $response->daily->time, + 'kodigu_klima' => $response->daily->weather_code, + "temperatura_2m_max" => HelperUtil::concateArray($response->daily->temperature_2m_max, '°C'), + "temperatura_2m_min" => HelperUtil::concateArray($response->daily->temperature_2m_min, '°C'), + "uv_index" => $response->daily->uv_index_max, + "presipitasaun_sum" => HelperUtil::concateArray($response->daily->precipitation_sum, 'mm'), + "udan_sum" => HelperUtil::concateArray($response->daily->rain_sum, 'mm'), + "velosidade_anin_10m" => HelperUtil::concateArray($response->daily->wind_speed_10m_max, 'km/h'), + "sunrise" => HelperUtil::convertDailyTime($response->daily->sunrise), + "sunset" => HelperUtil::convertDailyTime($response->daily->sunset) + ]; + + //convert an array to object + $object_response = (object) $response_result; + + //return the data + return $object_response; + } + + + public static function wrapHourlyData(City $city, $response): stdClass + { + $response_result = [ + 'id' => $city->id, + 'munisipiu' => $city->name, + "tempu" => HelperUtil::filterNextFiveHoursData($response->hourly->time), + 'kodigu_klima' => HelperUtil::filterNextFiveHoursData($response->hourly->weather_code), + "temperatura_2m" => HelperUtil::filterNextFiveHoursData($response->hourly->temperature_2m), + "umidade" => HelperUtil::filterNextFiveHoursData($response->hourly->relative_humidity_2m), + "presipitasaun" => HelperUtil::filterNextFiveHoursData($response->hourly->precipitation), + "udan_sum" => HelperUtil::filterNextFiveHoursData($response->hourly->rain), + "velosidade_anin_10m" => HelperUtil::filterNextFiveHoursData($response->hourly->wind_speed_10m), + "kalohan_taka" => HelperUtil::filterNextFiveHoursData($response->hourly->cloud_cover), + "presaun_rai" => HelperUtil::filterNextFiveHoursData($response->hourly->pressure_msl), + "presaun_tasi" => HelperUtil::filterNextFiveHoursData($response->hourly->surface_pressure) + ]; + + //convert an array to object + $object_response = (object) $response_result; + + //return the data + return $object_response; + } + + private static function filterNextFiveHoursData($data_json) + { + date_default_timezone_set("Asia/Dili"); + $timestamp = time(); // atau dapatkan timestamp dari sumber waktu lainnya + $dateTime = new DateTime("@$timestamp"); + $iso8601 = $dateTime->format('c'); + + $current_time = $iso8601; + + // Mengonversi waktu saat ini ke timestamp + $timestamp = strtotime($current_time); + + // Membulatkan ke jam berikutnya + $rounded_time = date('Y-m-d\TH:00', ceil($timestamp / 3600) * 3600); + + // Mencari waktu saat ini dalam data JSON + $index = array_search($rounded_time, $data_json); + + $now_hours_data = array_slice($data_json, $index + 8, 10, true); + // Mengatur kembali kunci-kunci array + $now_hours_data = array_values($now_hours_data); + + return $now_hours_data; + } + + public static function filterInputCity($city_name) + { + $city_name = strtolower($city_name); + //switch statement case of city name + switch ($city_name) { + case 'dili': + return 'dili'; + + case 'aileu': + return 'aileu'; + + case 'manatutu': + case 'manatuto': + return 'manatutu'; + + case 'bobonaru': + case 'bobonaro': + case 'maliana': + return 'bobonaru'; + + case 'ermera': + return 'ermera'; + + case 'atauru': + case 'atauro': + return 'atauro'; + + case 'liquisa': + case 'likisa': + case 'liquica': + case 'likuisa': + return 'likisa'; + + case 'lospalos': + case 'lautem': + return 'lautem'; + + case 'same': + case 'manufahi': + return 'manufahi'; + + case 'ainaru': + case 'ainaro': + return 'ainaro'; + + case 'baukau': + case 'baucau': + return 'baucau'; + + case 'oecusse': + case 'oekusse': + case 'oekuse': + return 'oekusi'; + + case 'viqueque': + case 'vikeke': + case 'vikuekue': + return 'vikeke'; + + case 'suai': + case 'kovalima': + case 'covalima': + return 'kovalima'; + + default: + return 'lahetan'; + } + } +} diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 03e02a23e..77ec359ab 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -2,12 +2,11 @@ namespace App\Http\Controllers; -use Illuminate\Foundation\Bus\DispatchesJobs; -use Illuminate\Routing\Controller as BaseController; -use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; +use Illuminate\Foundation\Validation\ValidatesRequests; +use Illuminate\Routing\Controller as BaseController; class Controller extends BaseController { - use AuthorizesRequests, DispatchesJobs, ValidatesRequests; + use AuthorizesRequests, ValidatesRequests; } diff --git a/app/Http/Controllers/CurrentWeatherController.php b/app/Http/Controllers/CurrentWeatherController.php new file mode 100644 index 000000000..329ad4402 --- /dev/null +++ b/app/Http/Controllers/CurrentWeatherController.php @@ -0,0 +1,132 @@ +baseUrl . "latitude=" . $city->lat . "&longitude=" . $city->lng . $this->tailUrl; + //get body and content with asyn method + $promises[$city->id] = $client->getAsync($url)->then(function ($response) use ($city) { + //decode it from json + $response = json_decode($response->getBody()->getContents()); + //wrap the data + return HelperUtil::wrapData($city, $response); + }); + } + + //Make wait jobs for the data + $responses = Promise\Utils::settle($promises)->wait(); + $cities_data = []; + + //looping the await data and store them into cities_data variable + foreach ($responses as $cityId => $promise) { + //make sure promise data is fulfiled if isn't throw exception errors + if ($promise['state'] === 'fulfilled') { + $cities_data[] = $promise['value']; + } else { + // Handle errors + return throw new HttpResponseException(response() + ->json(['errors' => 'Dadus la existe']) + ->setStatusCode(400)); + } + } + + //all data that have been got put in into CityResourceCollection and return it + return new CityResourceCollection($cities_data); + } + + /** + * @OA\Get( + * path="/api/klima/{municipality}", + * summary="Get Each Current weather data from 14 municipalities", + * tags={"Current Weather Data"}, + * @OA\Parameter( + * name="municipality", + * in="path", + * description="Name of the municipality to get weather data for", + * required=true, + * @OA\Schema( + * type="string" + * ) + * ), + * @OA\Response(response=200, description="Successful operation"), + * @OA\Response(response=400, description="Invalid request") + * ) + */ + public function getEachCurrentWeather(string $city_name): CityResource + { + //filter input url query data + $city_name = HelperUtil::filterInputCity($city_name); + //parsing city data from database + $city = City::where('name', $city_name)->first(); + //if get the data return it into CityResource + if ($city) { + + //url concatenation + $url = $this->baseUrl . "latitude=" . $city->lat . "&longitude=" . $city->lng . $this->tailUrl; + + //parse the data from url + $response = HelperUtil::parseMeteoData($url); + //wrap the data + $object_response = HelperUtil::wrapData($city, $response); + + //return to CityResource + return new CityResource($object_response); + } else { + //if not throw an exception + return throw new HttpResponseException(response() + ->json(['errors' => 'Dadus la existe']) + ->setStatusCode(400)); + } + } +} diff --git a/app/Http/Controllers/DailyWeatherController.php b/app/Http/Controllers/DailyWeatherController.php new file mode 100644 index 000000000..c721b5bf0 --- /dev/null +++ b/app/Http/Controllers/DailyWeatherController.php @@ -0,0 +1,86 @@ +first(); + //check data is presence + if ($city) { + //create array of promise + $promises = []; + //initialize http client + $client = new Client(); + } else { + return throw new HttpResponseException(response() + ->json(['errors' => 'Dadus la existe']) + ->setStatusCode(400)); + } + + + //url concatenation + $url = $this->baseUrl . "latitude=" . $city->lat . "&longitude=" . $city->lng . $this->tailUrl; + //get body and content with asyn method + $promises[$city->id] = $client->getAsync($url)->then(function ($response) use ($city) { + //decode it from json + $response = json_decode($response->getBody()->getContents()); + //wrap the data + return HelperUtil::wrapDailyData($city, $response); + }); + + //Make wait jobs for the data + $responses = Promise\Utils::settle($promises)->wait(); + $cities_data = []; + + //looping the await data and store them into cities_data variable + foreach ($responses as $cityId => $promise) { + + //make sure promise data is fulfiled if isn't throw exception errors + if ($promise['state'] === 'fulfilled') { + $cities_data[] = $promise['value']; + } else { + // Handle errors + return throw new HttpResponseException(response() + ->json(['errors' => 'Dadus la existe']) + ->setStatusCode(400)); + } + } + + //all data that have been got put in into CityResourceCollection and return it + return new CityResourceDailyCollection($cities_data); + } +} diff --git a/app/Http/Controllers/HourlyWeatherController.php b/app/Http/Controllers/HourlyWeatherController.php new file mode 100644 index 000000000..4f313bb55 --- /dev/null +++ b/app/Http/Controllers/HourlyWeatherController.php @@ -0,0 +1,86 @@ +first(); + //create array of promise + if ($city) { + //create array of promise + $promises = []; + //initialize http client + $client = new Client(); + } else { + return throw new HttpResponseException(response() + ->json(['errors' => 'Dadus la existe']) + ->setStatusCode(400)); + } + + //url concatenation + $url = $this->baseUrl . "latitude=" . $city->lat . "&longitude=" . $city->lng . $this->tailUrl; + //get body and content with asyn method + $promises[$city->id] = $client->getAsync($url)->then(function ($response) use ($city) { + //decode it from json + $response = json_decode($response->getBody()->getContents()); + //wrap the data + return HelperUtil::wrapHourlyData($city, $response); + }); + + //Make wait jobs for the data + $responses = Promise\Utils::settle($promises)->wait(); + $cities_data = []; + + //looping the await data and store them into cities_data variable + foreach ($responses as $cityId => $promise) { + + //make sure promise data is fulfiled if isn't throw exception errors + if ($promise['state'] === 'fulfilled') { + $cities_data[] = $promise['value']; + } else { + // Handle errors + return throw new HttpResponseException(response() + ->json(['errors' => 'Dadus la existe']) + ->setStatusCode(400)); + } + } + + //all data that have been got put in into CityResourceCollection and return it + return new CityResourceHourlyCollection($cities_data); + } +} diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index a4be5c587..d4ef6447a 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -3,19 +3,15 @@ namespace App\Http\Middleware; use Illuminate\Auth\Middleware\Authenticate as Middleware; +use Illuminate\Http\Request; class Authenticate extends Middleware { /** * Get the path the user should be redirected to when they are not authenticated. - * - * @param \Illuminate\Http\Request $request - * @return string */ - protected function redirectTo($request) + protected function redirectTo(Request $request): ?string { - if (! $request->expectsJson()) { - return route('login'); - } + return $request->expectsJson() ? null : route('login'); } } diff --git a/app/Http/Middleware/EncryptCookies.php b/app/Http/Middleware/EncryptCookies.php index 033136ad1..867695bdc 100644 --- a/app/Http/Middleware/EncryptCookies.php +++ b/app/Http/Middleware/EncryptCookies.php @@ -9,7 +9,7 @@ class EncryptCookies extends Middleware /** * The names of the cookies that should not be encrypted. * - * @var array + * @var array */ protected $except = [ // diff --git a/app/Http/Middleware/PreventRequestsDuringMaintenance.php b/app/Http/Middleware/PreventRequestsDuringMaintenance.php new file mode 100644 index 000000000..74cbd9a9e --- /dev/null +++ b/app/Http/Middleware/PreventRequestsDuringMaintenance.php @@ -0,0 +1,17 @@ + + */ + protected $except = [ + // + ]; +} diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php index e4cec9c8b..afc78c4e5 100644 --- a/app/Http/Middleware/RedirectIfAuthenticated.php +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -2,23 +2,27 @@ namespace App\Http\Middleware; +use App\Providers\RouteServiceProvider; use Closure; +use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; +use Symfony\Component\HttpFoundation\Response; class RedirectIfAuthenticated { /** * Handle an incoming request. * - * @param \Illuminate\Http\Request $request - * @param \Closure $next - * @param string|null $guard - * @return mixed + * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */ - public function handle($request, Closure $next, $guard = null) + public function handle(Request $request, Closure $next, string ...$guards): Response { - if (Auth::guard($guard)->check()) { - return redirect('/home'); + $guards = empty($guards) ? [null] : $guards; + + foreach ($guards as $guard) { + if (Auth::guard($guard)->check()) { + return redirect(RouteServiceProvider::HOME); + } } return $next($request); diff --git a/app/Http/Middleware/TrimStrings.php b/app/Http/Middleware/TrimStrings.php index 5a50e7b5c..88cadcaaf 100644 --- a/app/Http/Middleware/TrimStrings.php +++ b/app/Http/Middleware/TrimStrings.php @@ -9,9 +9,10 @@ class TrimStrings extends Middleware /** * The names of the attributes that should not be trimmed. * - * @var array + * @var array */ protected $except = [ + 'current_password', 'password', 'password_confirmation', ]; diff --git a/app/Http/Middleware/TrustHosts.php b/app/Http/Middleware/TrustHosts.php new file mode 100644 index 000000000..c9c58bddc --- /dev/null +++ b/app/Http/Middleware/TrustHosts.php @@ -0,0 +1,20 @@ + + */ + public function hosts(): array + { + return [ + $this->allSubdomainsOfApplicationUrl(), + ]; + } +} diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php index 4f7aed47d..3391630ec 100644 --- a/app/Http/Middleware/TrustProxies.php +++ b/app/Http/Middleware/TrustProxies.php @@ -2,15 +2,15 @@ namespace App\Http\Middleware; -use Illuminate\Http\Request; use Illuminate\Http\Middleware\TrustProxies as Middleware; +use Illuminate\Http\Request; class TrustProxies extends Middleware { /** * The trusted proxies for this application. * - * @var array|string + * @var array|string|null */ protected $proxies; diff --git a/app/Http/Middleware/ValidateSignature.php b/app/Http/Middleware/ValidateSignature.php new file mode 100644 index 000000000..093bf64af --- /dev/null +++ b/app/Http/Middleware/ValidateSignature.php @@ -0,0 +1,22 @@ + + */ + protected $except = [ + // 'fbclid', + // 'utm_campaign', + // 'utm_content', + // 'utm_medium', + // 'utm_source', + // 'utm_term', + ]; +} diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 324a166bc..9e8652172 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -6,17 +6,10 @@ class VerifyCsrfToken extends Middleware { - /** - * Indicates whether the XSRF-TOKEN cookie should be set on the response. - * - * @var bool - */ - protected $addHttpCookie = true; - /** * The URIs that should be excluded from CSRF verification. * - * @var array + * @var array */ protected $except = [ // diff --git a/app/Http/Resources/CityResource.php b/app/Http/Resources/CityResource.php new file mode 100644 index 000000000..d46268129 --- /dev/null +++ b/app/Http/Resources/CityResource.php @@ -0,0 +1,32 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'munisipiu' => $this->munisipiu, + "tempu" => $this->tempu, + "temperatura_2m" => $this->temperatura_2m, + "umidade_2m" => $this->umidade_2m, + "presipitasaun" => $this->presipitasaun, + "udan" => $this->udan, + "kodigu_klima" => $this->kodigu_klima, + "kalohan_taka" => $this->kalohan_taka, + "presaun_tasi" => $this->presaun_tasi, + "presaun_rai" => $this->presaun_rai, + "velosidade_anin_10m" => $this->velosidade_anin_10m + ]; + } +} diff --git a/app/Http/Resources/CityResourceCollection.php b/app/Http/Resources/CityResourceCollection.php new file mode 100644 index 000000000..87c8715fc --- /dev/null +++ b/app/Http/Resources/CityResourceCollection.php @@ -0,0 +1,21 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'data' => CityResource::collection($this->collection) + ]; + } +} diff --git a/app/Http/Resources/CityResourceDaily.php b/app/Http/Resources/CityResourceDaily.php new file mode 100644 index 000000000..f9927b464 --- /dev/null +++ b/app/Http/Resources/CityResourceDaily.php @@ -0,0 +1,32 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'munisipiu' => $this->munisipiu, + "tempu" => $this->tempu, + 'kodigu_klima' => $this->kodigu_klima, + "temperatura_2m_max" => $this->temperatura_2m_max, + "temperatura_2m_min" => $this->temperatura_2m_min, + "uv_index" => $this->uv_index, + "presipitasaun_sum" => $this->presipitasaun_sum, + "udan_sum" => $this->udan_sum, + "velosidade_anin_10m" => $this->velosidade_anin_10m, + "sunrise" => $this->sunrise, + "sunset" => $this->sunset + ]; + } +} diff --git a/app/Http/Resources/CityResourceDailyCollection.php b/app/Http/Resources/CityResourceDailyCollection.php new file mode 100644 index 000000000..9d66d3cd5 --- /dev/null +++ b/app/Http/Resources/CityResourceDailyCollection.php @@ -0,0 +1,21 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'data' => CityResourceDaily::collection($this->collection) + ]; + } +} diff --git a/app/Http/Resources/CityResourceHourly.php b/app/Http/Resources/CityResourceHourly.php new file mode 100644 index 000000000..dcfe57d37 --- /dev/null +++ b/app/Http/Resources/CityResourceHourly.php @@ -0,0 +1,33 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'munisipiu' => $this->munisipiu, + "tempu" => HelperUtil::convertDailyTime($this->tempu), + 'kodigu_klima' => $this->kodigu_klima, + "temperatura_2m" => HelperUtil::concateArray($this->temperatura_2m, '°C'), + "umidade" => HelperUtil::concateArray($this->umidade, '%'), + "presipitasaun" => HelperUtil::concateArray($this->presipitasaun, 'mm'), + "udan_sum" => HelperUtil::concateArray($this->udan_sum, 'mm'), + "velosidade_anin_10m" => HelperUtil::concateArray($this->velosidade_anin_10m, 'km/h'), + "kalohan_taka" => HelperUtil::concateArray($this->kalohan_taka, '%'), + "presaun_rai" => HelperUtil::concateArray($this->presaun_rai, 'hPa'), + "presaun_tasi" => HelperUtil::concateArray($this->presaun_tasi, 'hPa') + ]; + } +} diff --git a/app/Http/Resources/CityResourceHourlyCollection.php b/app/Http/Resources/CityResourceHourlyCollection.php new file mode 100644 index 000000000..23fa4738d --- /dev/null +++ b/app/Http/Resources/CityResourceHourlyCollection.php @@ -0,0 +1,21 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'data' => CityResourceHourly::collection($this->collection) + ]; + } +} diff --git a/app/Models/City.php b/app/Models/City.php new file mode 100644 index 000000000..0cc1ea33c --- /dev/null +++ b/app/Models/City.php @@ -0,0 +1,24 @@ + + */ + protected $fillable = [ + 'name', + 'email', + 'password', + ]; + + /** + * The attributes that should be hidden for serialization. + * + * @var array + */ + protected $hidden = [ + 'password', + 'remember_token', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'email_verified_at' => 'datetime', + 'password' => 'hashed', + ]; +} diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index 5e516ceea..584104c9c 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -1,27 +1,44 @@ + */ +class UserFactory extends Factory +{ + /** + * The current password being used by the factory. + */ + protected static ?string $password; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'name' => fake()->name(), + 'email' => fake()->unique()->safeEmail(), + 'email_verified_at' => now(), + 'password' => static::$password ??= Hash::make('password'), + 'remember_token' => Str::random(10), + ]; + } -$factory->define(User::class, function (Faker $faker) { - return [ - 'name' => $faker->name, - 'email' => $faker->unique()->safeEmail, - 'email_verified_at' => now(), - 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password - 'remember_token' => Str::random(10), - ]; -}); + /** + * Indicate that the model's email address should be unverified. + */ + public function unverified(): static + { + return $this->state(fn (array $attributes) => [ + 'email_verified_at' => null, + ]); + } +} diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index 4a3ba4723..444fafb7f 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -1,20 +1,18 @@ bigIncrements('id'); + $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); @@ -26,11 +24,9 @@ public function up() /** * Reverse the migrations. - * - * @return void */ - public function down() + public function down(): void { Schema::dropIfExists('users'); } -} +}; diff --git a/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php b/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php new file mode 100644 index 000000000..81a7229b0 --- /dev/null +++ b/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php @@ -0,0 +1,28 @@ +string('email')->primary(); + $table->string('token'); + $table->timestamp('created_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('password_reset_tokens'); + } +}; diff --git a/database/migrations/2019_08_19_000000_create_failed_jobs_table.php b/database/migrations/2019_08_19_000000_create_failed_jobs_table.php new file mode 100644 index 000000000..249da8171 --- /dev/null +++ b/database/migrations/2019_08_19_000000_create_failed_jobs_table.php @@ -0,0 +1,32 @@ +id(); + $table->string('uuid')->unique(); + $table->text('connection'); + $table->text('queue'); + $table->longText('payload'); + $table->longText('exception'); + $table->timestamp('failed_at')->useCurrent(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('failed_jobs'); + } +}; diff --git a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php new file mode 100644 index 000000000..e828ad818 --- /dev/null +++ b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php @@ -0,0 +1,33 @@ +id(); + $table->morphs('tokenable'); + $table->string('name'); + $table->string('token', 64)->unique(); + $table->text('abilities')->nullable(); + $table->timestamp('last_used_at')->nullable(); + $table->timestamp('expires_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('personal_access_tokens'); + } +}; diff --git a/database/migrations/2024_04_01_020626_add_city_table.php b/database/migrations/2024_04_01_020626_add_city_table.php new file mode 100644 index 000000000..b7e2bb1e7 --- /dev/null +++ b/database/migrations/2024_04_01_020626_add_city_table.php @@ -0,0 +1,30 @@ +id(); + $table->string('name', 100)->nullable(false); + $table->string('lat', 100)->nullable(false); + $table->string('lng', 100)->nullable(false); + $table->string('country', 100)->default('Timor-Leste')->nullable(false); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('city'); + } +}; diff --git a/database/seeds/CitySeed.php b/database/seeds/CitySeed.php new file mode 100644 index 000000000..009093997 --- /dev/null +++ b/database/seeds/CitySeed.php @@ -0,0 +1,120 @@ + 'dili', + 'lat' => '-8.5586', + 'lng' => '125.5736', + 'country' => 'Timor-Leste' + ], + + [ + 'name' => 'manufahi', + 'lat' => '-9.0042', + 'lng' => '125.6486', + 'country' => 'Timor-Leste' + ], + + [ + 'name' => 'ainaro', + 'lat' => '-8.9924', + 'lng' => '125.5082', + 'country' => 'Timor-Leste' + ], + + [ + 'name' => 'baucau', + 'lat' => '-8.4757', + 'lng' => '126.4563', + 'country' => 'Timor-Leste' + ], + + [ + 'name' => 'lautem', + 'lat' => '-8.3642', + 'lng' => '126.9044', + 'country' => 'Timor-Leste' + ], + + [ + 'name' => 'aileu', + 'lat' => '-8.7281', + 'lng' => '125.5664', + 'country' => 'Timor-Leste' + ], + + [ + 'name' => 'likisa', + 'lat' => '-8.5875', + 'lng' => '125.3419', + 'country' => 'Timor-Leste' + ], + + [ + 'name' => 'ermera', + 'lat' => '-8.7522', + 'lng' => '125.3969', + 'country' => 'Timor-Leste' + ], + + [ + 'name' => 'bobonaru', + 'lat' => '-9.0319', + 'lng' => '125.325', + 'country' => 'Timor-Leste' + ], + + [ + 'name' => 'manatutu', + 'lat' => '-8.5114', + 'lng' => '126.0131', + 'country' => 'Timor-Leste' + ], + + [ + 'name' => 'vikeke', + 'lat' => '-8.8575', + 'lng' => '126.3647', + 'country' => 'Timor-Leste' + ], + + [ + 'name' => 'kovalima', + 'lat' => '-9.3129', + 'lng' => '125.2565', + 'country' => 'Timor-Leste' + ], + + [ + 'name' => 'oekusi', + 'lat' => '-9.2037', + 'lng' => '124.3569', + 'country' => 'Timor-Leste' + ], + + [ + 'name' => 'atauro', + 'lat' => '-8.2667', + 'lng' => '125.6014', + 'country' => 'Timor-Leste' + ], + ]; + foreach ($data_cities as $city) { + City::create($city); + } + } +} diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 91cb6d1c2..a9f4519fc 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -1,16 +1,22 @@ call(UsersTableSeeder::class); + // \App\Models\User::factory(10)->create(); + + // \App\Models\User::factory()->create([ + // 'name' => 'Test User', + // 'email' => 'test@example.com', + // ]); } } diff --git a/routes/api.php b/routes/api.php index c641ca5e5..06b5c8786 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,6 +1,10 @@ get('/user', function (Request $request) { - return $request->user(); -}); +Route::get('/klima', [CurrentWeatherController::class, 'getAllCurrentWeather']); +Route::get('/klima/{name}', [CurrentWeatherController::class, 'getEachCurrentWeather']); +Route::get('/klima/diariu/{name}', [DailyWeatherController::class, 'getDailyWeather']); +Route::get('/klima/oras/{name}', [HourlyWeatherController::class, 'getHourlyWeather']);