*/ private static array $columnExists = []; public static function hasSettingsColumn(string $column): bool { if (! isset(static::$columnExists[$column])) { try { static::$columnExists[$column] = Schema::hasColumn((new static)->getTable(), $column); } catch (\Throwable) { static::$columnExists[$column] = false; } } return static::$columnExists[$column]; } public static function hasTypeColumn(): bool { return static::hasSettingsColumn('type'); } public static function hasMenuColumn(): bool { return static::hasSettingsColumn('menu'); } public static function hasShowToUserColumn(): bool { return static::hasSettingsColumn('show_to_user'); } /** @return array */ public static function adminSelectColumns(): array { $cols = ['id', 'title_fa', 'key', 'value', 'description', 'is_active', 'can_edit']; if (static::hasTypeColumn()) { $cols[] = 'type'; } if (static::hasMenuColumn()) { $cols[] = 'menu'; } if (static::hasShowToUserColumn()) { $cols[] = 'show_to_user'; } return $cols; } /** * کلیدهایی که هرگز نباید در پاسخ عمومی api/get_settings برگردند. * credential درگاه، توکن‌ها، رمزها و پیکربندی داخلی پرداخت. */ public static function isSecretOrServerOnlyKey(string $key): bool { $key = strtolower(trim($key)); if ($key === '') { return false; } // کل گروه پیکربندی پرداخت آنلاین — فقط سرور / ادمین if ( str_starts_with($key, 'external_payment_') || $key === 'wallet_payment_provider' || str_starts_with($key, 'payping_') ) { return true; } $exact = [ 'node_client_id', 'node_shared_secret', 'montzar_password', 'montzar_token', 'montzar_mobile', 'bale_bot_token', 'telegram_bot_token', 'rubika_bot_token', 'tahesab_token', 'tahesab_host', 'tahesab_port', 'tahesab_db', 'pargar_password', 'pargar_api_token', 'pargar_username', 'zarin_api', 'zarin_token', 'chat_webhook_secret', 'chat_webhook_base_url', ]; if (in_array($key, $exact, true)) { return true; } return (bool) preg_match('/(^|_)(secret|password|token|api_key|apikey|private)(_|$)/', $key); } public static function isShownToUserApp($row): bool { $key = (string) (is_array($row) ? ($row['key'] ?? '') : ($row->key ?? '')); if ($key === '' || static::isSecretOrServerOnlyKey($key)) { return false; } $flag = is_array($row) ? ($row['show_to_user'] ?? 0) : ($row->show_to_user ?? 0); return $flag === true || $flag === 1 || $flag === '1'; } /** * فیلتر تنظیمات برای پاسخ عمومی (اپ کاربر) — ستون show_to_user، بدون secret. * * @param \Illuminate\Support\Collection|iterable $settings * @return \Illuminate\Support\Collection */ public static function forPublicApi($settings) { return static::forClientApi($settings); } /** * @param \Illuminate\Support\Collection|iterable $settings * @return \Illuminate\Support\Collection */ public static function forClientApi($settings) { return collect($settings) ->filter(fn ($row) => static::isShownToUserApp($row)) ->map(function ($row) { if (is_array($row)) { return [ 'key' => (string) ($row['key'] ?? ''), 'value' => $row['value'] ?? '', 'is_active' => $row['is_active'] ?? 1, ]; } return [ 'key' => (string) ($row->key ?? ''), 'value' => $row->value ?? '', 'is_active' => $row->is_active ?? 1, ]; }) ->values(); } protected $fillable = [ 'key', 'title_fa', 'is_active', 'description', 'value', 'value_json', 'type', 'can_edit', 'menu', 'show_to_user', ]; protected $casts = [ 'value_json'=>'array', 'is_active'=>'boolean', 'show_to_user'=>'boolean', ]; }