init
This commit is contained in:
36
app/Console/Kernel.php
Normal file
36
app/Console/Kernel.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
use App\Http\Controllers\CityController;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
$schedule->call(function () {
|
||||
$CityController = new CityController();
|
||||
$CityController->refresh();
|
||||
})->everyHour();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the commands for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function commands()
|
||||
{
|
||||
$this->load(__DIR__.'/Commands');
|
||||
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
}
|
||||
50
app/Exceptions/Handler.php
Normal file
50
app/Exceptions/Handler.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* A list of exception types with their corresponding custom log levels.
|
||||
*
|
||||
* @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>
|
||||
*/
|
||||
protected $levels = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
*
|
||||
* @var array<int, class-string<\Throwable>>
|
||||
*/
|
||||
protected $dontReport = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the inputs that are never flashed to the session on validation exceptions.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $dontFlash = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register the exception handling callbacks for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->reportable(function (Throwable $e) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
||||
36
app/Filters/ApiFilter.php
Normal file
36
app/Filters/ApiFilter.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filters;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ApiFilter {
|
||||
protected $safeParms = [];
|
||||
|
||||
protected $columnMap = [];
|
||||
|
||||
protected $operatorMap = [];
|
||||
|
||||
public function transform(Request $request) {
|
||||
$eloQuery = [];
|
||||
|
||||
foreach ($this->safeParms as $parm => $operators) {
|
||||
$query = $request->query($parm);
|
||||
|
||||
if (!isset($query)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$column = $this->columnMap[$parm] ?? $parm;
|
||||
|
||||
foreach ($operators as $operator) {
|
||||
if (isset($query[$operator])) {
|
||||
$eloQuery[] = [$column, $this->operatorMap[$operator], $query[$operator]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $eloQuery;
|
||||
}
|
||||
|
||||
}
|
||||
26
app/Filters/CityFilter.php
Normal file
26
app/Filters/CityFilter.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filters;
|
||||
|
||||
use App\Filters\ApiFilter;
|
||||
|
||||
class CityFilter extends ApiFilter {
|
||||
protected $safeParms = [
|
||||
'locationName' => ['eq'],
|
||||
'locationCountry' => ['eq'],
|
||||
'id' => ['eq']
|
||||
];
|
||||
|
||||
protected $columnMap = [
|
||||
'locationName' => 'location_name',
|
||||
'locationCountry' => 'location_country'
|
||||
];
|
||||
|
||||
protected $operatorMap = [
|
||||
'eq' => '=',
|
||||
'lt' => '<',
|
||||
'lte' => '<=',
|
||||
'gt' => '>',
|
||||
'gte' => '>=',
|
||||
];
|
||||
}
|
||||
93
app/Http/Controllers/CityController.php
Normal file
93
app/Http/Controllers/CityController.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\City;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class CityController extends Controller
|
||||
{
|
||||
|
||||
public function show()
|
||||
{
|
||||
$DatabaseController = new DatabaseController();
|
||||
return view('cities', [
|
||||
'cities' => $DatabaseController->getNewestWeatherDataForAllCities()
|
||||
]);
|
||||
}
|
||||
|
||||
public function create(Request $request) {
|
||||
$request->validate([
|
||||
'name' => 'required|max:85|regex:/^[a-zA-Z\säöüÄÖÜß]+$/',
|
||||
]);
|
||||
|
||||
$city = $request->name;
|
||||
|
||||
$response = WeatherstackController::requestByCity($city);
|
||||
|
||||
$WeatherstackController = new WeatherstackController();
|
||||
$isValidResponse = $WeatherstackController->checkResponse($city, $response);
|
||||
|
||||
($isValidResponse[0]) ? DatabaseController::store($response) : redirect('/')->withErrors(['name' => $isValidResponse[1]]);
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
public function delete($id) {
|
||||
City::findOrFail($id)->delete();
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
public function refresh() {
|
||||
$cities = DB::table('cities')
|
||||
->select('id', 'location_name', 'location_country')
|
||||
->get();
|
||||
|
||||
foreach ($cities as $city) {
|
||||
$city = "$city->location_name,$city->location_country";
|
||||
|
||||
$response = WeatherstackController::requestByCity($city);
|
||||
|
||||
($response->successful() === false) ? redirect('/')->withErrors(['name' => "Aktualisierung fehlgeschlagen"])
|
||||
: DatabaseController::store($response);
|
||||
}
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
public function setup() {
|
||||
$credentials = [
|
||||
'email' => 'admin@admin.com',
|
||||
'password' => 'password'
|
||||
];
|
||||
|
||||
if (!Auth::attempt($credentials)) {
|
||||
$user = new \App\Models\User();
|
||||
|
||||
$user->name = 'Admin';
|
||||
$user->email = $credentials['email'];
|
||||
$user->password = Hash::make($credentials['password']);
|
||||
|
||||
$user->save();
|
||||
|
||||
if (Auth::attempt($credentials)) {
|
||||
$user = Auth::user();
|
||||
|
||||
$adminToken = $user->createToken('admin-token', ['create','update','delete']);
|
||||
$updateToken = $user->createToken('update-token', ['create','update']);
|
||||
$basicToken = $user->createToken('basic-token', ['none']);
|
||||
|
||||
return [
|
||||
'admin' => $adminToken->plainTextToken,
|
||||
'update' => $updateToken->plainTextToken,
|
||||
'basic' => $basicToken->plainTextToken,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
13
app/Http/Controllers/Controller.php
Normal file
13
app/Http/Controllers/Controller.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
}
|
||||
97
app/Http/Controllers/DatabaseController.php
Normal file
97
app/Http/Controllers/DatabaseController.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Models\City;
|
||||
use App\Models\WeatherData;
|
||||
use Illuminate\Http\Client\Response as ClientResponse;
|
||||
use App\Http\Requests\StoreCityRequest;
|
||||
use App\Http\Requests\UpdateCityRequest;
|
||||
|
||||
class DatabaseController extends Controller
|
||||
{
|
||||
|
||||
public static function getNewestWeatherDataByCityID($city_id) {
|
||||
return DB::table('cities')
|
||||
->join('weather_data', 'cities.id', '=', 'weather_data.city_id')
|
||||
->select('cities.id', 'cities.location_name', 'cities.location_country', 'weather_data.current_temperature', 'weather_data.weather_icon', 'weather_data.weather_description', 'weather_data.wind_speed', 'weather_data.wind_dir', 'weather_data.localtime_epoch')
|
||||
->where('cities.id', '=', $city_id)
|
||||
->orderBy('localtime_epoch', 'desc')
|
||||
->first();
|
||||
}
|
||||
|
||||
public function getNewestWeatherDataForAllCities () {
|
||||
$city_ids = DB::table('cities')->pluck('id');
|
||||
|
||||
$responses = collect();
|
||||
|
||||
foreach ($city_ids as $city_id) {
|
||||
$response = $this->getNewestWeatherDataByCityID($city_id);
|
||||
$responses->push($response);
|
||||
}
|
||||
|
||||
return $responses;
|
||||
}
|
||||
|
||||
public static function store(ClientResponse $response) {
|
||||
$city = City::firstOrNew([
|
||||
'location_name' => $response->json('location.name'),
|
||||
'location_country' => $response->json('location.country')
|
||||
]);
|
||||
$city->save();
|
||||
|
||||
$weatherData = WeatherData::firstOrNew([
|
||||
'city_id' => $city->id,
|
||||
'current_temperature' => $response->json('current.temperature'),
|
||||
'weather_icon' => $response->json("current.weather_icons")[0],
|
||||
'weather_description' => $response->json('current.weather_descriptions')[0],
|
||||
'wind_speed' => $response->json('current.wind_speed'),
|
||||
'wind_dir' => $response->json('current.wind_dir'),
|
||||
'localtime_epoch' => $response->json('location.localtime_epoch')
|
||||
]);
|
||||
$weatherData->save();
|
||||
}
|
||||
|
||||
public static function storeApiRequest(StoreCityRequest $request) {
|
||||
$city = City::firstOrNew([
|
||||
'location_name' => $request->location_name,
|
||||
'location_country' => $request->location_country
|
||||
]);
|
||||
$city->save();
|
||||
|
||||
$weatherData = WeatherData::firstOrNew([
|
||||
'city_id' => $city->id,
|
||||
'current_temperature' => $request->currentTemperature,
|
||||
'weather_icon' => $request->weatherIcon,
|
||||
'weather_description' => $request->weatherDescription,
|
||||
'wind_speed' => $request->windSpeed,
|
||||
'wind_dir' => $request->windDir,
|
||||
'localtime_epoch' => $request->localtimeEpoch
|
||||
]);
|
||||
$weatherData->save();
|
||||
|
||||
return $city->id;
|
||||
}
|
||||
|
||||
public function updateApiRequest($id, UpdateCityRequest $request) {
|
||||
$city = $this->getNewestWeatherDataByCityID($id);
|
||||
|
||||
DB::table('cities')
|
||||
->join('weather_data', 'cities.id', '=', 'weather_data.city_id')
|
||||
->select('cities.location_name', 'cities.location_country', 'weather_data.current_temperature', 'weather_data.weather_icon', 'weather_data.weather_description', 'weather_data.wind_speed', 'weather_data.wind_dir', 'weather_data.localtime_epoch')
|
||||
->where('cities.id', '=', $id)
|
||||
->where('weather_data.localtime_epoch', '=', $city->localtime_epoch)
|
||||
->update([
|
||||
'cities.location_name' => $request->location_name,
|
||||
'cities.location_country' => $request->location_country,
|
||||
'weather_data.current_temperature' => $request->currentTemperature,
|
||||
'weather_data.weather_icon' => $request->weatherIcon,
|
||||
'weather_data.weather_description' => $request->weatherDescription,
|
||||
'weather_data.wind_speed' => $request->windSpeed,
|
||||
'weather_data.wind_dir' => $request->windDir,
|
||||
'weather_data.localtime_epoch' => $request->localtimeEpoch
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
54
app/Http/Controllers/WeatherstackController.php
Normal file
54
app/Http/Controllers/WeatherstackController.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Http\Client\Response as ClientResponse;
|
||||
use App\Models\City;
|
||||
|
||||
class WeatherstackController extends Controller
|
||||
{
|
||||
|
||||
public static function requestByCity($city) {
|
||||
$access_key = config('app.weatherstack_api_key');
|
||||
$units = 'm'; /* m for Metric, s for Scientific, f for Fahrenheit */
|
||||
$url = 'http://api.weatherstack.com/current';
|
||||
|
||||
return Http::acceptJson()->get($url, [
|
||||
'access_key' => $access_key,
|
||||
'units' => $units,
|
||||
'query' => $city
|
||||
]);
|
||||
}
|
||||
|
||||
public function checkResponse($city, ClientResponse $response) {
|
||||
if ($response->successful()) {
|
||||
[$isValidResponse, $error] = $this->checkErrorMessage($city, $response);
|
||||
}
|
||||
elseif ($response->failed()) {
|
||||
$isValidResponse = false;
|
||||
$error = 'Request failed.';
|
||||
}
|
||||
|
||||
return [$isValidResponse, $error];
|
||||
}
|
||||
|
||||
public static function checkErrorMessage($city, ClientResponse $response) {
|
||||
$isValidResponse = true;
|
||||
$error = '';
|
||||
|
||||
if ($response->json('success') === false) {
|
||||
$isValidResponse = false;
|
||||
|
||||
($response->json('error.type') === 'usage_limit_reached') ? $error = 'The usage limit of your API key has been reached.'
|
||||
: $error = "No city named '{$city}' could be found.";
|
||||
}
|
||||
elseif (City::where('location_name', $response->json('location.name'))->exists()) {
|
||||
$isValidResponse = false;
|
||||
$error = "'{$response->json('location.name')}, {$response->json('location.country')}' has been already added.";
|
||||
}
|
||||
|
||||
return [$isValidResponse, $error];
|
||||
}
|
||||
|
||||
}
|
||||
67
app/Http/Kernel.php
Normal file
67
app/Http/Kernel.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
* These middleware are run during every request to your application.
|
||||
*
|
||||
* @var array<int, class-string|string>
|
||||
*/
|
||||
protected $middleware = [
|
||||
// \App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Illuminate\Http\Middleware\HandleCors::class,
|
||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware groups.
|
||||
*
|
||||
* @var array<string, array<int, class-string|string>>
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
||||
'throttle:api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware.
|
||||
*
|
||||
* These middleware may be assigned to groups or used individually.
|
||||
*
|
||||
* @var array<string, class-string|string>
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'signed' => \App\Http\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
];
|
||||
}
|
||||
21
app/Http/Middleware/Authenticate.php
Normal file
21
app/Http/Middleware/Authenticate.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
|
||||
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|null
|
||||
*/
|
||||
protected function redirectTo($request)
|
||||
{
|
||||
if (! $request->expectsJson()) {
|
||||
return route('login');
|
||||
}
|
||||
}
|
||||
}
|
||||
17
app/Http/Middleware/EncryptCookies.php
Normal file
17
app/Http/Middleware/EncryptCookies.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
||||
|
||||
class EncryptCookies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
17
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Normal file
17
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
|
||||
|
||||
class PreventRequestsDuringMaintenance extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
32
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
32
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||
* @param string|null ...$guards
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle(Request $request, Closure $next, ...$guards)
|
||||
{
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
19
app/Http/Middleware/TrimStrings.php
Normal file
19
app/Http/Middleware/TrimStrings.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||
|
||||
class TrimStrings extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the attributes that should not be trimmed.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
}
|
||||
20
app/Http/Middleware/TrustHosts.php
Normal file
20
app/Http/Middleware/TrustHosts.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustHosts as Middleware;
|
||||
|
||||
class TrustHosts extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the host patterns that should be trusted.
|
||||
*
|
||||
* @return array<int, string|null>
|
||||
*/
|
||||
public function hosts()
|
||||
{
|
||||
return [
|
||||
$this->allSubdomainsOfApplicationUrl(),
|
||||
];
|
||||
}
|
||||
}
|
||||
28
app/Http/Middleware/TrustProxies.php
Normal file
28
app/Http/Middleware/TrustProxies.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* @var array<int, string>|string|null
|
||||
*/
|
||||
protected $proxies;
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
}
|
||||
22
app/Http/Middleware/ValidateSignature.php
Normal file
22
app/Http/Middleware/ValidateSignature.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Routing\Middleware\ValidateSignature as Middleware;
|
||||
|
||||
class ValidateSignature extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the parameters that should be ignored.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $ignore = [
|
||||
// 'fbclid',
|
||||
// 'utm_campaign',
|
||||
// 'utm_content',
|
||||
// 'utm_medium',
|
||||
// 'utm_source',
|
||||
// 'utm_term',
|
||||
];
|
||||
}
|
||||
17
app/Http/Middleware/VerifyCsrfToken.php
Normal file
17
app/Http/Middleware/VerifyCsrfToken.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
||||
|
||||
class VerifyCsrfToken extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
50
app/Http/Requests/StoreCityRequest.php
Normal file
50
app/Http/Requests/StoreCityRequest.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreCityRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
$user = $this->user();
|
||||
|
||||
return $user != null && $user->tokenCan('create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'locationName' => ['required'],
|
||||
'locationCountry' => ['required'],
|
||||
'currentTemperature' => ['required'],
|
||||
'weatherIcon' => ['required'],
|
||||
'weatherDescription' => ['required'],
|
||||
'windSpeed' => ['required'],
|
||||
'localtimeEpoch' => ['required'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function prepareForValidation() {
|
||||
$this->merge([
|
||||
'location_name' => $this->locationName,
|
||||
'location_country' => $this->locationCountry,
|
||||
'current_temperature' => $this->currentTemperature,
|
||||
'weather_icon' => $this->weatherIcon,
|
||||
'weather_description' => $this->weatherDescription,
|
||||
'wind_speed' => $this->wind_speed,
|
||||
'localtime_epoch' => $this->localtime_epoch
|
||||
]);
|
||||
}
|
||||
}
|
||||
55
app/Http/Requests/UpdateCityRequest.php
Normal file
55
app/Http/Requests/UpdateCityRequest.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateCityRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
$user = $this->user();
|
||||
|
||||
return $user != null && $user->tokenCan('update');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
|
||||
|
||||
if ($this->method() == 'PUT') {
|
||||
return [
|
||||
'locationName' => ['required'],
|
||||
'locationCountry' => ['required'],
|
||||
'currentTemperature' => ['required'],
|
||||
'weatherIcon' => ['required'],
|
||||
'weatherDescription' => ['required'],
|
||||
'windSpeed' => ['required'],
|
||||
'localtimeEpoch' => ['required'],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function prepareForValidation() {
|
||||
$this->merge([
|
||||
'location_name' => $this->locationName,
|
||||
'location_country' => $this->locationCountry,
|
||||
'current_temperature' => $this->currentTemperature,
|
||||
'weather_icon' => $this->weatherIcon,
|
||||
'weather_description' => $this->weatherDescription,
|
||||
'wind_speed' => $this->wind_speed,
|
||||
'localtime_epoch' => $this->localtime_epoch
|
||||
]);
|
||||
}
|
||||
}
|
||||
23
app/Http/Resources/CityCollection.php
Normal file
23
app/Http/Resources/CityCollection.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class CityCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'data' => $this->collection,
|
||||
'meta' => ['count' => $this->collection->count()]
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
25
app/Http/Resources/CityResource.php
Normal file
25
app/Http/Resources/CityResource.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class CityResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'locationName' => $this->location_name,
|
||||
'locationCountry' => $this->location_country,
|
||||
'weatherData' => new WeatherDataCollection($this->weatherData)
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
22
app/Http/Resources/WeatherDataCollection.php
Normal file
22
app/Http/Resources/WeatherDataCollection.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class WeatherDataCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'data' => $this->collection
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
27
app/Http/Resources/WeatherDataResource.php
Normal file
27
app/Http/Resources/WeatherDataResource.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class WeatherDataResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'currentTemperature' => $this->current_temperature,
|
||||
'weatherIcon' => $this->weather_icon,
|
||||
'weatherDescription' => $this->weather_description,
|
||||
'windSpeed' => $this->wind_speed,
|
||||
'windDir' => $this->wind_dir,
|
||||
'localtimeEpoch' => $this->localtime_epoch,
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
17
app/Models/City.php
Normal file
17
app/Models/City.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class City extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = ['location_name', 'location_country'];
|
||||
|
||||
public function weatherdata() {
|
||||
return $this->hasMany(WeatherData::class);
|
||||
}
|
||||
}
|
||||
44
app/Models/User.php
Normal file
44
app/Models/User.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasApiTokens, HasFactory, Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
16
app/Models/WeatherData.php
Normal file
16
app/Models/WeatherData.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class WeatherData extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
protected $fillable = ['localtime_epoch', 'city_id', 'current_temperature', 'weather_icon', 'weather_description', 'wind_speed', 'wind_dir'];
|
||||
|
||||
public function city() {
|
||||
return $this->belongsTo(City::class);
|
||||
}
|
||||
}
|
||||
28
app/Providers/AppServiceProvider.php
Normal file
28
app/Providers/AppServiceProvider.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
30
app/Providers/AuthServiceProvider.php
Normal file
30
app/Providers/AuthServiceProvider.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
// use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The model to policy mappings for the application.
|
||||
*
|
||||
* @var array<class-string, class-string>
|
||||
*/
|
||||
protected $policies = [
|
||||
// 'App\Models\Model' => 'App\Policies\ModelPolicy',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any authentication / authorization services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->registerPolicies();
|
||||
|
||||
//
|
||||
}
|
||||
}
|
||||
21
app/Providers/BroadcastServiceProvider.php
Normal file
21
app/Providers/BroadcastServiceProvider.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Broadcast;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class BroadcastServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
Broadcast::routes();
|
||||
|
||||
require base_path('routes/channels.php');
|
||||
}
|
||||
}
|
||||
42
app/Providers/EventServiceProvider.php
Normal file
42
app/Providers/EventServiceProvider.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The event to listener mappings for the application.
|
||||
*
|
||||
* @var array<class-string, array<int, class-string>>
|
||||
*/
|
||||
protected $listen = [
|
||||
Registered::class => [
|
||||
SendEmailVerificationNotification::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any events for your application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if events and listeners should be automatically discovered.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldDiscoverEvents()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
52
app/Providers/RouteServiceProvider.php
Normal file
52
app/Providers/RouteServiceProvider.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The path to the "home" route for your application.
|
||||
*
|
||||
* Typically, users are redirected here after authentication.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const HOME = '/home';
|
||||
|
||||
/**
|
||||
* Define your route model bindings, pattern filters, and other route configuration.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->configureRateLimiting();
|
||||
|
||||
$this->routes(function () {
|
||||
Route::middleware('api')
|
||||
->prefix('api')
|
||||
->group(base_path('routes/api.php'));
|
||||
|
||||
Route::middleware('web')
|
||||
->group(base_path('routes/web.php'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the rate limiters for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function configureRateLimiting()
|
||||
{
|
||||
RateLimiter::for('api', function (Request $request) {
|
||||
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user