diff --git a/src/com_tjnotifications/admin/language/en-GB.com_tjnotifications.ini b/src/com_tjnotifications/admin/language/en-GB.com_tjnotifications.ini
index 42163815..7d5fab55 100644
--- a/src/com_tjnotifications/admin/language/en-GB.com_tjnotifications.ini
+++ b/src/com_tjnotifications/admin/language/en-GB.com_tjnotifications.ini
@@ -311,3 +311,17 @@ COM_TJNOTIFICATIONS_SETTINGS_WEBHOOK_URL_LABEL="Webhook URL"
COM_TJNOTIFICATIONS_SETTINGS_WEBHOOK_URL_DESC="Enter URL for your Webhook notification"
COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_CUSTOM_WEBHOOK_URLS="Please add custom webhook URL or use global webhook URL"
COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_GLOBAL_WEBHOOK_URLS="Please add webhook URLs in the global config or add custom webhook URL."
+
+;Since 3.1.0
+;Notification - Validation error messages
+COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_WEBHOOK_BODY_REQUIRED="Webhook body is required when webhook is enabled."
+COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_WEBHOOK_LANGUAGE_REQUIRED="Language selection is required when webhook is enabled."
+COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_EMAIL_BODY_REQUIRED="Email body is required when email is enabled."
+COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_EMAIL_SUBJECT_REQUIRED="Email subject is required when email is enabled."
+COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_EMAIL_LANGUAGE_REQUIRED="Language selection is required when email is enabled."
+COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_SMS_BODY_REQUIRED="SMS body is required when SMS is enabled."
+COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_SMS_LANGUAGE_REQUIRED="Language selection is required when SMS is enabled."
+COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_PUSH_BODY_REQUIRED="Push body is required when push is enabled."
+COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_PUSH_LANGUAGE_REQUIRED="Language selection is required when push is enabled."
+COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_WHATSAPP_BODY_REQUIRED="WhatsApp body is required when WhatsApp is enabled."
+COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_WHATSAPP_LANGUAGE_REQUIRED="Language selection is required when WhatsApp is enabled."
\ No newline at end of file
diff --git a/src/com_tjnotifications/admin/models/forms/emailfields.xml b/src/com_tjnotifications/admin/models/forms/emailfields.xml
index 9501102f..40f0fd6f 100644
--- a/src/com_tjnotifications/admin/models/forms/emailfields.xml
+++ b/src/com_tjnotifications/admin/models/forms/emailfields.xml
@@ -10,7 +10,6 @@
type="contentlanguage"
label="JFIELD_LANGUAGE_LABEL"
description="COM_TJNOTIFICATIONS_NOTIFICATION_LANGUAGE_DESC"
- required="true"
>
@@ -20,7 +19,6 @@
type="textarea"
label="COM_TJNOTIFICATIONS_FIELD_EMAIL_SUBJECT_LABEL"
description="COM_TJNOTIFICATIONS_FIELD_EMAIL_SUBJECT_DESC"
- required="true"
/>
diff --git a/src/com_tjnotifications/admin/models/forms/pushfields.xml b/src/com_tjnotifications/admin/models/forms/pushfields.xml
index 0e106254..c7e461d8 100644
--- a/src/com_tjnotifications/admin/models/forms/pushfields.xml
+++ b/src/com_tjnotifications/admin/models/forms/pushfields.xml
@@ -10,7 +10,6 @@
type="contentlanguage"
label="JFIELD_LANGUAGE_LABEL"
description="COM_TJNOTIFICATIONS_NOTIFICATION_LANGUAGE_DESC"
- required="true"
>
@@ -24,7 +23,6 @@
cols="150"
filter="JComponentHelper::filterText"
class="validate-json"
- required="true"
/>
diff --git a/src/com_tjnotifications/admin/models/forms/smsfields.xml b/src/com_tjnotifications/admin/models/forms/smsfields.xml
index aa3b8d64..8082040a 100644
--- a/src/com_tjnotifications/admin/models/forms/smsfields.xml
+++ b/src/com_tjnotifications/admin/models/forms/smsfields.xml
@@ -10,7 +10,6 @@
type="contentlanguage"
label="JFIELD_LANGUAGE_LABEL"
description="COM_TJNOTIFICATIONS_NOTIFICATION_LANGUAGE_DESC"
- required="true"
>
@@ -23,7 +22,6 @@
rows="10"
cols="150"
filter="JComponentHelper::filterText"
- required="true"
onchange="tjnotificationsAdmin.notification.validateSmsLength(this)"
/>
diff --git a/src/com_tjnotifications/admin/models/forms/webhookfields.xml b/src/com_tjnotifications/admin/models/forms/webhookfields.xml
index c2f967e2..46689bb2 100755
--- a/src/com_tjnotifications/admin/models/forms/webhookfields.xml
+++ b/src/com_tjnotifications/admin/models/forms/webhookfields.xml
@@ -10,7 +10,6 @@
type="contentlanguage"
label="JFIELD_LANGUAGE_LABEL"
description="COM_TJNOTIFICATIONS_NOTIFICATION_LANGUAGE_DESC"
- required="true"
>
@@ -45,7 +44,6 @@
cols="350"
filter="JComponentHelper::filterText"
class="validate-json"
- required="true"
/>
diff --git a/src/com_tjnotifications/admin/models/forms/whatsappfields.xml b/src/com_tjnotifications/admin/models/forms/whatsappfields.xml
index cdd0caef..8426832b 100644
--- a/src/com_tjnotifications/admin/models/forms/whatsappfields.xml
+++ b/src/com_tjnotifications/admin/models/forms/whatsappfields.xml
@@ -10,7 +10,6 @@
type="contentlanguage"
label="JFIELD_LANGUAGE_LABEL"
description="COM_TJNOTIFICATIONS_NOTIFICATION_LANGUAGE_DESC"
- required="true"
>
@@ -23,7 +22,6 @@
rows="10"
cols="150"
filter="JComponentHelper::filterText"
- required="true"
/>
diff --git a/src/com_tjnotifications/admin/models/notification.php b/src/com_tjnotifications/admin/models/notification.php
index 28f00bd0..310e9596 100644
--- a/src/com_tjnotifications/admin/models/notification.php
+++ b/src/com_tjnotifications/admin/models/notification.php
@@ -321,7 +321,8 @@ public function updateReplacementTags($data)
*/
public function save($data)
{
- $isNew = true;
+ // Determine if this is a new record or edit
+ $isNew = empty($data['id']) || $data['id'] == 0;
// 1 - save template first
if (!empty($data))
@@ -345,14 +346,22 @@ public function save($data)
if (!parent::save($data))
{
+ // Log the error for debugging
+ Factory::getApplication()->getLogger()->error('TJNotifications: Failed to save template - ' . $this->getError());
return false;
}
else
{
- $db = Factory::getDbo();
+ $db = Factory::getDbo();
+
+ // Get the template ID - use insertid() for new records, or the existing ID for edits
+ if ($isNew) {
+ $templateId = $db->insertid();
+ } else {
+ $templateId = $data['id'];
+ }
+
// IMPORTANT to set new id in state, it is fetched in controller later
- // Get current Template id
- $templateId = $db->insertid();
$this->setState('com_tjnotifications.edit.notification.id', $templateId);
$this->setState('com_tjnotifications.edit.notification.new', $isNew);
}
@@ -397,25 +406,58 @@ public function save($data)
// 2.2 Find existing template config entries to be deleted (i.e. language specific templates removed by user)
foreach ($data[$backend][$backend . 'fields'] as $backendName => $backendFieldValues)
{
- // Webhook stuff starts here
- if ($backend == 'webhook' && $data[$backend]['state'])
+ // Backend-specific validation - only validate when backend is enabled
+ if ($data[$backend]['state'])
{
- // If not using global webhook URLs & custom webhooks URLs are also empty
- if (empty($backendFieldValues['use_global_webhook_url']) && empty($backendFieldValues['webhook_url']))
+ // Common validation for all backends
+ if (empty($backendFieldValues['language']))
{
- $this->setError(Text::_('COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_CUSTOM_WEBHOOK_URLS'));
+ $errorKey = 'COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_' . strtoupper($backend) . '_LANGUAGE_REQUIRED';
+ $this->setError(Text::_($errorKey));
return false;
}
- // If using global webhook URL & the global URLs are empty
- elseif ($backendFieldValues['use_global_webhook_url'] && empty($webhookUrls[0]))
+
+ // Check if body exists and is not empty (trim to handle whitespace)
+ if (!isset($backendFieldValues['body']) || trim($backendFieldValues['body']) === '')
{
- $this->setError(Text::_('COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_GLOBAL_WEBHOOK_URLS'));
+ $errorKey = 'COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_' . strtoupper($backend) . '_BODY_REQUIRED';
+ $this->setError(Text::_($errorKey));
return false;
}
+
+ // Email-specific validation
+ if ($backend == 'email')
+ {
+ if (empty($backendFieldValues['subject']))
+ {
+ $this->setError(Text::_('COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_EMAIL_SUBJECT_REQUIRED'));
+
+ return false;
+ }
+ }
+
+ // Webhook-specific validation
+ if ($backend == 'webhook')
+ {
+ // If not using global webhook URLs & custom webhooks URLs are also empty
+ if (empty($backendFieldValues['use_global_webhook_url']) && empty($backendFieldValues['webhook_url']))
+ {
+ $this->setError(Text::_('COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_CUSTOM_WEBHOOK_URLS'));
+
+ return false;
+ }
+ // If using global webhook URL & the global URLs are empty
+ elseif (!empty($backendFieldValues['use_global_webhook_url']) && empty($webhookUrls[0]))
+ {
+ $this->setError(Text::_('COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_GLOBAL_WEBHOOK_URLS'));
+
+ return false;
+ }
+ }
}
- // Webhook stuff ends here
+ // Backend validation ends here
// Iterate through each lang. specific config entry
foreach ($existingBackendConfigs as $existingBackendConfig)
@@ -453,23 +495,40 @@ public function save($data)
// Function call to delete template configs
$this->deleteBackendConfigs($backendConfigIdsToBeDeleted);
- // 2.3 Common data for saving
- $createdOn = !empty($data['created_on']) ? $data['created_on'] : '';
- $updatedOn = !empty($data['updated_on']) ? $data['updated_on'] : '';
-
// 2.4 try saving all backend specific configs
// This has repeatable data eg: $data['email']['emailfields'] or $data['sms']['smsfields']
foreach ($data[$backend][$backend . 'fields'] as $backendName => $backendFieldValues)
{
$templateConfigTable = Table::getInstance('Template', 'TjnotificationTable', array('dbo', $db));
- $templateConfigTable->load(array('template_id' => $templateId, 'backend' => $backendName));
+
+ // Determine if this is a new backend config or existing one
+ $isNewBackendConfig = empty($backendFieldValues['id']);
+
+ // Load existing record if ID is present (edit mode)
+ if (!$isNewBackendConfig)
+ {
+ $templateConfigTable->load($backendFieldValues['id']);
+ }
// Non-repeat data
$templateConfigTable->template_id = $templateId;
$templateConfigTable->backend = $backend;
$templateConfigTable->state = $data[$backend]['state'];
- $templateConfigTable->created_on = $createdOn;
- $templateConfigTable->updated_on = $updatedOn;
+
+ // Set datetime fields properly
+ $date = Factory::getDate();
+ if ($isNewBackendConfig)
+ {
+ // New backend config - set created_on to now
+ $templateConfigTable->created_on = $date->toSql(true);
+ $templateConfigTable->updated_on = $db->getNullDate();
+ }
+ else
+ {
+ // Existing backend config - keep created_on, update updated_on
+ // created_on is already loaded from database
+ $templateConfigTable->updated_on = $date->toSql(true);
+ }
// Get params data
// State, emailfields / smsfields
@@ -487,9 +546,9 @@ public function save($data)
$templateConfigTable->params = json_encode($params);
// Repeatable data
- $templateConfigTable->subject = !empty($backendFieldValues['subject']) ? $backendFieldValues['subject']: '';
- $templateConfigTable->body = $backendFieldValues['body'];
- $templateConfigTable->language = $backendFieldValues['language'];
+ $templateConfigTable->subject = !empty($backendFieldValues['subject']) ? $backendFieldValues['subject'] : '';
+ $templateConfigTable->body = isset($backendFieldValues['body']) ? $backendFieldValues['body'] : '';
+ $templateConfigTable->language = isset($backendFieldValues['language']) ? $backendFieldValues['language'] : '*';
$templateConfigTable->is_override = 0;
// Webhook stuff starts here
@@ -504,15 +563,17 @@ public function save($data)
$templateConfigTable->provider_template_id = $backendFieldValues['provider_template_id'];
}
- // Save backend in config table
- if (empty($backendFieldValues['id']))
+ // Set ID if exists (for updates), otherwise it will be a new insert
+ if (!empty($backendFieldValues['id']))
{
- $templateConfigTable->save($templateConfigTable);
+ $templateConfigTable->id = $backendFieldValues['id'];
}
- else
+
+ // Save backend in config table
+ if (!$templateConfigTable->store())
{
- $templateConfigTable->id = $backendFieldValues['id'];
- $templateConfigTable->save($templateConfigTable);
+ $this->setError($templateConfigTable->getError());
+ return false;
}
}
}
@@ -716,7 +777,7 @@ public function updateTemplates($template, $client)
$templateConfigTable->updated_on = '';
$templateConfigTable->is_override = 0;
$templateConfigTable->params = json_encode([]);
- $templateConfigTable->save($templateConfigTable);
+ $templateConfigTable->store();
}
}
}