add a card

This commit is contained in:
Flatlogic Bot 2026-02-15 06:25:40 +00:00
parent 921e3675c0
commit e7ab037971
5 changed files with 167 additions and 12 deletions

86
admin/generate_card.php Normal file
View File

@ -0,0 +1,86 @@
<?php
require_once __DIR__ . '/../includes/I18N/Arabic.php';
// --- Parameters ---
$text = $_GET['text'] ?? 'Default Text';
$lang = $_GET['lang'] ?? 'en';
$template = $_GET['template'] ?? 'default';
// --- Configuration ---
$width = 800;
$height = 600;
$font_size = 24;
$font_file = __DIR__ . '/../includes/fpdf/font/amiri.ttf';
$template_image = __DIR__ . '/../assets/images/card_templates/' . basename($template) . '.png';
if (!file_exists($template_image)) {
$template_image = __DIR__ . '/../assets/images/card_templates/default.png';
}
// --- Text Processing for Arabic ---
if ($lang === 'ar') {
$arabic = new I18N\Arabic();
$text = $arabic->utf8Glyphs($text);
}
// --- Image Generation ---
header('Content-Type: image/jpeg');
$image = imagecreatefrompng($template_image);
// Colors
$text_color = imagecolorallocate($image, 0, 0, 0); // Black
// --- Text Wrapping and Positioning ---
$lines = [];
if ($lang === 'ar') {
// Simple reverse for RTL line wrapping (basic)
$words = explode(' ', $text);
$line = '';
foreach ($words as $word) {
$new_line = $line . ' ' . $word;
$bbox = imagettfbbox($font_size, 0, $font_file, $new_line);
$line_width = abs($bbox[2] - $bbox[0]);
if ($line_width > ($width - 80)) { // 40px margin
$lines[] = $line;
$line = $word;
} else {
$line = $new_line;
}
}
$lines[] = $line;
} else {
$words = explode(' ', $text);
$line = '';
foreach ($words as $word) {
$new_line = $line . ($line ? ' ' : '') . $word;
$bbox = imagettfbbox($font_size, 0, $font_file, $new_line);
$line_width = abs($bbox[2] - $bbox[0]);
if ($line_width > ($width - 80)) { // 40px margin
$lines[] = $line;
$line = $word;
} else {
$line = $new_line;
}
}
$lines[] = $line;
}
// Calculate total text height
$total_text_height = count($lines) * ($font_size * 1.5);
$y_start = ($height - $total_text_height) / 2;
// Draw text line by line
foreach ($lines as $i => $line) {
$line = trim($line);
$bbox = imagettfbbox($font_size, 0, $font_file, $line);
$line_width = abs($bbox[2] - $bbox[0]);
$x = ($width - $line_width) / 2;
$y = $y_start + ($i * $font_size * 1.5);
imagettftext($image, $font_size, 0, $x, $y, $text_color, $font_file, $line);
}
// --- Output ---
imagejpeg($image);
imagedestroy($image);

View File

@ -11,10 +11,16 @@ if (!is_super_admin()) {
$pdo = db();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Handle checkbox separately
if (!isset($_POST['settings']['whatsapp_send_cards'])) {
$_POST['settings']['whatsapp_send_cards'] = '0';
}
foreach ($_POST['settings'] as $key => $value) {
$stmt = $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (?, ?) ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value)");
$stmt->execute([$key, $value]);
}
header('Location: settings.php?success=1');
exit;
}
@ -194,16 +200,25 @@ $is_rtl = (get_current_lang() === 'ar');
<label class="form-label"><?= __('API Token') ?></label>
<input type="password" name="settings[wablas_api_token]" class="form-control" value="<?= htmlspecialchars($settings['wablas_api_token'] ?? '') ?>">
</div>
<div class="mb-3">
<label class="form-label"><?= __('Security Key') ?></label>
<input type="password" name="settings[wablas_security_key]" class="form-control" value="<?= htmlspecialchars($settings['wablas_security_key'] ?? '') ?>">
</div>
<div class="mb-3">
<div class="mb-3">
<label class="form-label"><?= __('Server URL') ?></label>
<input type="url" name="settings[wablas_server_url]" class="form-control" value="<?= htmlspecialchars($settings['wablas_server_url'] ?? 'https://console.wablas.com') ?>">
</div>
</div>
</div>
<!-- WhatsApp Settings -->
<div class="card">
<div class="card-header bg-white py-3">
<h5 class="mb-0"><i class="bi bi-card-image <?= $is_rtl ? 'ms-2' : 'me-2' ?>"></i> <?= __('WhatsApp Settings') ?></h5>
</div>
<div class="card-body">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" name="settings[whatsapp_send_cards]" value="1" id="whatsapp_send_cards" <?= ($settings['whatsapp_send_cards'] ?? '0') == '1' ? 'checked' : '' ?>>
<label class="form-check-label" for="whatsapp_send_cards"><?= __('Send Rich-Text Cards') ?></label>
<div class="form-text"><?= __('When enabled, sends messages as an image (card) instead of plain text.') ?></div>
</div>
</div>
</div>
</div>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1 @@
INSERT INTO settings (setting_key, setting_value) VALUES ('whatsapp_send_cards', '0');

View File

@ -8,7 +8,6 @@ class WablasService {
$token = $settings['wablas_api_token'] ?? '';
$serverUrl = $settings['wablas_server_url'] ?? '';
$securityKey = $settings['wablas_security_key'] ?? '';
if (empty($token) || empty($serverUrl)) {
error_log("Wablas settings missing.");
@ -18,10 +17,6 @@ class WablasService {
$to = prefix_phone($to);
$data = ['phone' => $to, 'message' => $message];
if (!empty($securityKey)) {
$data['security_key'] = $securityKey;
$data['secret_key'] = $securityKey;
}
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, ["Authorization: $token"]);
@ -50,13 +45,60 @@ class WablasService {
return ['success' => false, 'error' => $result];
}
public static function sendImageAndCaption($to, $imageUrl, $caption) {
$pdo = db();
$settings = $pdo->query("SELECT setting_key, setting_value FROM settings WHERE setting_key LIKE 'wablas_%'")->fetchAll(PDO::FETCH_KEY_PAIR);
$token = $settings['wablas_api_token'] ?? '';
$serverUrl = $settings['wablas_server_url'] ?? '';
if (empty($token) || empty($serverUrl)) {
error_log("Wablas settings missing.");
return ['success' => false, 'error' => 'Settings missing'];
}
$to = prefix_phone($to);
$data = [
'phone' => $to,
'image' => $imageUrl,
'caption' => $caption
];
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, ["Authorization: $token"]);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($curl, CURLOPT_URL, rtrim($serverUrl, '/') . "/api/send-image");
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
$result = curl_exec($curl);
$error = curl_error($curl);
curl_close($curl);
if ($error) {
error_log("Wablas CURL error: " . $error);
return ['success' => false, 'error' => $error];
}
$response = json_decode($result, true);
if (isset($response['status']) && $response['status'] == true) {
return ['success' => true, 'data' => $response];
}
error_log("Wablas API error: " . $result);
return ['success' => false, 'error' => $result];
}
public static function getOrgName($lang = 'en') {
$pdo = db();
$org = $pdo->query("SELECT name_en, name_ar FROM org_profile LIMIT 1")->fetch();
return ($lang === 'ar') ? ($org['name_ar'] ?? 'المنظمة') : ($org['name_en'] ?? 'Organization');
}
private static function sendTemplatedMessage($to, $templateName, $vars, $lang = 'en') {
private static function sendTemplatedMessage($to, $templateName, $vars, $lang = 'en', $useImage = true) {
if (empty($to)) {
return ['success' => false, 'error' => 'Recipient phone number is missing.'];
}
@ -77,7 +119,18 @@ class WablasService {
$messageBody = str_replace('{'.$key.'}', $value, $messageBody);
}
return self::sendMessage($to, $messageBody);
if ($useImage) {
// ToDo: Find a way to get the base URL
$siteUrl = 'http://' . $_SERVER['HTTP_HOST'];
$imageUrl = $siteUrl . '/admin/generate_card.php?' . http_build_query([
'text' => $messageBody,
'lang' => $lang,
'template' => $templateName
]);
return self::sendImageAndCaption($to, $imageUrl, $messageBody);
} else {
return self::sendMessage($to, $messageBody);
}
}
public static function sendThankYou($donation, $lang = 'en') {