157 lines
5.9 KiB
PHP
157 lines
5.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Http\Controllers\Concerns\ProxiesBackend;
|
|
use App\Services\BackendHttpClient;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Validation\Rule;
|
|
|
|
class BonusApiController extends Controller
|
|
{
|
|
use ProxiesBackend;
|
|
|
|
public function __construct(private readonly BackendHttpClient $client)
|
|
{
|
|
// Inline token check middleware (no alias registration needed)
|
|
$this->middleware(function ($request, $next) {
|
|
$provided = $this->extractToken($request);
|
|
$expected = config('services.bonus_api.token');
|
|
|
|
if (!$expected || !hash_equals((string) $expected, (string) $provided)) {
|
|
return response()->json(['message' => 'Unauthorized'], 401);
|
|
}
|
|
|
|
return $next($request);
|
|
});
|
|
}
|
|
|
|
private function extractToken(Request $request): ?string
|
|
{
|
|
$auth = $request->header('Authorization');
|
|
if ($auth && str_starts_with($auth, 'Bearer ')) {
|
|
return substr($auth, 7);
|
|
}
|
|
return $request->query('api_token'); // fallback: allow ?api_token=
|
|
}
|
|
|
|
public function index(Request $request)
|
|
{
|
|
try {
|
|
$query = [];
|
|
if ($status = $request->query('status')) {
|
|
$query['status'] = $status;
|
|
}
|
|
if ($request->boolean('active_only')) {
|
|
$query['active_only'] = 1;
|
|
}
|
|
$query['per_page'] = min(200, max(1, (int) $request->query('per_page', 50)));
|
|
|
|
$res = $this->client->get($request, '/bonuses', $query, retry: true);
|
|
if ($res->successful()) {
|
|
return response()->json($res->json() ?: []);
|
|
}
|
|
if ($res->clientError()) return $this->mapClientError($res);
|
|
if ($res->serverError()) return $this->mapServiceUnavailable($res);
|
|
return $this->mapBadGateway();
|
|
} catch (\Throwable $e) {
|
|
return $this->mapBadGateway('API server not reachable');
|
|
}
|
|
}
|
|
|
|
public function show(Request $request, int $id)
|
|
{
|
|
try {
|
|
$res = $this->client->get($request, "/bonuses/{$id}", [], retry: true);
|
|
if ($res->successful()) {
|
|
return response()->json($res->json() ?: []);
|
|
}
|
|
if ($res->clientError()) return $this->mapClientError($res);
|
|
if ($res->serverError()) return $this->mapServiceUnavailable($res);
|
|
return $this->mapBadGateway();
|
|
} catch (\Throwable $e) {
|
|
return $this->mapBadGateway('API server not reachable');
|
|
}
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$data = $this->validateData($request);
|
|
try {
|
|
$res = $this->client->post($request, '/bonuses', $data);
|
|
if ($res->successful()) {
|
|
return response()->json($res->json() ?: [], 201);
|
|
}
|
|
if ($res->clientError()) return $this->mapClientError($res);
|
|
if ($res->serverError()) return $this->mapServiceUnavailable($res);
|
|
return $this->mapBadGateway();
|
|
} catch (\Throwable $e) {
|
|
return $this->mapBadGateway('API server not reachable');
|
|
}
|
|
}
|
|
|
|
public function update(Request $request, int $id)
|
|
{
|
|
$data = $this->validateData($request, partial: true);
|
|
try {
|
|
$res = $this->client->patch($request, "/bonuses/{$id}", $data);
|
|
if ($res->successful()) {
|
|
return response()->json($res->json() ?: []);
|
|
}
|
|
if ($res->clientError()) return $this->mapClientError($res);
|
|
if ($res->serverError()) return $this->mapServiceUnavailable($res);
|
|
return $this->mapBadGateway();
|
|
} catch (\Throwable $e) {
|
|
return $this->mapBadGateway('API server not reachable');
|
|
}
|
|
}
|
|
|
|
public function destroy(Request $request, int $id)
|
|
{
|
|
try {
|
|
$res = $this->client->delete($request, "/bonuses/{$id}");
|
|
if ($res->successful()) {
|
|
$body = $res->json();
|
|
return response()->json($body ?: ['message' => 'Deleted']);
|
|
}
|
|
if ($res->clientError()) return $this->mapClientError($res);
|
|
if ($res->serverError()) return $this->mapServiceUnavailable($res);
|
|
return $this->mapBadGateway();
|
|
} catch (\Throwable $e) {
|
|
return $this->mapBadGateway('API server not reachable');
|
|
}
|
|
}
|
|
|
|
private function validateData(Request $request, bool $partial = false): array
|
|
{
|
|
$required = $partial ? 'sometimes' : 'required';
|
|
|
|
$rules = [
|
|
'title' => [$required, 'string', 'max:255'],
|
|
'type' => ['sometimes', 'nullable', 'string', 'max:64'],
|
|
'amount_value' => ['sometimes', 'nullable', 'numeric'],
|
|
'amount_unit' => ['sometimes', 'nullable', Rule::in(['USD','EUR','BTC','ETH','PERCENT','SPINS'])],
|
|
'min_deposit' => ['sometimes', 'nullable', 'numeric', 'min:0'],
|
|
'max_amount' => ['sometimes', 'nullable', 'numeric', 'min:0'],
|
|
'currency' => ['sometimes', 'nullable', 'string', 'max:16'],
|
|
'code' => ['sometimes', 'nullable', 'string', 'max:64'],
|
|
'status' => ['sometimes', 'required', Rule::in(['draft','active','paused','expired'])],
|
|
'starts_at' => ['sometimes', 'nullable', 'date'],
|
|
'expires_at' => ['sometimes', 'nullable', 'date', 'after_or_equal:starts_at'],
|
|
'rules' => ['sometimes', 'nullable', 'array'],
|
|
'description' => ['sometimes', 'nullable', 'string'],
|
|
];
|
|
|
|
$validated = $request->validate($rules);
|
|
|
|
// Normalize empty strings to null
|
|
foreach (['type','amount_unit','currency','code','description'] as $k) {
|
|
if (array_key_exists($k, $validated) && $validated[$k] === '') {
|
|
$validated[$k] = null;
|
|
}
|
|
}
|
|
|
|
return $validated;
|
|
}
|
|
}
|