From 341b2da2c9f75199f844544d4aa79b684f5d4990 Mon Sep 17 00:00:00 2001 From: adonis Date: Tue, 18 Aug 2026 18:52:29 +0330 Subject: [PATCH] feat(server): expose settings table API and compose get_settings from SA locks plus local edits Co-authored-by: Cursor --- .../Controllers/Admin/SettingsController.php | 97 ++++++++++++------- .../SuperAdminProgramSettingsOverlay.php | 5 + routes/admin.php | 1 + 3 files changed, 66 insertions(+), 37 deletions(-) diff --git a/app/Http/Controllers/Admin/SettingsController.php b/app/Http/Controllers/Admin/SettingsController.php index 17e739b..38c4dd0 100644 --- a/app/Http/Controllers/Admin/SettingsController.php +++ b/app/Http/Controllers/Admin/SettingsController.php @@ -28,10 +28,8 @@ class SettingsController extends Controller ->select(Setting::adminSelectColumns()) ->orderBy('key'); - $skipOverlay = $request->boolean('skip_overlay'); - if ($request->boolean('system_only')) { - if (! $skipOverlay) { + if (! $request->boolean('skip_overlay')) { $overlay = app(SuperAdminProgramSettingsOverlay::class)->items(); if ($overlay) { return response()->json($this->authorizeSettingsPayload($this->overlayToRows($overlay))); @@ -40,7 +38,7 @@ class SettingsController extends Controller $rows = $query ->where(function ($q) { - $q->where('can_edit', 0)->orWhere('can_edit', false); + $q->where('can_edit', 0)->orWhere('can_edit', false)->orWhere('can_edit', '0'); }) ->where(function ($q) { $q->where('is_active', 1) @@ -53,17 +51,30 @@ class SettingsController extends Controller } if ($request->boolean('editable_only')) { - return response()->json($this->authorizeSettingsPayload($query->where('can_edit', 1)->get())); + return response()->json($this->authorizeSettingsPayload( + $query->where(function ($q) { + $q->where('can_edit', 1)->orWhere('can_edit', true)->orWhere('can_edit', '1'); + })->get() + )); } $local = $query->get(); - if ($skipOverlay) { - return response()->json($this->authorizeSettingsPayload($local)); - } - return response()->json($this->authorizeSettingsPayload( - $this->mergeOverlayIntoLocal($local) - )); + return response()->json($this->authorizeSettingsPayload($this->composeGetSettings($local))); + } + + /** + * جدول settings همین نسخه — بدون overlay سوپرادمین. + * سوپرادمین برای ایمپورت از این مسیر can_edit=0 را برمی‌دارد. + */ + public function localTable() + { + $rows = Setting::query() + ->select(Setting::adminSelectColumns()) + ->orderBy('key') + ->get(); + + return response()->json($this->authorizeSettingsPayload($rows)); } public function edit(Request $request) @@ -152,43 +163,55 @@ class SettingsController extends Controller return in_array($key, self::PANEL_MANAGED_KEYS, true); } - private function mergeOverlayIntoLocal($rows) + /** + * get_settings: کلیدهای سوپرادمین (can_edit=0) + ردیف‌های جدول لوکال با can_edit=1. + * اگر سوپرادمین در دسترس نباشد کل جدول لوکال برمی‌گردد. + * کلیدهای runtime / متعلق به پنل خانگی همیشه از جدول لوکال می‌آیند. + */ + private function composeGetSettings($localRows) { - $overlay = app(SuperAdminProgramSettingsOverlay::class)->items(); - if (! $overlay) { - return $rows; + $overlay = app(SuperAdminProgramSettingsOverlay::class); + $saMap = $overlay->map(); + if ($saMap === null) { + return $localRows; } $byKey = []; - foreach ($rows as $row) { - $byKey[(string) $row->key] = $row; + + foreach ($localRows as $row) { + if ($this->isEditableCanEdit($row->can_edit ?? null)) { + $byKey[(string) $row->key] = $row; + } } - foreach ($overlay as $item) { - $key = trim((string) ($item['key'] ?? '')); - if ($key === '' || SuperAdminProgramSettingsOverlay::isLocalOwned($key)) { + foreach ($saMap as $key => $item) { + if (! is_array($item)) { continue; } - if (isset($byKey[$key])) { - $byKey[$key]->value = $item['value'] ?? $byKey[$key]->value; - if (array_key_exists('title_fa', $item) && $item['title_fa'] !== null && $item['title_fa'] !== '') { - $byKey[$key]->title_fa = $item['title_fa']; - } - if (array_key_exists('description', $item) && $item['description'] !== null) { - $byKey[$key]->description = $item['description']; - } - if (array_key_exists('type', $item) && $item['type'] !== null && $item['type'] !== '') { - $byKey[$key]->type = $item['type']; - } - if (array_key_exists('is_active', $item)) { - $byKey[$key]->is_active = $item['is_active']; - } - } else { - $byKey[$key] = $this->overlayRowToSetting($item); + $byKey[(string) $key] = $this->overlayRowToSetting($item); + } + + foreach ($localRows as $row) { + $key = (string) $row->key; + if ( + SuperAdminProgramSettingsOverlay::isLocalOwned($key) + || SuperAdminProgramSettingsOverlay::isRuntime($key) + ) { + $byKey[$key] = $row; } } - return collect(array_values($byKey)); + return collect(array_values($byKey))->sortBy(fn ($row) => (string) ($row->key ?? ''))->values(); + } + + private function isEditableCanEdit(mixed $canEdit): bool + { + return $canEdit === 1 || $canEdit === true || $canEdit === '1'; + } + + private function mergeOverlayIntoLocal($rows) + { + return $this->composeGetSettings($rows); } /** diff --git a/app/Services/SuperAdminProgramSettingsOverlay.php b/app/Services/SuperAdminProgramSettingsOverlay.php index 375b8c0..4abb73a 100644 --- a/app/Services/SuperAdminProgramSettingsOverlay.php +++ b/app/Services/SuperAdminProgramSettingsOverlay.php @@ -100,6 +100,11 @@ class SuperAdminProgramSettingsOverlay return $map[$key]; } + public static function isRuntime(string $key): bool + { + return in_array($key, self::RUNTIME_KEYS, true); + } + public static function isLocalOwned(string $key): bool { return in_array($key, self::LOCAL_OWNED_KEYS, true); diff --git a/routes/admin.php b/routes/admin.php index 496fb98..3dde05c 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -39,6 +39,7 @@ Route::middleware('auth:user')->group(function (){ //settigs Route::get('get_settings',[SettingsController::class, 'index']); Route::post('get_settings',[SettingsController::class, 'edit']); + Route::get('settings/table',[SettingsController::class, 'localTable']); //------------balence Route::post('getBalance', [DashboardController::class, 'getBalance']);