select(Setting::adminSelectColumns()) ->orderBy('key'); if ($request->boolean('system_only')) { $overlay = app(SuperAdminProgramSettingsOverlay::class)->items(); if ($overlay) { return response()->json($this->authorizeSettingsPayload($this->overlayToRows($overlay))); } $rows = $query ->where(function ($q) { $q->where('can_edit', 0)->orWhere('can_edit', false); }) ->where(function ($q) { $q->where('is_active', 1) ->orWhere('is_active', true) ->orWhere('is_active', '1'); }) ->get(); return response()->json($this->authorizeSettingsPayload($rows)); } if ($request->boolean('editable_only')) { return response()->json($this->authorizeSettingsPayload($query->where('can_edit', 1)->get())); } return response()->json($this->authorizeSettingsPayload( $this->mergeOverlayIntoLocal($query->get()) )); } public function edit(Request $request) { $setting = Setting::where('key', $request->key)->first(); $isNew = !$setting; if ($isNew) { if ($request->boolean('system_deploy')) { return response()->json([ 'message' => 'تنظیمات پیشرفته فقط از سوپرادمین اضافه می‌شوند', ], 403); } $setting = new Setting(); $setting->key = $request->key; $setting->can_edit = 1; } elseif (!$setting->can_edit && !$this->isPanelManagedKey((string) $request->key)) { return response()->json([ 'message' => 'این تنظیم از سوپرادمین کنترل می‌شود و در پنل خانگی قابل ویرایش نیست', ], 403); } $previousValue = $setting->exists ? (string) ($setting->value ?? '') : null; $setting->value = $request->value; $setting->description = $request->description; if ($request->has('is_active')) { $setting->is_active = filter_var($request->is_active, FILTER_VALIDATE_BOOLEAN) ? 1 : 0; } elseif ($isNew) { $setting->is_active = 1; } $setting->title_fa = $request->title_fa ?? ''; if (Setting::hasTypeColumn()) { $setting->type = $request->type ?? ''; } $setting->save(); if ( $request->key === 'price_channel_message_text' && $previousValue !== (string) ($request->value ?? '') ) { dispatch(function () { app(PriceChannelBroadcastService::class)->broadcastAfterTemplateChange(); })->afterResponse(); } if ($isNew) { $projectName = Setting::where('key', 'name_fa')->value('value') ?: 'پروژه'; $settingTitle = trim($request->title_fa ?? '') ?: $request->key; $this->Send( self::NEW_SETTING_NOTIFY_MOBILE, "تنظیم جدید: {$settingTitle}\nپروژه: {$projectName}", false ); } return response()->json($setting); } private function normalizeAdminMobile(?string $mobile): string { $digits = preg_replace('/\D+/', '', (string) $mobile) ?? ''; if (str_starts_with($digits, '98') && strlen($digits) >= 12) { $digits = substr($digits, 2); } if (strlen($digits) === 11 && str_starts_with($digits, '0')) { $digits = substr($digits, 1); } return $digits; } private function isDeployAdminUser(): bool { $user = auth('user')->user() ?? auth()->user(); if (!$user) { return false; } return $this->normalizeAdminMobile($user->mobile ?? '') === self::DEPLOY_ADMIN_MOBILE_SUFFIX; } private function isPanelManagedKey(string $key): bool { return in_array($key, self::PANEL_MANAGED_KEYS, true); } private function mergeOverlayIntoLocal($rows) { $overlay = app(SuperAdminProgramSettingsOverlay::class)->items(); if (! $overlay) { return $rows; } $byKey = []; foreach ($rows as $row) { $byKey[(string) $row->key] = $row; } foreach ($overlay as $item) { $key = trim((string) ($item['key'] ?? '')); if ($key === '' || SuperAdminProgramSettingsOverlay::isLocalOwned($key)) { 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); } } return collect(array_values($byKey)); } /** * @param array> $overlay */ private function overlayToRows(array $overlay) { return collect($overlay) ->filter(fn ($item) => is_array($item) && trim((string) ($item['key'] ?? '')) !== '') ->map(fn ($item) => $this->overlayRowToSetting($item)) ->values(); } private function overlayRowToSetting(array $item): Setting { $setting = new Setting(); $setting->id = isset($item['id']) && is_numeric($item['id']) ? (int) $item['id'] : null; $setting->key = (string) ($item['key'] ?? ''); $setting->value = $item['value'] ?? ''; $setting->title_fa = $item['title_fa'] ?? ''; $setting->description = $item['description'] ?? ''; $setting->type = $item['type'] ?? ''; $setting->is_active = $item['is_active'] ?? 1; $setting->can_edit = 0; return $setting; } /** * اپ کاربر (بدون auth ادمین) هرگز secret/credential نمی‌بیند. * پنل ادمین با auth:user همه کلیدها را می‌بیند. * * @param \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Collection|iterable $rows * @return \Illuminate\Support\Collection */ private function authorizeSettingsPayload($rows) { if (auth('user')->check()) { return collect($rows)->values(); } return Setting::forPublicApi($rows); } }