'integrations']); if (isset($_POST['wablas_send_test'])) { $defaultCountryCode = (string) (wablasSettingValue('wablas_default_country_code', '') ?? ''); $numbers = wablasNumbersFromText((string) ($_POST['wablas_test_numbers'] ?? ''), $defaultCountryCode); $message = substr(trim(str_replace(["\r\n", "\r"], "\n", (string) ($_POST['wablas_test_message'] ?? ''))), 0, 3000); if ($numbers === []) { redirectWithMessage('Error: Add at least one valid WhatsApp number for the test send.', $wablasSettingsUrl); } if ($message === '') { redirectWithMessage('Error: Enter a test WhatsApp message before sending.', $wablasSettingsUrl); } $result = wablasSendManualTest($numbers, $message); if (!empty($result['success'])) { $messageText = 'Wablas test message sent to ' . count($numbers) . ' recipient(s).'; if (!empty($result['log_id'])) { $messageText .= ' It was also added to System Logs.'; } redirectWithMessage($messageText, $wablasSettingsUrl); } $errorText = trim((string) ($result['error'] ?? 'Wablas test send failed.')); redirectWithMessage('Error: ' . $errorText, $wablasSettingsUrl); } if (isset($_POST['wablas_run_due_now'])) { $dailyQueue = wablasQueueDailySummaryIfDue(wablasNow()); $processed = wablasProcessDueDispatches(25); $parts = []; if (!empty($dailyQueue['queued'])) { $parts[] = 'Daily summary queued.'; } elseif (($dailyQueue['reason'] ?? '') === 'already_exists') { $parts[] = "Today's daily summary already exists."; } elseif (($dailyQueue['reason'] ?? '') === 'not_due') { $parts[] = 'Daily summary is not due yet.'; } elseif (($dailyQueue['reason'] ?? '') === 'no_recipients') { $parts[] = 'Daily summary recipients are not configured.'; } elseif (($dailyQueue['reason'] ?? '') === 'disabled') { $parts[] = 'Daily summary automation is disabled.'; } elseif (!empty($dailyQueue['error'])) { $parts[] = 'Error: ' . (string) $dailyQueue['error']; } $parts[] = 'Queue run checked ' . (int) ($processed['checked'] ?? 0) . ' job(s), sent ' . (int) ($processed['sent'] ?? 0) . ', failed ' . (int) ($processed['failed'] ?? 0) . ', skipped ' . (int) ($processed['skipped'] ?? 0) . '.'; if (!empty($processed['messages'][0])) { $parts[] = (string) $processed['messages'][0]; } redirectWithMessage(implode(' ', array_filter($parts)), $wablasSettingsUrl); } } } if (isset($_POST['update_settings'])) { if (can('settings_view')) { $db = db(); $settings = isset($_POST['settings']) && is_array($_POST['settings']) ? $_POST['settings'] : []; $textLimits = [ 'company_name' => 190, 'ctr_no' => 120, 'vat_number' => 120, 'company_phone' => 60, 'company_email' => 190, 'company_address' => 500, 'license_app_name' => 190, 'smtp_host' => 190, 'smtp_user' => 190, 'smtp_pass' => 255, 'smtp_from_email' => 190, 'smtp_from_name' => 190, 'smtp_reply_to' => 190, 'wablas_api_url' => 255, 'wablas_token' => 500, 'wablas_security_key' => 500, 'wablas_sender' => 190, 'wablas_invoice_numbers' => 1500, 'wablas_invoice_template' => 3000, 'wablas_daily_summary_numbers' => 1500, 'wablas_daily_summary_template' => 3000, ]; foreach ($textLimits as $key => $limit) { if (array_key_exists($key, $settings)) { $settings[$key] = substr(trim((string)$settings[$key]), 0, $limit); } } $licenseAppName = trim((string)($settings['license_app_name'] ?? '')); $settings['license_app_name'] = $licenseAppName !== '' ? substr($licenseAppName, 0, 190) : ''; $licenseAppSlug = trim((string)($settings['license_app_slug'] ?? '')); $settings['license_app_slug'] = $licenseAppSlug !== '' ? LicenseService::sanitizeAppSlug($licenseAppSlug, true) : ''; $timezone = trim((string)($settings['timezone'] ?? '')); $settings['timezone'] = in_array($timezone, DateTimeZone::listIdentifiers(), true) ? $timezone : date_default_timezone_get(); $settings['allow_zero_stock_sell'] = (($settings['allow_zero_stock_sell'] ?? '1') === '0') ? '0' : '1'; $settings['manual_discount_enabled'] = (($settings['manual_discount_enabled'] ?? '0') === '1') ? '1' : '0'; $manualDiscountProfitLimitPercent = $settings['manual_discount_profit_limit_percent'] ?? '5'; $manualDiscountProfitLimitPercent = is_numeric($manualDiscountProfitLimitPercent) ? (float)$manualDiscountProfitLimitPercent : 5.0; if ($manualDiscountProfitLimitPercent < 0) { $manualDiscountProfitLimitPercent = 0.0; } if ($manualDiscountProfitLimitPercent > 100) { $manualDiscountProfitLimitPercent = 100.0; } $settings['manual_discount_profit_limit_percent'] = number_format($manualDiscountProfitLimitPercent, 3, '.', ''); $settings['loyalty_enabled'] = (($settings['loyalty_enabled'] ?? '0') === '1') ? '1' : '0'; $settings['smtp_enabled'] = (($settings['smtp_enabled'] ?? '0') === '1') ? '1' : '0'; $settings['wablas_enabled'] = (($settings['wablas_enabled'] ?? '0') === '1') ? '1' : '0'; $settings['wablas_invoice_enabled'] = (($settings['wablas_invoice_enabled'] ?? '0') === '1') ? '1' : '0'; $settings['wablas_daily_summary_enabled'] = (($settings['wablas_daily_summary_enabled'] ?? '0') === '1') ? '1' : '0'; $settings['weight_barcode_mode'] = in_array(($settings['weight_barcode_mode'] ?? 'weight'), ['weight', 'price'], true) ? (string)$settings['weight_barcode_mode'] : 'weight'; $prefixStart = (int)($settings['weight_barcode_prefix_start'] ?? 20); $prefixEnd = (int)($settings['weight_barcode_prefix_end'] ?? 29); if ($prefixStart < 20 || $prefixStart > 29) { $prefixStart = 20; } if ($prefixEnd < 20 || $prefixEnd > 29) { $prefixEnd = 29; } if ($prefixStart > $prefixEnd) { [$prefixStart, $prefixEnd] = [$prefixEnd, $prefixStart]; } $settings['weight_barcode_prefix_start'] = (string)$prefixStart; $settings['weight_barcode_prefix_end'] = (string)$prefixEnd; $smtpPortRaw = trim((string)($settings['smtp_port'] ?? '')); if ($smtpPortRaw === '') { $settings['smtp_port'] = ''; } else { $smtpPort = (int)$smtpPortRaw; if ($smtpPort < 1 || $smtpPort > 65535) { $smtpPort = 587; } $settings['smtp_port'] = (string)$smtpPort; } $settings['smtp_secure'] = in_array(($settings['smtp_secure'] ?? 'tls'), ['tls', 'ssl', 'none'], true) ? (string)$settings['smtp_secure'] : 'tls'; $wablasApiUrl = trim((string)($settings['wablas_api_url'] ?? '')); $settings['wablas_api_url'] = $wablasApiUrl !== '' ? substr(rtrim($wablasApiUrl, '/'), 0, 255) : ''; $wablasCountryCode = preg_replace('/[^0-9+]/', '', (string)($settings['wablas_default_country_code'] ?? '')); $settings['wablas_default_country_code'] = substr($wablasCountryCode, 0, 8); $timeFields = [ 'wablas_invoice_time' => '', 'wablas_daily_summary_time' => '20:00', ]; foreach ($timeFields as $key => $fallback) { $timeValue = trim((string)($settings[$key] ?? '')); if ($timeValue === '') { $settings[$key] = $fallback; continue; } $settings[$key] = preg_match('/^(?:[01]\d|2[0-3]):[0-5]\d$/', $timeValue) ? $timeValue : $fallback; } foreach (['wablas_invoice_numbers', 'wablas_daily_summary_numbers'] as $numbersKey) { $normalizedNumbers = wablasNumbersFromText((string)($settings[$numbersKey] ?? ''), (string)$settings['wablas_default_country_code']); $settings[$numbersKey] = implode("\n", array_slice($normalizedNumbers, 0, 50)); } foreach (['wablas_invoice_template' => 3000, 'wablas_daily_summary_template' => 3000] as $templateKey => $limit) { $template = str_replace(["\r\n", "\r"], "\n", (string)($settings[$templateKey] ?? '')); $settings[$templateKey] = substr(trim($template), 0, $limit); } foreach ($settings as $key => $value) { if (is_array($value)) { continue; } $value = (string)$value; $stmt = $db->prepare("INSERT INTO settings (`key`, `value`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `value` = ?"); $stmt->execute([$key, $value, $value]); } $files = ['company_logo', 'favicon', 'manager_signature', 'display_slide_1', 'display_slide_2', 'display_slide_3']; foreach ($files as $file_key) { if (isset($_FILES[$file_key]) && $_FILES[$file_key]['error'] === 0) { $ext = pathinfo($_FILES[$file_key]['name'], PATHINFO_EXTENSION); $filename = 'uploads/' . $file_key . '_' . time() . '.' . $ext; if (!is_dir('uploads')) { mkdir('uploads', 0777, true); } if (move_uploaded_file($_FILES[$file_key]['tmp_name'], $filename)) { $stmt = $db->prepare("INSERT INTO settings (`key`, `value`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `value` = ?"); $stmt->execute([$file_key, $filename, $filename]); } } } $allowedTabs = ['company', 'system', 'branding', 'integrations']; $activeTab = strtolower(trim((string)($_POST['settings_active_tab'] ?? 'company'))); if (!in_array($activeTab, $allowedTabs, true)) { $activeTab = 'company'; } redirectWithMessage('Settings updated successfully!', page_url('settings', ['tab' => $activeTab])); } }