change whatsapp setting
This commit is contained in:
parent
a3d27b0ee3
commit
3f3ac7d889
@ -2,37 +2,65 @@
|
|||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
require_once __DIR__ . '/includes/layout.php';
|
require_once __DIR__ . '/includes/layout.php';
|
||||||
|
require_once __DIR__ . '/includes/NotificationService.php';
|
||||||
|
|
||||||
ensure_schema();
|
ensure_schema();
|
||||||
|
|
||||||
$errors = [];
|
$errors = [];
|
||||||
$success = '';
|
$success = '';
|
||||||
|
$testSuccess = '';
|
||||||
|
$testError = '';
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
$updates = [
|
if (isset($_POST['action']) && $_POST['action'] === 'test_whatsapp') {
|
||||||
'thawani_publishable_key' => trim($_POST['thawani_publishable_key'] ?? ''),
|
$testPhone = trim($_POST['test_phone'] ?? '');
|
||||||
'thawani_secret_key' => trim($_POST['thawani_secret_key'] ?? ''),
|
$testMessage = trim($_POST['test_message'] ?? '');
|
||||||
'thawani_environment' => trim($_POST['thawani_environment'] ?? 'test'),
|
|
||||||
'wablas_domain' => trim($_POST['wablas_domain'] ?? ''),
|
if ($testPhone === '') {
|
||||||
'wablas_api_token' => trim($_POST['wablas_api_token'] ?? ''),
|
$testError = 'Phone number is required for testing.';
|
||||||
'wablas_secret_key' => trim($_POST['wablas_secret_key'] ?? ''),
|
} else {
|
||||||
'whatsapp_enabled' => isset($_POST['whatsapp_enabled']) ? '1' : '0',
|
// Check if settings are saved first?
|
||||||
'smtp_host' => trim($_POST['smtp_host'] ?? ''),
|
// We rely on get_setting() which reads from DB.
|
||||||
'smtp_port' => trim($_POST['smtp_port'] ?? ''),
|
// If user just changed input but didn't save, it won't work.
|
||||||
'smtp_secure' => trim($_POST['smtp_secure'] ?? ''),
|
// That's standard behavior.
|
||||||
'smtp_user' => trim($_POST['smtp_user'] ?? ''),
|
|
||||||
'smtp_pass' => trim($_POST['smtp_pass'] ?? ''),
|
try {
|
||||||
'mail_from' => trim($_POST['mail_from'] ?? ''),
|
// We use the new public method in NotificationService
|
||||||
'mail_from_name' => trim($_POST['mail_from_name'] ?? ''),
|
// This method handles the 968 prefix logic internally.
|
||||||
];
|
NotificationService::sendWhatsApp($testPhone, $testMessage ?: 'Test message from CargoLink');
|
||||||
|
$testSuccess = 'Test message sent (check logs/phone).';
|
||||||
if (empty($errors)) {
|
} catch (Throwable $e) {
|
||||||
$pdo = db();
|
$testError = 'Error sending test: ' . $e->getMessage();
|
||||||
foreach ($updates as $key => $val) {
|
}
|
||||||
$stmt = $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (:k, :v) ON DUPLICATE KEY UPDATE setting_value = :v2");
|
}
|
||||||
$stmt->execute([':k' => $key, ':v' => $val, ':v2' => $val]);
|
|
||||||
|
} else {
|
||||||
|
// Save Settings
|
||||||
|
$updates = [
|
||||||
|
'thawani_publishable_key' => trim($_POST['thawani_publishable_key'] ?? ''),
|
||||||
|
'thawani_secret_key' => trim($_POST['thawani_secret_key'] ?? ''),
|
||||||
|
'thawani_environment' => trim($_POST['thawani_environment'] ?? 'test'),
|
||||||
|
'wablas_domain' => trim($_POST['wablas_domain'] ?? ''),
|
||||||
|
'wablas_api_token' => trim($_POST['wablas_api_token'] ?? ''),
|
||||||
|
'wablas_secret_key' => trim($_POST['wablas_secret_key'] ?? ''),
|
||||||
|
'whatsapp_enabled' => isset($_POST['whatsapp_enabled']) ? '1' : '0',
|
||||||
|
'smtp_host' => trim($_POST['smtp_host'] ?? ''),
|
||||||
|
'smtp_port' => trim($_POST['smtp_port'] ?? ''),
|
||||||
|
'smtp_secure' => trim($_POST['smtp_secure'] ?? ''),
|
||||||
|
'smtp_user' => trim($_POST['smtp_user'] ?? ''),
|
||||||
|
'smtp_pass' => trim($_POST['smtp_pass'] ?? ''),
|
||||||
|
'mail_from' => trim($_POST['mail_from'] ?? ''),
|
||||||
|
'mail_from_name' => trim($_POST['mail_from_name'] ?? ''),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (empty($errors)) {
|
||||||
|
$pdo = db();
|
||||||
|
foreach ($updates as $key => $val) {
|
||||||
|
$stmt = $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (:k, :v) ON DUPLICATE KEY UPDATE setting_value = :v2");
|
||||||
|
$stmt->execute([':k' => $key, ':v' => $val, ':v2' => $val]);
|
||||||
|
}
|
||||||
|
$success = "Integrations settings updated successfully.";
|
||||||
}
|
}
|
||||||
$success = "Integrations settings updated successfully.";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,11 +96,17 @@ render_header('Integrations', 'admin', true);
|
|||||||
<?php if ($success): ?>
|
<?php if ($success): ?>
|
||||||
<div class="alert alert-success"><?= e($success) ?></div>
|
<div class="alert alert-success"><?= e($success) ?></div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
<?php if ($testSuccess): ?>
|
||||||
|
<div class="alert alert-info"><?= e($testSuccess) ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if ($testError): ?>
|
||||||
|
<div class="alert alert-danger"><?= e($testError) ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
<?php if ($errors): ?>
|
<?php if ($errors): ?>
|
||||||
<div class="alert alert-danger"><?= e(implode('<br>', $errors)) ?></div>
|
<div class="alert alert-danger"><?= e(implode('<br>', $errors)) ?></div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<form method="post">
|
<form method="post" id="settingsForm">
|
||||||
|
|
||||||
<ul class="nav nav-tabs mb-4" id="integrationsTab" role="tablist">
|
<ul class="nav nav-tabs mb-4" id="integrationsTab" role="tablist">
|
||||||
<li class="nav-item" role="presentation">
|
<li class="nav-item" role="presentation">
|
||||||
@ -166,6 +200,27 @@ render_header('Integrations', 'admin', true);
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Test Section -->
|
||||||
|
<div class="panel p-4 border-top">
|
||||||
|
<h4 class="h6 fw-bold mb-3">Test Connection</h4>
|
||||||
|
<div class="row g-2 align-items-end">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label small text-muted">Test Phone Number</label>
|
||||||
|
<input type="text" form="testForm" name="test_phone" class="form-control" placeholder="e.g. 12345678">
|
||||||
|
<div class="form-text x-small">Enter 8 digits (system adds 968) or full number.</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5">
|
||||||
|
<label class="form-label small text-muted">Test Message</label>
|
||||||
|
<input type="text" form="testForm" name="test_message" class="form-control" placeholder="Test message...">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<button type="submit" form="testForm" class="btn btn-outline-success w-100">
|
||||||
|
<i class="bi bi-send me-1"></i> Send Test
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- SMTP Mail Gateway Panel -->
|
<!-- SMTP Mail Gateway Panel -->
|
||||||
@ -228,6 +283,11 @@ render_header('Integrations', 'admin', true);
|
|||||||
<button type="submit" class="btn btn-primary px-5">Save Integrations</button>
|
<button type="submit" class="btn btn-primary px-5">Save Integrations</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<!-- Hidden Test Form -->
|
||||||
|
<form method="post" id="testForm" style="display:none;">
|
||||||
|
<input type="hidden" name="action" value="test_whatsapp">
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ class NotificationService
|
|||||||
* Send a notification for a specific event.
|
* Send a notification for a specific event.
|
||||||
*
|
*
|
||||||
* @param string $eventName The event name (e.g., 'shipment_created')
|
* @param string $eventName The event name (e.g., 'shipment_created')
|
||||||
* @param array $user The recipient user array (must contain 'email' and 'full_name')
|
* @param array $user The recipient user array (must contain 'id', 'email', 'full_name', 'role')
|
||||||
* @param array $data Data to replace in placeholders (e.g., ['shipment_id' => 123])
|
* @param array $data Data to replace in placeholders (e.g., ['shipment_id' => 123])
|
||||||
* @param string|null $lang 'en' or 'ar'. If null, sends both combined.
|
* @param string|null $lang 'en' or 'ar'. If null, sends both combined.
|
||||||
*/
|
*/
|
||||||
@ -69,9 +69,109 @@ class NotificationService
|
|||||||
|
|
||||||
// Send WhatsApp if enabled
|
// Send WhatsApp if enabled
|
||||||
if (get_setting('whatsapp_enabled') === '1') {
|
if (get_setting('whatsapp_enabled') === '1') {
|
||||||
// Log WhatsApp (Mock)
|
$phone = self::getPhoneNumber($user);
|
||||||
// In a real app, this would call Twilio/Meta API
|
if ($phone) {
|
||||||
error_log("WHATSAPP Notification to {$user['email']} (Phone N/A): $whatsapp");
|
self::sendWhatsApp($phone, $whatsapp);
|
||||||
|
} else {
|
||||||
|
error_log("WHATSAPP Notification skipped for {$user['email']}: Phone number not found.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* Retrieve phone number for a user, fetching from profile if necessary.
|
||||||
|
*/
|
||||||
|
private static function getPhoneNumber(array $user): ?string
|
||||||
|
{
|
||||||
|
if (!empty($user['phone'])) {
|
||||||
|
return $user['phone'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($user['id']) || empty($user['role'])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdo = db();
|
||||||
|
if ($user['role'] === 'shipper') {
|
||||||
|
$stmt = $pdo->prepare("SELECT phone FROM shipper_profiles WHERE user_id = ?");
|
||||||
|
$stmt->execute([$user['id']]);
|
||||||
|
return $stmt->fetchColumn() ?: null;
|
||||||
|
} elseif ($user['role'] === 'truck_owner') {
|
||||||
|
$stmt = $pdo->prepare("SELECT phone FROM truck_owner_profiles WHERE user_id = ?");
|
||||||
|
$stmt->execute([$user['id']]);
|
||||||
|
return $stmt->fetchColumn() ?: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a WhatsApp message via Wablas API.
|
||||||
|
*/
|
||||||
|
public static function sendWhatsApp(string $phone, string $message)
|
||||||
|
{
|
||||||
|
// 1. Format Phone Number
|
||||||
|
// Remove non-numeric characters
|
||||||
|
$phone = preg_replace('/[^0-9]/', '', $phone);
|
||||||
|
|
||||||
|
// If 8 digits, prepend 968 (Oman country code)
|
||||||
|
if (strlen($phone) === 8) {
|
||||||
|
$phone = '968' . $phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Get Settings
|
||||||
|
$domain = get_setting('wablas_domain');
|
||||||
|
$token = get_setting('wablas_api_token');
|
||||||
|
|
||||||
|
if (!$domain || !$token) {
|
||||||
|
error_log("WHATSAPP Error: Wablas domain or token not configured.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure domain has no trailing slash and correct scheme
|
||||||
|
$domain = rtrim($domain, '/');
|
||||||
|
if (!preg_match('/^https?:\\/', $domain)) {
|
||||||
|
$domain = 'https://' . $domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Send API Request
|
||||||
|
// Endpoint: /api/send-message (StandardWablas)
|
||||||
|
$url = $domain . "/api/send-message";
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'phone' => $phone,
|
||||||
|
'message' => $message,
|
||||||
|
];
|
||||||
|
|
||||||
|
$ch = curl_init($url);
|
||||||
|
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||||
|
"Authorization: $token",
|
||||||
|
"Content-Type: application/json" // Wablas often accepts JSON or form-data. Trying JSON first, or form-data if that fails.
|
||||||
|
// Actually, many Wablas instances use form-data or x-www-form-urlencoded.
|
||||||
|
// Let's try standard POST fields which curl sends as application/x-www-form-urlencoded by default if passing array.
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Resetting headers to just Authorization for form-urlencoded default
|
||||||
|
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||||
|
"Authorization: $token"
|
||||||
|
]);
|
||||||
|
curl_setopt($ch, CURLOPT_POST, true);
|
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||||
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // For dev env
|
||||||
|
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
$error = curl_error($ch);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
if ($error) {
|
||||||
|
error_log("WHATSAPP cURL Error: $error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log result
|
||||||
|
error_log("WHATSAPP Sent to $phone. Status: $httpCode. Response: " . substr($response, 0, 100));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user