feat(settings): add menu/show_to_user and public get_settings for client apps
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -65,6 +65,14 @@ class DeploySettingsConstCommand extends Command
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$extraPath = database_path('sql/settings_menu_and_show_to_user.sql');
|
||||
if (is_file($extraPath)) {
|
||||
$extraSql = file_get_contents($extraPath);
|
||||
if ($extraSql !== false && trim($extraSql) !== '') {
|
||||
$sql .= "\n".$extraSql;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($databases as $db) {
|
||||
$db = trim((string) $db);
|
||||
if ($db === '') {
|
||||
|
||||
@@ -31,22 +31,37 @@ class SettingsController extends Controller
|
||||
if ($request->boolean('system_only')) {
|
||||
$local = $query->get();
|
||||
|
||||
return response()->json($this->authorizeSettingsPayload(
|
||||
$this->composeSystemSettings($local)
|
||||
));
|
||||
return response()->json($this->composeSystemSettings($local));
|
||||
}
|
||||
|
||||
if ($request->boolean('editable_only')) {
|
||||
$local = $query->get();
|
||||
|
||||
return response()->json($this->authorizeSettingsPayload(
|
||||
$this->composeEditableSettings($local)
|
||||
));
|
||||
return response()->json($this->composeEditableSettings($local));
|
||||
}
|
||||
|
||||
$local = $query->get();
|
||||
|
||||
return response()->json($this->authorizeSettingsPayload($this->composeGetSettings($local)));
|
||||
return response()->json($this->composeGetSettings($local));
|
||||
}
|
||||
|
||||
/**
|
||||
* اپ کاربر (khanegi_user / theme / ghatreh) — فقط ردیفهای show_to_user=1، بدون credential.
|
||||
* پنل ادمین از admin/get_settings استفاده میکند.
|
||||
*/
|
||||
public function publicIndex()
|
||||
{
|
||||
if (! Setting::hasShowToUserColumn()) {
|
||||
return response()->json([]);
|
||||
}
|
||||
|
||||
$local = Setting::query()
|
||||
->select(Setting::adminSelectColumns())
|
||||
->where('show_to_user', 1)
|
||||
->orderBy('key')
|
||||
->get();
|
||||
|
||||
return response()->json(Setting::forClientApi($this->composeGetSettings($local)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,7 +75,7 @@ class SettingsController extends Controller
|
||||
->orderBy('key')
|
||||
->get();
|
||||
|
||||
return response()->json($this->authorizeSettingsPayload($rows));
|
||||
return response()->json($rows);
|
||||
}
|
||||
|
||||
public function edit(Request $request)
|
||||
@@ -174,6 +189,10 @@ class SettingsController extends Controller
|
||||
$saMap = $overlay->catalogMap();
|
||||
|
||||
$byKey = [];
|
||||
$localByKey = [];
|
||||
foreach ($localRows as $row) {
|
||||
$localByKey[(string) $row->key] = $row;
|
||||
}
|
||||
|
||||
if ($saMap !== null) {
|
||||
foreach ($saMap as $key => $item) {
|
||||
@@ -188,7 +207,7 @@ class SettingsController extends Controller
|
||||
}
|
||||
$value = $item['value'] ?? null;
|
||||
if ($value !== null && $value !== '') {
|
||||
$byKey[(string) $key] = $this->overlayRowToSetting($item);
|
||||
$byKey[(string) $key] = $this->overlayRowToSetting($item, $localByKey[(string) $key] ?? null);
|
||||
}
|
||||
}
|
||||
foreach ($localRows as $row) {
|
||||
@@ -246,7 +265,7 @@ class SettingsController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* get_settings اپ/ادمین:
|
||||
* get_settings ادمین (و پایهٔ publicIndex قبل از فیلتر show_to_user):
|
||||
* can_edit=1 (+ runtime) از DB لوکال
|
||||
* can_edit=0 از سوپرادمین؛ اگر کلید در SA نبود یا value خالی بود → کپی لوکال
|
||||
* اگر سوپرادمین در دسترس نباشد کل جدول لوکال برمیگردد.
|
||||
@@ -259,6 +278,11 @@ class SettingsController extends Controller
|
||||
return $localRows;
|
||||
}
|
||||
|
||||
$localByKey = [];
|
||||
foreach ($localRows as $row) {
|
||||
$localByKey[(string) $row->key] = $row;
|
||||
}
|
||||
|
||||
$byKey = [];
|
||||
|
||||
foreach ($localRows as $row) {
|
||||
@@ -285,7 +309,7 @@ class SettingsController extends Controller
|
||||
}
|
||||
$value = $item['value'] ?? null;
|
||||
if ($value !== null && $value !== '') {
|
||||
$byKey[$key] = $this->overlayRowToSetting($item);
|
||||
$byKey[$key] = $this->overlayRowToSetting($item, $localByKey[$key] ?? null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,7 +355,7 @@ class SettingsController extends Controller
|
||||
->values();
|
||||
}
|
||||
|
||||
private function overlayRowToSetting(array $item): Setting
|
||||
private function overlayRowToSetting(array $item, ?Setting $local = null): Setting
|
||||
{
|
||||
$setting = new Setting();
|
||||
$setting->id = isset($item['id']) && is_numeric($item['id']) ? (int) $item['id'] : null;
|
||||
@@ -342,6 +366,14 @@ class SettingsController extends Controller
|
||||
$setting->type = $item['type'] ?? '';
|
||||
$setting->is_active = $item['is_active'] ?? 1;
|
||||
$setting->can_edit = 0;
|
||||
if ($local) {
|
||||
if (Setting::hasMenuColumn()) {
|
||||
$setting->menu = $local->menu;
|
||||
}
|
||||
if (Setting::hasShowToUserColumn()) {
|
||||
$setting->show_to_user = $local->show_to_user;
|
||||
}
|
||||
}
|
||||
|
||||
return $setting;
|
||||
}
|
||||
@@ -359,20 +391,4 @@ class SettingsController extends Controller
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* اپ کاربر (بدون 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);
|
||||
}
|
||||
}
|
||||
|
||||
+71
-12
@@ -14,21 +14,35 @@ class Setting extends Model
|
||||
{
|
||||
use HasFactory,Selector;
|
||||
|
||||
private static ?bool $typeColumnExists = null;
|
||||
/** @var array<string, bool> */
|
||||
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
|
||||
{
|
||||
if (static::$typeColumnExists !== null) {
|
||||
return static::$typeColumnExists;
|
||||
}
|
||||
return static::hasSettingsColumn('type');
|
||||
}
|
||||
|
||||
try {
|
||||
static::$typeColumnExists = Schema::hasColumn((new static)->getTable(), 'type');
|
||||
} catch (\Throwable) {
|
||||
static::$typeColumnExists = false;
|
||||
}
|
||||
public static function hasMenuColumn(): bool
|
||||
{
|
||||
return static::hasSettingsColumn('menu');
|
||||
}
|
||||
|
||||
return static::$typeColumnExists;
|
||||
public static function hasShowToUserColumn(): bool
|
||||
{
|
||||
return static::hasSettingsColumn('show_to_user');
|
||||
}
|
||||
|
||||
/** @return array<int, string> */
|
||||
@@ -38,6 +52,12 @@ class Setting extends Model
|
||||
if (static::hasTypeColumn()) {
|
||||
$cols[] = 'type';
|
||||
}
|
||||
if (static::hasMenuColumn()) {
|
||||
$cols[] = 'menu';
|
||||
}
|
||||
if (static::hasShowToUserColumn()) {
|
||||
$cols[] = 'show_to_user';
|
||||
}
|
||||
|
||||
return $cols;
|
||||
}
|
||||
@@ -90,16 +110,52 @@ class Setting extends Model
|
||||
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<int, array{key: string, value: mixed, is_active: mixed}>
|
||||
*/
|
||||
public static function forClientApi($settings)
|
||||
{
|
||||
return collect($settings)
|
||||
->filter(fn ($row) => ! static::isSecretOrServerOnlyKey((string) (is_array($row) ? ($row['key'] ?? '') : ($row->key ?? ''))))
|
||||
->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();
|
||||
}
|
||||
|
||||
@@ -112,9 +168,12 @@ class Setting extends Model
|
||||
'value_json',
|
||||
'type',
|
||||
'can_edit',
|
||||
'menu',
|
||||
'show_to_user',
|
||||
];
|
||||
protected $casts = [
|
||||
'value_json'=>'array',
|
||||
'is_active'=>'boolean',
|
||||
'show_to_user'=>'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (! Schema::hasTable('settings')) {
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::table('settings', function (Blueprint $table) {
|
||||
if (! Schema::hasColumn('settings', 'menu')) {
|
||||
$table->string('menu', 64)->nullable()->after('can_edit');
|
||||
}
|
||||
if (! Schema::hasColumn('settings', 'show_to_user')) {
|
||||
$table->boolean('show_to_user')->default(false)->after('menu');
|
||||
}
|
||||
});
|
||||
|
||||
$path = database_path('sql/settings_menu_and_show_to_user.sql');
|
||||
if (is_file($path)) {
|
||||
DB::unprepared((string) file_get_contents($path));
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if (! Schema::hasTable('settings')) {
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::table('settings', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('settings', 'show_to_user')) {
|
||||
$table->dropColumn('show_to_user');
|
||||
}
|
||||
if (Schema::hasColumn('settings', 'menu')) {
|
||||
$table->dropColumn('menu');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -708,6 +708,8 @@ CREATE TABLE `settings` (
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
`is_active` tinyint DEFAULT NULL,
|
||||
`type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`menu` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`show_to_user` tinyint(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
-- اصول:
|
||||
-- • چند بار قابل اجرا (idempotent)
|
||||
-- • value / is_active ردیفهای موجود هرگز دست نخورده — فقط INSERT برای کلید جدید
|
||||
-- • can_edit / title_fa / description / type هر deploy از این فایل بهروز میشوند
|
||||
-- • can_edit / title_fa / description / type / menu / show_to_user هر deploy از این فایل بهروز میشوند
|
||||
-- • menu و show_to_user: database/sql/settings_menu_and_show_to_user.sql (settings:deploy و migrate اضافه میکنند)
|
||||
-- • کلیدهای can_edit=0 (سوپرادمین) در این فایل کامنت شدهاند — مالکیت: SuperAdminProgramSettingsOverlay
|
||||
-- • schema (جدول/ستون) فقط با migrate — نه این فایل
|
||||
--
|
||||
@@ -2435,6 +2436,9 @@ COMMIT;
|
||||
|
||||
SELECT 'deploy_settings_const.sql finished' AS status;
|
||||
|
||||
-- menu / show_to_user: php artisan settings:deploy و migrate فایل
|
||||
-- database/sql/settings_menu_and_show_to_user.sql را بعد از این اجرا میکنند.
|
||||
|
||||
-- بررسی fee_deduct_from_gold (desc_preview باید با «مشتری دقیقاً» شروع شود):
|
||||
SELECT `key`, `title_fa`, LEFT(`description`, 60) AS desc_preview, `can_edit`, `type`, `value`
|
||||
FROM `settings`
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
-- menu + show_to_user روی settings (متادیتا؛ value دست نخورده)
|
||||
-- از migrate و php artisan settings:deploy اجرا میشود.
|
||||
|
||||
SET @db = DATABASE();
|
||||
|
||||
SET @sql = IF(
|
||||
(SELECT COUNT(*) FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'settings' AND COLUMN_NAME = 'menu') = 0,
|
||||
'ALTER TABLE `settings` ADD COLUMN `menu` VARCHAR(64) NULL DEFAULT NULL',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = IF(
|
||||
(SELECT COUNT(*) FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'settings' AND COLUMN_NAME = 'show_to_user') = 0,
|
||||
'ALTER TABLE `settings` ADD COLUMN `show_to_user` TINYINT(1) NOT NULL DEFAULT 0',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
UPDATE `settings` SET `menu` = CASE
|
||||
WHEN `key` IN (
|
||||
'close_price', 'startDay', 'endDay', 'show_last_price',
|
||||
'show_home_price_when_closed', 'show_gold_ounce_price', 'trading_hours_by_day'
|
||||
) THEN 'trading_hours'
|
||||
WHEN `key` = 'tracking_systems' THEN 'capture_sites'
|
||||
WHEN `key` LIKE 'chat_%' THEN 'support_chat'
|
||||
WHEN `key` LIKE 'deposit_method_%'
|
||||
OR `key` IN (
|
||||
'deposit_account_holder', 'deposit_card_number', 'deposit_account_number',
|
||||
'deposit_sheba', 'deposit_bank_name'
|
||||
) THEN 'deposit_methods'
|
||||
WHEN `key` LIKE 'support_messenger%'
|
||||
OR `key` IN ('deposit_sms_support_number', 'deposit_support_message_text') THEN 'support'
|
||||
WHEN `key` LIKE 'zarin_%' THEN 'accounting_zarin'
|
||||
WHEN `key` LIKE 'tahesab_%' OR `key` = 'send_to_tahesab' THEN 'accounting_tahesab'
|
||||
WHEN `key` LIKE 'pargar_%' OR `key` = 'send_to_pargar' THEN 'accounting_pargar'
|
||||
WHEN `key` = 'accounting_provider' THEN 'accounting_provider'
|
||||
WHEN `key` LIKE 'payping_%' THEN 'payping'
|
||||
WHEN `key` LIKE 'external_payment_%' OR `key` = 'wallet_payment_provider' THEN 'deposit_methods'
|
||||
WHEN `key` LIKE 'montzar_%' OR `key` = 'display_montzar' THEN 'montzar'
|
||||
WHEN `key` LIKE 'sms_notif_%'
|
||||
OR `key` IN ('charge_notif', 'register_referral_sms_to_referrer') THEN 'notifications'
|
||||
WHEN `key` LIKE 'price_channel_%' OR `key` = 'change_mesghal' THEN 'price_channel'
|
||||
WHEN `key` LIKE 'telegram_bot%' OR `key` LIKE 'bale_bot%' OR `key` LIKE 'rubika_bot%' THEN 'bots'
|
||||
WHEN `key` LIKE 'referral_%'
|
||||
OR `key` IN ('invite_link_text', 'gift_for', 'register_referral', 'referral_bonus_amount') THEN 'referral'
|
||||
WHEN `key` LIKE 'text_%' OR `key` IN ('enamad_url', 'about_software') THEN 'content'
|
||||
WHEN `key` LIKE 'min_%' OR `key` LIKE 'minimum_%' OR `key` LIKE 'balance_report_exclude%' THEN 'limits'
|
||||
WHEN `key` LIKE 'zaarbox_%' OR `key` IN ('price_provider', 'main_product') THEN 'price_source'
|
||||
WHEN `key` LIKE 'node_%' OR `key` IN ('montify_name', 'external_order_api_enabled') THEN 'store'
|
||||
WHEN `key` LIKE 'chart_%' THEN 'chart'
|
||||
WHEN `key` IN ('wss_enabled', 'sse_path', 'wss_path', 'profit_gold_api_enabled') THEN 'infra'
|
||||
WHEN `key` LIKE 'fee_%'
|
||||
OR `key` IN ('buy_fee', 'sell_fee', 'up_price', 'down_price', 'price_extreme_date')
|
||||
OR `key` LIKE '%charge_percentage%' THEN 'fees'
|
||||
WHEN `key` LIKE 'product_%'
|
||||
OR `key` IN ('main_wallet_products', 'require_zero_main_gold_before_other_buy')
|
||||
OR `key` LIKE 'profit_gold%' THEN 'features'
|
||||
WHEN `key` IN (
|
||||
'banner_enabled', 'tracking_systems_enabled', 'jibit_verification', 'register_jibit_verify',
|
||||
'show_product_details', 'show_product_trade_status', 'show_product_card_meta',
|
||||
'products_site_link_enabled', 'products_site_link_url', 'products_site_link_text', 'has_chat',
|
||||
'enable_conditional_order', 'enable_product_funds', 'has_page_price_trigger', 'has_page_notification',
|
||||
'has_page_gift_card', 'enable_customer_level_profit', 'jibit_enabled', 'customer_direct_sms',
|
||||
'has_page_earn_money', 'group_sms', 'customer_special_pricing', 'permision__enabled', 'show_to_users_chat'
|
||||
) THEN 'customer_features'
|
||||
WHEN `key` LIKE 'logo_%'
|
||||
OR `key` IN (
|
||||
'name_fa', 'name_en', 'app_url', 'admin_url', 'apk_download_link', 'bace_url', 'server_url',
|
||||
'title_pwa', 'title_fav', 'metal_type', 'main_metal', 'unit', 'open_register', 'auto_active_customer',
|
||||
'store_status', 'key', 'is_store', 'sms_panel'
|
||||
) THEN 'general'
|
||||
ELSE 'misc'
|
||||
END;
|
||||
|
||||
UPDATE `settings` SET `show_to_user` = 0;
|
||||
|
||||
UPDATE `settings` SET `show_to_user` = 1 WHERE `key` IN (
|
||||
'apk_download_link',
|
||||
'app_url',
|
||||
'banner_enabled',
|
||||
'chat_api',
|
||||
'chat_download_url',
|
||||
'chat_upload_url',
|
||||
'close_price',
|
||||
'deposit_account_holder',
|
||||
'deposit_account_number',
|
||||
'deposit_bank_name',
|
||||
'deposit_card_number',
|
||||
'deposit_method_card_to_card',
|
||||
'deposit_method_gateway',
|
||||
'deposit_method_identified',
|
||||
'deposit_method_shetab',
|
||||
'deposit_sheba',
|
||||
'deposit_sms_support_number',
|
||||
'deposit_support_message_text',
|
||||
'enable_conditional_order',
|
||||
'enable_product_funds',
|
||||
'endDay',
|
||||
'fee_conditional_order',
|
||||
'fee_deduct_from_gold',
|
||||
'fee_service_charge_percentage',
|
||||
'has_chat',
|
||||
'has_page_gift_card',
|
||||
'has_page_notification',
|
||||
'has_page_price_trigger',
|
||||
'invite_link_text',
|
||||
'main_product',
|
||||
'main_wallet_products',
|
||||
'metal_type',
|
||||
'min_deposit',
|
||||
'min_withdraw',
|
||||
'open_register',
|
||||
'permision__enabled',
|
||||
'products_site_link_enabled',
|
||||
'products_site_link_text',
|
||||
'products_site_link_url',
|
||||
'referral_id',
|
||||
'referral_show',
|
||||
'show_gold_ounce_price',
|
||||
'show_home_price_when_closed',
|
||||
'show_product_card_meta',
|
||||
'show_product_details',
|
||||
'show_product_trade_status',
|
||||
'show_to_users_chat',
|
||||
'sse_path',
|
||||
'startDay',
|
||||
'support_messenger',
|
||||
'support_messenger_id',
|
||||
'support_messenger_text',
|
||||
'support_messengers',
|
||||
'text_about',
|
||||
'text_rule',
|
||||
'tracking_systems',
|
||||
'tracking_systems_enabled',
|
||||
'unit',
|
||||
'wss_enabled',
|
||||
'wss_path',
|
||||
'zaarbox_api_url'
|
||||
);
|
||||
@@ -59,9 +59,9 @@ Montify → payment_url → درگاه بانکی
|
||||
|
||||
### ۳.۲. فیلتر `get_settings`
|
||||
|
||||
در `App\Models\Setting::isSecretOrServerOnlyKey()` و `SettingsController::authorizeSettingsPayload()`:
|
||||
در `App\Models\Setting::isSecretOrServerOnlyKey()` و `Setting::forClientApi()`:
|
||||
|
||||
- درخواست عمومی (`api/get_settings` بدون auth ادمین) → کلیدهای محرمانه حذف میشوند.
|
||||
- درخواست عمومی (`api/get_settings` بدون auth) → فقط ردیفهای `show_to_user=1`؛ credential حذف میشود.
|
||||
- پنل ادمین (`admin/get_settings` با `auth:user`) → همه کلیدها قابل مشاهده/ویرایش طبق `can_edit`.
|
||||
|
||||
کلیدهای مرتبط با پرداخت که به اپ عمومی نمیروند شامل:
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ Route::post('price_triggers/table', [PriceTriggerController::class, 'table']);
|
||||
Route::get('/city/state',[CityController::class, 'stateList']);
|
||||
Route::get('/city/all',[CityController::class, 'cityListAll']);
|
||||
Route::get('/city/{state_id}',[CityController::class, 'cityList']);
|
||||
Route::get('get_settings',[SettingsController::class, 'index']);
|
||||
Route::get('get_settings', [SettingsController::class, 'publicIndex']);
|
||||
|
||||
// وبهوک سرور چت → اعلان SMS اولین پیام خواندهنشده پشتیبانی
|
||||
Route::post('/chat/support-message-notify', [SupportChatNotifyController::class, 'notify']);
|
||||
|
||||
Reference in New Issue
Block a user