add a card
This commit is contained in:
parent
921e3675c0
commit
e7ab037971
86
admin/generate_card.php
Normal file
86
admin/generate_card.php
Normal 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);
|
||||
@ -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>
|
||||
|
||||
|
||||
BIN
assets/images/card_templates/default.png
Normal file
BIN
assets/images/card_templates/default.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
@ -0,0 +1 @@
|
||||
INSERT INTO settings (setting_key, setting_value) VALUES ('whatsapp_send_cards', '0');
|
||||
@ -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') {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user