178 lines
6.1 KiB
PHP
178 lines
6.1 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Http\Resources\HitcountResource;
|
|
use App\Models\Hitcount;
|
|
use App\Models\Log;
|
|
use Detection\MobileDetect;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
class HitcountController extends Controller
|
|
{
|
|
/**
|
|
* @OA\Get(
|
|
* path="/api/hitcounts",
|
|
* summary="Get list of hitcounts (paginated, only admin)",
|
|
* description="Returns a paginated list of all recorded hitcounts. Requires admin privileges.",
|
|
* operationId="getHitcounts",
|
|
* tags={"Hitcounts"},
|
|
* security={{"bearerAuth":{}}},
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="List of hitcounts",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(
|
|
* property="data",
|
|
* type="array",
|
|
* @OA\Items(ref="#/components/schemas/HitcountResource")
|
|
* ),
|
|
* @OA\Property(property="links", type="object"),
|
|
* @OA\Property(property="meta", type="object")
|
|
* )
|
|
* ),
|
|
* @OA\Response(response=401, description="Unauthenticated"),
|
|
* @OA\Response(response=403, description="Forbidden (not admin)")
|
|
* )
|
|
*/
|
|
public function index()
|
|
{
|
|
$this->authorize('viewAny', Hitcount::class);
|
|
return HitcountResource::collection(Hitcount::paginate());
|
|
}
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/api/hitcounts/{id}",
|
|
* summary="Get a specific hitcount (only admin)",
|
|
* description="Returns detailed information about a specific hitcount. Requires admin privileges.",
|
|
* operationId="getHitcount",
|
|
* tags={"Hitcounts"},
|
|
* security={{"bearerAuth":{}}},
|
|
* @OA\Parameter(
|
|
* name="id",
|
|
* in="path",
|
|
* required=true,
|
|
* description="Hitcount ID",
|
|
* @OA\Schema(type="integer", example=1)
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Hitcount details",
|
|
* @OA\JsonContent(ref="#/components/schemas/HitcountResource")
|
|
* ),
|
|
* @OA\Response(response=401, description="Unauthenticated"),
|
|
* @OA\Response(response=403, description="Forbidden (not admin)"),
|
|
* @OA\Response(response=404, description="Not Found")
|
|
* )
|
|
*/
|
|
public function show(Hitcount $hitcount)
|
|
{
|
|
$this->authorize('view', $hitcount);
|
|
return new HitcountResource($hitcount);
|
|
}
|
|
|
|
/**
|
|
* @OA\Delete(
|
|
* path="/api/hitcounts/{id}",
|
|
* summary="Delete a hitcount (only admin)",
|
|
* description="Deletes a specific hitcount entry. Requires admin privileges.",
|
|
* operationId="deleteHitcount",
|
|
* tags={"Hitcounts"},
|
|
* security={{"bearerAuth":{}}},
|
|
* @OA\Parameter(
|
|
* name="id",
|
|
* in="path",
|
|
* required=true,
|
|
* description="Hitcount ID to delete",
|
|
* @OA\Schema(type="integer", example=1)
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Hitcount deleted successfully",
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
* @OA\Property(property="message", type="string", example="The hitcount was deleted")
|
|
* )
|
|
* ),
|
|
* @OA\Response(response=401, description="Unauthenticated"),
|
|
* @OA\Response(response=403, description="Forbidden (not admin)"),
|
|
* @OA\Response(response=404, description="Not Found")
|
|
* )
|
|
*/
|
|
public function destroy(Request $request, Hitcount $hitcount)
|
|
{
|
|
$this->authorize('delete', $hitcount);
|
|
$hitcount->delete();
|
|
Log::writeLog("Category '" . $hitcount->id . "' is deleted by " . $request->user()->username);
|
|
return ['message' => 'The hitcount was deleted'];
|
|
}
|
|
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/api/hit",
|
|
* summary="Register a hit for a URL",
|
|
* description="Stores information about a visit, including IP, device, user agent, and country",
|
|
* tags={"Hitcounts"},
|
|
* @OA\RequestBody(
|
|
* required=true,
|
|
* @OA\JsonContent(
|
|
* required={"url"},
|
|
* @OA\Property(property="url", type="string", maxLength=255, example="https://my-application.com")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Hitcount successfully set",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="message", type="string", example="The hitcount is set")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=422,
|
|
* description="Validation error",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="message", type="string", example="The given data was invalid."),
|
|
* @OA\Property(
|
|
* property="errors",
|
|
* type="object",
|
|
* example={"url": {"The url field is required."}}
|
|
* )
|
|
* )
|
|
* )
|
|
* )
|
|
*/
|
|
public function callHit(Request $request)
|
|
{
|
|
$fields = $request->validate([
|
|
'url' => 'required|max:255'
|
|
]);
|
|
$hitcount = new Hitcount();
|
|
$ip = $request->ip();
|
|
$hitcount->ip = $ip;
|
|
$hitcount->user_agent = $request->userAgent();
|
|
$hitcount->url = $fields['url'];
|
|
$detect = new MobileDetect();
|
|
$hitcount->device_type = ($detect->isMobile() ? ($detect->isTablet() ? 'tablet' : 'phone') : 'desktop');
|
|
|
|
$previousHitcount = Hitcount::where('ip', $ip)->first();
|
|
if($previousHitcount) {
|
|
$hitcount->country = $previousHitcount->country;
|
|
}
|
|
else {
|
|
$response = Http::get("http://ip-api.com/json/{$hitcount->ip}?fields=country");
|
|
if ($response->ok()) {
|
|
$hitcount->country = $response->json('country');
|
|
} else {
|
|
$hitcount->country = null;
|
|
}
|
|
}
|
|
|
|
$hitcount->save();
|
|
return ['message' => 'The hitcount is set'];
|
|
}
|
|
}
|