From 1740c568f9e82c600e3a60e5ddea8edc3d373fbc Mon Sep 17 00:00:00 2001 From: Focuslinkstech <45756999+Focuslinkstech@users.noreply.github.com> Date: Wed, 9 Apr 2025 11:39:00 +0100 Subject: [PATCH] feat: add subject field for bulk messaging and update validation logic --- system/controllers/message.php | 21 +++++++++--- ui/ui/admin/message/bulk.tpl | 61 +++++++++++++++++++++++++++++----- 2 files changed, 69 insertions(+), 13 deletions(-) diff --git a/system/controllers/message.php b/system/controllers/message.php index f7ec29b0..01ce48a0 100644 --- a/system/controllers/message.php +++ b/system/controllers/message.php @@ -135,9 +135,14 @@ EOT; $router = $_REQUEST['router'] ?? null; $test = isset($_REQUEST['test']) && $_REQUEST['test'] === 'on' ? true : false; $service = $_REQUEST['service'] ?? ''; + $subject = $_REQUEST['subject'] ?? ''; if (empty($group) || empty($message) || empty($via) || empty($service)) { - die(json_encode(['status' => 'error', 'message' => 'All fields are required'])); + die(json_encode(['status' => 'error', 'message' => LANG::T('All fields are required')])); + } + + if ($via === 'all' || $via === 'email' || $via === 'inbox' && empty($subject)) { + die(json_encode(['status' => 'error', 'message' => LANG::T('Subject is required to send message using') . ' ' . $via . '.'])); } // Get batch of customers based on group @@ -153,7 +158,7 @@ EOT; default: $router = ORM::for_table('tbl_routers')->find_one($router); if (!$router) { - die(json_encode(['status' => 'error', 'message' => 'Invalid router'])); + die(json_encode(['status' => 'error', 'message' => LANG::T('Invalid router')])); } $routerName = $router->name; break; @@ -295,7 +300,7 @@ EOT; $totalInboxSent = 0; $totalInboxFailed = 0; $batchStatus = []; - $subject = $config['CompanyName'] . ' ' . Lang::T('Notification Message'); + //$subject = $config['CompanyName'] . ' ' . Lang::T('Notification Message'); $form = 'Admin'; foreach ($customers as $customer) { @@ -305,6 +310,12 @@ EOT; $message ); + $currentSubject = str_replace( + ['[[name]]', '[[user_name]]', '[[phone]]', '[[company_name]]'], + [$customer['fullname'], $customer['username'], $customer['phonenumber'], $config['CompanyName']], + $subject + ); + $phoneNumber = preg_replace('/\D/', '', $customer['phonenumber']); if (empty($phoneNumber)) { @@ -347,7 +358,7 @@ EOT; } if ($via === 'email' || $via === 'all') { - if (Message::sendEmail($customer['email'], $subject, $currentMessage)) { + if (Message::sendEmail($customer['email'], $currentSubject, $currentMessage)) { $totalEmailSent++; $batchStatus[] = ['name' => $customer['fullname'], 'channel' => $customer['email'], 'status' => 'Email Sent', 'message' => $currentMessage]; } else { @@ -357,7 +368,7 @@ EOT; } if ($via === 'inbox' || $via === 'all') { - if (Message::addToInbox($customer['customer_id'], $subject, $currentMessage, $form)) { + if (Message::addToInbox($customer['customer_id'], $currentSubject, $currentMessage, $form)) { $totalInboxSent++; $batchStatus[] = ['name' => $customer['fullname'], 'channel' => 'Inbox', 'status' => 'Inbox Message Sent', 'message' => $currentMessage]; } else { diff --git a/ui/ui/admin/message/bulk.tpl b/ui/ui/admin/message/bulk.tpl index a0e6a903..9610309d 100644 --- a/ui/ui/admin/message/bulk.tpl +++ b/ui/ui/admin/message/bulk.tpl @@ -30,7 +30,8 @@ <select class="form-control" name="service" id="service"> <option value="all" {if $group=='all' }selected{/if}>{Lang::T('All')}</option> <option value="PPPoE" {if $service=='PPPoE' }selected{/if}>{Lang::T('PPPoE')}</option> - <option value="Hotspot" {if $service=='Hotspot' }selected{/if}>{Lang::T('Hotspot')}</option> + <option value="Hotspot" {if $service=='Hotspot' }selected{/if}>{Lang::T('Hotspot')} + </option> <option value="VPN" {if $service=='VPN' }selected{/if}>{Lang::T('VPN')}</option> </select> </div> @@ -41,8 +42,10 @@ <select class="form-control" name="group" id="group"> <option value="all" {if $group=='all' }selected{/if}>{Lang::T('All Customers')}</option> <option value="new" {if $group=='new' }selected{/if}>{Lang::T('New Customers')}</option> - <option value="expired" {if $group=='expired' }selected{/if}>{Lang::T('Expired Customers')}</option> - <option value="active" {if $group=='active' }selected{/if}>{Lang::T('Active Customers')}</option> + <option value="expired" {if $group=='expired' }selected{/if}>{Lang::T('Expired + Customers')}</option> + <option value="active" {if $group=='active' }selected{/if}>{Lang::T('Active Customers')} + </option> </select> </div> </div> @@ -55,7 +58,8 @@ <option value="email" {if $via=='email' }selected{/if}>{Lang::T('Email')}</option> <option value="sms" {if $via=='sms' }selected{/if}>{Lang::T('SMS')}</option> <option value="wa" {if $via=='wa' }selected{/if}>{Lang::T('WhatsApp')}</option> - <option value="both" {if $via=='both' }selected{/if}>{Lang::T('SMS and WhatsApp')}</option> + <option value="both" {if $via=='both' }selected{/if}>{Lang::T('SMS and WhatsApp')} + </option> </select> </div> </div> @@ -75,10 +79,21 @@ {Lang::T('Use 20 and above if you are sending to all customers to avoid server time out')} </div> </div> + <div class="form-group" id="subject"> + <label class="col-md-2 control-label">{Lang::T('Subject')}</label> + <div class="col-md-6"> + <input type="text" class="form-control" name="subject" id="subject-content" value="" + placeholder="{Lang::T('Enter message subject here')}"> + </div> + <p class="help-block col-md-4"> + {Lang::T('You can also use the below placeholders here too')}. + </p> + </div> <div class="form-group"> <label class="col-md-2 control-label">{Lang::T('Message')}</label> <div class="col-md-6"> - <textarea class="form-control" id="message" name="message" required placeholder="{Lang::T('Compose your message...')}" rows="5">{$message}</textarea> + <textarea class="form-control" id="message" name="message" required + placeholder="{Lang::T('Compose your message...')}" rows="5">{$message}</textarea> <input name="test" id="test" type="checkbox"> {Lang::T('Testing [if checked no real message is sent]')} </div> @@ -96,7 +111,8 @@ </div> <div class="form-group"> <div class="col-lg-offset-2 col-lg-10"> - <button type="button" id="startBulk" class="btn btn-primary">{Lang::T('Start Bulk Messaging')}</button> + <button type="button" id="startBulk" class="btn btn-primary">{Lang::T('Start Bulk + Messaging')}</button> <a href="{Text::url('dashboard')}" class="btn btn-default">{Lang::T('Cancel')}</a> </div> </div> @@ -129,6 +145,34 @@ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script src="https://cdn.datatables.net/1.11.3/js/jquery.dataTables.min.js"></script> +<script> + document.getElementById('via').addEventListener('change', function () { + const via = this.value; + const subject = document.getElementById('subject'); + const subjectField = document.getElementById('subject-content'); + + subject.style.display = (via === 'all' || via === 'email' || via === 'inbox') ? 'block' : 'none'; + + switch (via) { + case 'all': + subjectField.placeholder = 'Enter a subject for all channels'; + subjectField.required = true; + break; + case 'email': + subjectField.placeholder = 'Enter a subject for email'; + subjectField.required = true; + break; + case 'inbox': + subjectField.placeholder = 'Enter a subject for inbox'; + subjectField.required = true; + break; + default: + subjectField.placeholder = 'Enter message subject here'; + subjectField.required = false; + break; + } + }); +</script> {literal} <script> let page = 0; @@ -154,6 +198,7 @@ method: 'POST', data: { group: $('#group').val(), + subject: $('#subject').val() || '', message: $('#message').val(), via: $('#via').val(), batch: $('#batch').val(), @@ -192,7 +237,7 @@ msg.channel, `<span class="text-${statusClass}">${msg.status}</span>`, msg.message || 'No message', - msg.router ? msg.router : 'All Router', + msg.router ? msg.router : 'All Router', msg.service == 'all' ? 'All Service' : (msg.service || 'No Service') ]).draw(false); // Add row without redrawing the table }); @@ -210,7 +255,7 @@ console.error("Unexpected response format:", response); $('#status').html(` <div class="alert alert-danger"> - <i class="fas fa-exclamation-circle"></i> Error: Unexpected response format. + <i class="fas fa-exclamation-circle"></i> Error: ${response.message} </div> `); }