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']; } }