diff --git a/src/com_tjnotifications/admin/controllers/notification.php b/src/com_tjnotifications/admin/controllers/notification.php index 6c25cb27..adb9f951 100644 --- a/src/com_tjnotifications/admin/controllers/notification.php +++ b/src/com_tjnotifications/admin/controllers/notification.php @@ -36,7 +36,7 @@ class TjnotificationsControllerNotification extends FormController public function save($key = null, $urlVar = '') { // Check for request forgeries. - Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + Session::checkToken() or Factory::getApplication()->close(); // Initialise variables. $app = Factory::getApplication(); @@ -407,7 +407,7 @@ public function cancel($key = null) public function add($key = null, $urlVar = null) { // Check for request forgeries - Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + Session::checkToken() or Factory::getApplication()->close(); $input = Factory::getApplication()->input; $extension = $input->get('extension', '', 'STRING'); diff --git a/src/com_tjnotifications/admin/controllers/notifications.php b/src/com_tjnotifications/admin/controllers/notifications.php index a2f57354..091dde04 100644 --- a/src/com_tjnotifications/admin/controllers/notifications.php +++ b/src/com_tjnotifications/admin/controllers/notifications.php @@ -53,7 +53,7 @@ public function getModel($name = 'Notification', $prefix = 'TjnotificationsModel public function delete() { // Check for request forgeries - Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + Session::checkToken() or Factory::getApplication()->close(); $mainframe = Factory::getApplication(); $input = $mainframe->input; diff --git a/src/com_tjnotifications/admin/controllers/subscription.php b/src/com_tjnotifications/admin/controllers/subscription.php index 2849415a..7d1fa39a 100644 --- a/src/com_tjnotifications/admin/controllers/subscription.php +++ b/src/com_tjnotifications/admin/controllers/subscription.php @@ -68,7 +68,7 @@ public function __construct() public function save($key = null, $urlVar = '') { // Check for request forgeries. - Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + Session::checkToken() or Factory::getApplication()->close(); // Initialise variables. $app = Factory::getApplication(); diff --git a/src/com_tjnotifications/admin/helpers/tjnotifications.php b/src/com_tjnotifications/admin/helpers/tjnotifications.php index 5f6b9969..c5a95041 100644 --- a/src/com_tjnotifications/admin/helpers/tjnotifications.php +++ b/src/com_tjnotifications/admin/helpers/tjnotifications.php @@ -13,7 +13,7 @@ use Joomla\CMS\Language\Text; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Factory; -use Joomla\CMS\Filesystem\Path; +use Joomla\Filesystem\Path; use Joomla\CMS\Helper\ContentHelper; /** 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 b5c6f9df..42163815 100644 --- a/src/com_tjnotifications/admin/language/en-GB.com_tjnotifications.ini +++ b/src/com_tjnotifications/admin/language/en-GB.com_tjnotifications.ini @@ -311,16 +311,3 @@ 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." - -; 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/fields/backends.php b/src/com_tjnotifications/admin/models/fields/backends.php index 3b2e5a90..489dac41 100644 --- a/src/com_tjnotifications/admin/models/fields/backends.php +++ b/src/com_tjnotifications/admin/models/fields/backends.php @@ -13,15 +13,14 @@ use Joomla\CMS\Form\FormHelper; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; - -FormHelper::loadFieldClass('list'); +use Joomla\CMS\Form\Field\ListField; /** * Supports an HTML select list of backends * * @since 2.0.0 */ -class JFormFieldBackends extends JFormFieldList +class JFormFieldBackends extends ListField { /** * The form field type. @@ -34,7 +33,7 @@ class JFormFieldBackends extends JFormFieldList /** * Method to get a list of options for a list input. * - * @return array An array of JHtml options. + * @return array An array of HTMLHelper options. * * @since 2.0.0 */ @@ -55,7 +54,7 @@ protected function getOptions() /** * Method to get a list of options for a list input externally and not from xml. * - * @return array An array of JHtml options. + * @return array An array of HTMLHelper options. * * @since 2.1 */ diff --git a/src/com_tjnotifications/admin/models/fields/clients.php b/src/com_tjnotifications/admin/models/fields/clients.php index 41bc2fec..01976c6b 100644 --- a/src/com_tjnotifications/admin/models/fields/clients.php +++ b/src/com_tjnotifications/admin/models/fields/clients.php @@ -14,20 +14,19 @@ use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Factory; - -FormHelper::loadFieldClass('list'); +use Joomla\CMS\Form\Field\ListField; /** * Custom field to list all client of tjnotification * * @since 2.0.1 */ -class JFormFieldClients extends JFormFieldList +class JFormFieldClients extends ListField { /** * Method to get a list of options for a list input. * - * @return array An array of JHtml options. + * @return array An array of HTMLHelper options. * * @since 2.0.1 */ diff --git a/src/com_tjnotifications/admin/models/fields/mobilenumberfields.php b/src/com_tjnotifications/admin/models/fields/mobilenumberfields.php index f600e2fd..0531a401 100644 --- a/src/com_tjnotifications/admin/models/fields/mobilenumberfields.php +++ b/src/com_tjnotifications/admin/models/fields/mobilenumberfields.php @@ -26,7 +26,7 @@ * @since 2.0.1 */ -class JFormFieldMobilenumberfields extends JFormFieldGroupedList +class JFormFieldMobilenumberfields extends GroupedlistField { /** * The form field type. @@ -54,7 +54,10 @@ class JFormFieldMobilenumberfields extends JFormFieldGroupedList protected function getGroups() { // Load fields helper - JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR . '/components/com_fields/helpers/fields.php'); + $fieldsHelperPath = JPATH_ADMINISTRATOR . '/components/com_fields/helpers/fields.php'; + if (file_exists($fieldsHelperPath)) { + require_once $fieldsHelperPath; + } // Get custom field names by users $customFieldnames = FieldsHelper::getFields('com_users.user'); diff --git a/src/com_tjnotifications/admin/models/fields/platforms.php b/src/com_tjnotifications/admin/models/fields/platforms.php index 4788623d..8e523ee9 100644 --- a/src/com_tjnotifications/admin/models/fields/platforms.php +++ b/src/com_tjnotifications/admin/models/fields/platforms.php @@ -13,15 +13,14 @@ use Joomla\CMS\Form\FormHelper; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; - -FormHelper::loadFieldClass('list'); +use Joomla\CMS\Form\Field\ListField; /** * Supports an HTML select list of platforms * * @since 2.0.0 */ -class JFormFieldPlatforms extends JFormFieldList +class JFormFieldPlatforms extends ListField { /** * The form field type. @@ -34,7 +33,7 @@ class JFormFieldPlatforms extends JFormFieldList /** * Method to get a list of options for a list input. * - * @return array An array of JHtml options. + * @return array An array of HTMLHelper options. * * @since 2.0.0 */ @@ -53,7 +52,7 @@ protected function getOptions() /** * Method to get a list of options for a list input externally and not from xml. * - * @return array An array of JHtml options. + * @return array An array of HTMLHelper options. * * @since 2.1 */ diff --git a/src/com_tjnotifications/admin/models/fields/tjnotificationsbackends.php b/src/com_tjnotifications/admin/models/fields/tjnotificationsbackends.php index 65a84038..37bce467 100644 --- a/src/com_tjnotifications/admin/models/fields/tjnotificationsbackends.php +++ b/src/com_tjnotifications/admin/models/fields/tjnotificationsbackends.php @@ -13,15 +13,14 @@ use Joomla\CMS\Form\FormHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\HTML\HTMLHelper; - -FormHelper::loadFieldClass('list'); +use Joomla\CMS\Form\Field\ListField; /** * Supports an HTML select list of backends * * @since 2.0.0 */ -class JFormFieldTjnotificationsbackends extends JFormFieldList +class JFormFieldTjnotificationsbackends extends ListField { /** * The form field type. @@ -34,7 +33,7 @@ class JFormFieldTjnotificationsbackends extends JFormFieldList /** * Method to get a list of options for a list input. * - * @return array An array of JHtml options. + * @return array An array of HTMLHelper options. * * @since 2.0.0 */ diff --git a/src/com_tjnotifications/admin/models/forms/emailfields.xml b/src/com_tjnotifications/admin/models/forms/emailfields.xml index d2ea987f..ad22b779 100644 --- a/src/com_tjnotifications/admin/models/forms/emailfields.xml +++ b/src/com_tjnotifications/admin/models/forms/emailfields.xml @@ -5,30 +5,33 @@ name="id" type="hidden" /> - - - + + + - + - + diff --git a/src/com_tjnotifications/admin/models/forms/pushfields.xml b/src/com_tjnotifications/admin/models/forms/pushfields.xml index 882a1964..8b69739d 100644 --- a/src/com_tjnotifications/admin/models/forms/pushfields.xml +++ b/src/com_tjnotifications/admin/models/forms/pushfields.xml @@ -5,24 +5,26 @@ name="id" type="hidden" /> - - - + + + - + diff --git a/src/com_tjnotifications/admin/models/forms/smsfields.xml b/src/com_tjnotifications/admin/models/forms/smsfields.xml index 8fb7c046..b4600b07 100644 --- a/src/com_tjnotifications/admin/models/forms/smsfields.xml +++ b/src/com_tjnotifications/admin/models/forms/smsfields.xml @@ -5,25 +5,27 @@ name="id" type="hidden" /> - - - + + + - + - - - + + + - + diff --git a/src/com_tjnotifications/admin/models/forms/whatsappfields.xml b/src/com_tjnotifications/admin/models/forms/whatsappfields.xml index e6b3d87d..25cd9055 100644 --- a/src/com_tjnotifications/admin/models/forms/whatsappfields.xml +++ b/src/com_tjnotifications/admin/models/forms/whatsappfields.xml @@ -5,23 +5,25 @@ name="id" type="hidden" /> - - - + + + - + diff --git a/src/com_tjnotifications/admin/models/notification.php b/src/com_tjnotifications/admin/models/notification.php index a4ba1a31..c34797ba 100644 --- a/src/com_tjnotifications/admin/models/notification.php +++ b/src/com_tjnotifications/admin/models/notification.php @@ -321,8 +321,7 @@ public function updateReplacementTags($data) */ public function save($data) { - // Determine if this is a new record or edit - $isNew = empty($data['id']) || $data['id'] == 0; + $isNew = true; // 1 - save template first if (!empty($data)) @@ -346,28 +345,30 @@ 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(); - - // Get the template ID - use insertid() for new records, or the existing ID for edits - if ($isNew) { - $templateId = $db->insertid(); - } else { + $db = Factory::getDbo(); + // IMPORTANT to set new id in state, it is fetched in controller later + // Get current Template id - Fix for existing records + if (!empty($data['id'])) + { $templateId = $data['id']; + $isNew = false; + } + else + { + $templateId = $db->insertid(); } - // IMPORTANT to set new id in state, it is fetched in controller later $this->setState('com_tjnotifications.edit.notification.id', $templateId); $this->setState('com_tjnotifications.edit.notification.new', $isNew); } if (empty($templateId)) { + $this->setError(Text::_('COM_TJNOTIFICATIONS_ERROR_TEMPLATE_ID_MISSING')); return false; } @@ -386,7 +387,13 @@ public function save($data) { // 2.1 Check if current backend exists in posted data // If not $data['email'] or $data['sms'] - if (empty($data[$backend])) + if (empty($data[$backend]) || !isset($data[$backend][$backend . 'fields'])) + { + continue; + } + + // Validate backend data structure + if (!is_array($data[$backend][$backend . 'fields'])) { continue; } @@ -406,57 +413,25 @@ 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) { - // Backend-specific validation - only validate when backend is enabled - if ($data[$backend]['state']) + // Webhook stuff starts here + if ($backend == 'webhook' && $data[$backend]['state']) { - // Common validation for all backends - if (empty($backendFieldValues['language'])) + // If not using global webhook URLs & custom webhooks URLs are also empty + if (empty($backendFieldValues['use_global_webhook_url']) && empty($backendFieldValues['webhook_url'])) { - $errorKey = 'COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_' . strtoupper($backend) . '_LANGUAGE_REQUIRED'; - $this->setError(Text::_($errorKey)); + $this->setError(Text::_('COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_CUSTOM_WEBHOOK_URLS')); return false; } - - if (empty($backendFieldValues['body'])) + // If using global webhook URL & the global URLs are empty + elseif ($backendFieldValues['use_global_webhook_url'] && empty($webhookUrls[0])) { - $errorKey = 'COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_' . strtoupper($backend) . '_BODY_REQUIRED'; - $this->setError(Text::_($errorKey)); + $this->setError(Text::_('COM_TJNOTIFICATIONS_TEMPLATE_ERR_MSG_GLOBAL_WEBHOOK_URLS')); 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; - } - } } - // Backend validation ends here + // Webhook stuff ends here // Iterate through each lang. specific config entry foreach ($existingBackendConfigs as $existingBackendConfig) @@ -495,22 +470,44 @@ public function save($data) $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'] : ''; + $date = Factory::getDate(); + $currentDateTime = $date->toSql(true); + + // Always use current datetime for backend configs to avoid empty string issues + $createdOn = $currentDateTime; + $updatedOn = $currentDateTime; // 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) { + // Validate backend field values + if (!is_array($backendFieldValues) || empty($backendFieldValues)) + { + continue; + } + $templateConfigTable = Table::getInstance('Template', 'TjnotificationTable', array('dbo', $db)); - $templateConfigTable->load(array('template_id' => $templateId, 'backend' => $backendName)); + $isExistingRecord = $templateConfigTable->load(array('template_id' => $templateId, 'backend' => $backend)); // 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 with proper values + // For existing records, only update the updated_on field + if ($isExistingRecord && !empty($templateConfigTable->created_on)) + { + $templateConfigTable->updated_on = $updatedOn; + // Keep existing created_on value + } + else + { + // For new records, set both created_on and updated_on + $templateConfigTable->created_on = $createdOn; + $templateConfigTable->updated_on = $updatedOn; + } // Get params data // State, emailfields / smsfields @@ -546,14 +543,30 @@ public function save($data) } // Save backend in config table - if (empty($backendFieldValues['id'])) + try { - $templateConfigTable->save($templateConfigTable); + if (empty($backendFieldValues['id'])) + { + if (!$templateConfigTable->save($templateConfigTable)) + { + $this->setError(Text::sprintf('COM_TJNOTIFICATIONS_ERROR_SAVE_BACKEND_CONFIG', $backend, $templateConfigTable->getError())); + return false; + } + } + else + { + $templateConfigTable->id = $backendFieldValues['id']; + if (!$templateConfigTable->save($templateConfigTable)) + { + $this->setError(Text::sprintf('COM_TJNOTIFICATIONS_ERROR_SAVE_BACKEND_CONFIG', $backend, $templateConfigTable->getError())); + return false; + } + } } - else + catch (Exception $e) { - $templateConfigTable->id = $backendFieldValues['id']; - $templateConfigTable->save($templateConfigTable); + $this->setError(Text::sprintf('COM_TJNOTIFICATIONS_ERROR_SAVE_BACKEND_CONFIG', $backend, $e->getMessage())); + return false; } } } @@ -763,4 +776,4 @@ public function updateTemplates($template, $client) } } } -} +} \ No newline at end of file diff --git a/src/com_tjnotifications/admin/models/subscription.php b/src/com_tjnotifications/admin/models/subscription.php index 6b8e0caf..33554269 100644 --- a/src/com_tjnotifications/admin/models/subscription.php +++ b/src/com_tjnotifications/admin/models/subscription.php @@ -156,7 +156,7 @@ protected function prepareTable($table) { $db = Factory::getDbo(); $db->setQuery('SELECT MAX(ordering) FROM #__tjnotifications_subscriptions'); - $max = $db->loadResult(); + $max = $db->loadColumn()[0] ?? null; $table->ordering = $max + 1; } } diff --git a/src/com_tjnotifications/admin/views/logs/tmpl/default.php b/src/com_tjnotifications/admin/views/logs/tmpl/default.php index 24840660..7caeb110 100644 --- a/src/com_tjnotifications/admin/views/logs/tmpl/default.php +++ b/src/com_tjnotifications/admin/views/logs/tmpl/default.php @@ -17,7 +17,8 @@ use Joomla\CMS\Router\Route; HTMLHelper::_('bootstrap.renderModal', 'a.modal'); -HTMLHelper::_('formbehavior.chosen', 'select'); +HTMLHelper::_('behavior.multiselect'); // only for list tables + $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); diff --git a/src/com_tjnotifications/admin/views/logs/view.csv.php b/src/com_tjnotifications/admin/views/logs/view.csv.php index 1acbfaa5..38905422 100644 --- a/src/com_tjnotifications/admin/views/logs/view.csv.php +++ b/src/com_tjnotifications/admin/views/logs/view.csv.php @@ -10,7 +10,7 @@ // No direct access defined('_JEXEC') or die('Restricted access'); -jimport('techjoomla.view.csv'); +require_once JPATH_LIBRARIES . '/techjoomla/view/csv.php'; /** * View class for a list of notifications logs. diff --git a/src/com_tjnotifications/admin/views/logs/view.html.php b/src/com_tjnotifications/admin/views/logs/view.html.php index 6b127247..53fb4b3e 100644 --- a/src/com_tjnotifications/admin/views/logs/view.html.php +++ b/src/com_tjnotifications/admin/views/logs/view.html.php @@ -17,7 +17,10 @@ use Joomla\CMS\Helper\ContentHelper; use Joomla\CMS\HTML\HTMLHelper; -JLoader::register('TjnotificationsHelper', JPATH_ADMINISTRATOR . '/components/com_tjnotifications/helpers/tjnotifications.php'); +$tjnotificationsHelperPath = JPATH_ADMINISTRATOR . '/components/com_tjnotifications/helpers/tjnotifications.php'; +if (file_exists($tjnotificationsHelperPath)) { + require_once $tjnotificationsHelperPath; +} /** * View class for a list of notifications logs. @@ -50,7 +53,7 @@ public function display($tpl = null) // Check for errors. if (count($errors = $this->get('Errors'))) { - JError::raiseError(500, implode('
', $errors)); + throw new \Exception(implode('
', $errors), 500); return false; } @@ -59,7 +62,7 @@ public function display($tpl = null) TjnotificationsHelper::addSubmenu('logs'); $this->addToolBar(); - $this->sidebar = JHtmlSidebar::render(); + $this->sidebar = '';; parent::display($tpl); } @@ -78,7 +81,7 @@ protected function addToolBar() if ($this->canDo->get('core.export')) { // Adding techjoomla library for csv Export - jimport('techjoomla.tjtoolbar.button.csvexport'); + require_once JPATH_LIBRARIES . '/techjoomla/tjtoolbar/button/csvexport.php'; $bar = Toolbar::getInstance('toolbar'); diff --git a/src/com_tjnotifications/admin/views/notification/view.html.php b/src/com_tjnotifications/admin/views/notification/view.html.php index 301c0fcf..1c7ab11a 100644 --- a/src/com_tjnotifications/admin/views/notification/view.html.php +++ b/src/com_tjnotifications/admin/views/notification/view.html.php @@ -16,7 +16,10 @@ use Joomla\CMS\Router\Route; use Joomla\CMS\Toolbar\ToolbarHelper; -JLoader::import('preferences', JPATH_SITE . '/components/com_tjnotifications/models'); +$preferencesPath = JPATH_SITE . '/components/com_tjnotifications/models/preferences.php'; +if (file_exists($preferencesPath)) { + require_once $preferencesPath; +} /** * new notification View @@ -56,7 +59,7 @@ public function display($tpl = null) if (empty($this->user->authorise('core.create', 'com_tjnotifications')) || empty($this->user->authorise('core.edit', 'com_tjnotifications'))) { $msg = Text::_('JERROR_ALERTNOAUTHOR'); - JError::raiseError(403, $msg); + throw new \Exception($msg, 403); $this->app->redirect(Route::_('index.php?Itemid=0', false)); } @@ -74,18 +77,18 @@ public function display($tpl = null) // Check for errors. if (count($errors = $this->get('Errors'))) { - JError::raiseError(500, implode('
', $errors)); + throw new \Exception(implode('
', $errors), 500); return false; } - $this->addToolBar(); + $this->addToolbar(); $extension = $this->app->input->getCmd('extension', ''); if ($extension) { - $this->_setToolBar(); + $this->_setToolbar(); } parent::display($tpl); @@ -98,7 +101,7 @@ public function display($tpl = null) * * @since 1.6 */ - protected function addToolBar() + protected function addToolbar() { Factory::getApplication()->input->set('hidemainmenu', true); @@ -113,29 +116,29 @@ protected function addToolBar() $checkedOut = false; } - JToolBarHelper::title(Text::_('COM_TJNOTIFICATIONS'), 'edit.png'); + ToolbarHelper::title(Text::_('COM_TJNOTIFICATIONS'), 'edit.png'); // If not checked out, can save the item. if (!$checkedOut) { - JToolBarHelper::apply('notification.apply', 'JTOOLBAR_APPLY'); - JToolBarHelper::save('notification.save', 'JTOOLBAR_SAVE'); - JToolBarHelper::custom('notification.save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false); + ToolbarHelper::apply('notification.apply', 'JTOOLBAR_APPLY'); + ToolbarHelper::save('notification.save', 'JTOOLBAR_SAVE'); + ToolbarHelper::custom('notification.save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false); } // If an existing item, can save to a copy. if (!$isNew) { - JToolBarHelper::custom('notification.save2copy', 'save-copy.png', 'save-copy_f2.png', 'JTOOLBAR_SAVE_AS_COPY', false); + ToolbarHelper::custom('notification.save2copy', 'save-copy.png', 'save-copy_f2.png', 'JTOOLBAR_SAVE_AS_COPY', false); } if (empty($this->item->id)) { - JToolBarHelper::cancel('notification.cancel', 'JTOOLBAR_CANCEL'); + ToolbarHelper::cancel('notification.cancel', 'JTOOLBAR_CANCEL'); } else { - JToolBarHelper::cancel('notification.cancel', 'JTOOLBAR_CLOSE'); + ToolbarHelper::cancel('notification.cancel', 'JTOOLBAR_CLOSE'); } } @@ -146,7 +149,7 @@ protected function addToolBar() * * @since 1.8 */ - public function _setToolBar() + public function _setToolbar() { $component = $this->state->get('filter.component'); $section = $this->state->get('filter.section'); diff --git a/src/com_tjnotifications/admin/views/notifications/tmpl/default_bs2.php b/src/com_tjnotifications/admin/views/notifications/tmpl/default_bs2.php index b49ae826..0920097e 100644 --- a/src/com_tjnotifications/admin/views/notifications/tmpl/default_bs2.php +++ b/src/com_tjnotifications/admin/views/notifications/tmpl/default_bs2.php @@ -17,7 +17,8 @@ use Joomla\CMS\Router\Route; use Joomla\CMS\Uri\Uri; -HTMLHelper::_('formbehavior.chosen', 'select'); +HTMLHelper::_('behavior.multiselect'); // only for list tables + $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); diff --git a/src/com_tjnotifications/admin/views/notifications/view.html.php b/src/com_tjnotifications/admin/views/notifications/view.html.php index e668c2df..cae1527e 100644 --- a/src/com_tjnotifications/admin/views/notifications/view.html.php +++ b/src/com_tjnotifications/admin/views/notifications/view.html.php @@ -17,6 +17,7 @@ use Joomla\CMS\MVC\Model\BaseDatabaseModel; use Joomla\CMS\MVC\View\HtmlView; use Joomla\CMS\Router\Route; +use Joomla\CMS\Toolbar\Toolbar; use Joomla\CMS\Toolbar\ToolbarHelper; /** @@ -44,6 +45,8 @@ class TjnotificationsViewNotifications extends HtmlView public $user; + public $sidebar; + /** * Display the view * @@ -62,8 +65,7 @@ public function display($tpl = null) if (empty($this->user->authorise('core.viewlist', 'com_tjnotifications'))) { $msg = Text::_('JERROR_ALERTNOAUTHOR'); - JError::raiseError(403, $msg); - $this->app->redirect(Route::_('index.php?Itemid=0', false)); + throw new \Exception($msg, 403); } // Get data from the model @@ -78,15 +80,13 @@ public function display($tpl = null) // Check for errors. if (count($errors = $this->get('Errors'))) { - JError::raiseError(500, implode('
', $errors)); - - return false; + throw new \Exception(implode('
', $errors), 500); } // Set the tool-bar and number of found items - $this->addToolBar(); + $this->addToolbar(); - $extension = Factory::getApplication()->input->getCmd('extension', ''); + $extension = $this->app->input->getCmd('extension', ''); BaseDatabaseModel::addIncludePath(JPATH_SITE . '/components/com_tjnotifications/models'); $model = AdminModel::getInstance('Preferences', 'TJNotificationsModel'); @@ -101,13 +101,30 @@ public function display($tpl = null) TjnotificationsHelper::addSubmenu('notifications'); } - $this->_setToolBar(); - $this->sidebar = JHtmlSidebar::render(); + $this->_setToolbar(); + + // Joomla 6 compatible sidebar rendering + $this->sidebar = $this->renderSidebar(); } parent::display($tpl); } + /** + * Render the sidebar for Joomla 6 + * + * @return string The rendered sidebar HTML + * + * @since 2.0.0 + */ + protected function renderSidebar() + { + // Joomla 4+ doesn't use sidebars in the same way as Joomla 3 + // The addSubmenu() method handles submenu registration + // Return empty string as sidebar is handled by Joomla core + return ''; + } + /** * Add the page title and toolbar. * @@ -115,7 +132,7 @@ public function display($tpl = null) * * @since 0.0.1 */ - protected function addToolBar() + protected function addToolbar() { $title = Text::_('COM_TJNOTIFICATIONS'); @@ -139,7 +156,9 @@ protected function addToolBar() if ($this->user->authorise('core.delete', 'com_tjnotifications')) { ToolbarHelper::deleteList( - Text::_('COM_TJNOTIFICATIONS_VIEW_NOTIFICATIONS_DELETE_MESSAGE'), 'notifications.delete', Text::_('COM_TJNOTIFICATIONS_VIEW_NOTIFICATIONS_DELETE') + Text::_('COM_TJNOTIFICATIONS_VIEW_NOTIFICATIONS_DELETE_MESSAGE'), + 'notifications.delete', + Text::_('COM_TJNOTIFICATIONS_VIEW_NOTIFICATIONS_DELETE') ); } @@ -156,7 +175,7 @@ protected function addToolBar() * * @since 1.8 */ - public function _setToolBar() + public function _setToolbar() { $component = $this->state->get('filter.component'); $section = $this->state->get('filter.section'); @@ -166,6 +185,7 @@ public function _setToolBar() { return; } + // Need to load the menu language file as mod_menu hasn't been loaded yet. $lang = Factory::getLanguage(); $lang->load($component, JPATH_BASE, null, false, true) @@ -177,17 +197,20 @@ public function _setToolBar() $title = Text::_($component_title_key); } elseif ($lang->hasKey($component_section_key = strtoupper($component . ($section ? "_$section" : '')))) - // Else if the component section string exits, let's use it { + // Else if the component section string exits, let's use it $title = Text::sprintf('COM_TJNOTIFICATIONS_NOTIFICATION_TITLE', $this->escape(Text::_($component_section_key))); } else - // Else use the base title { + // Else use the base title $title = Text::_('COM_TJNOTIFICATIONS_NOTIFICATION_BASE_TITLE'); } // Prepare the toolbar. - ToolbarHelper::title($title, 'folder notifications ' . substr($component, 4) . ($section ? "-$section" : '') . '-notification templates'); + ToolbarHelper::title( + $title, + 'folder notifications ' . substr($component, 4) . ($section ? "-$section" : '') . '-notification templates' + ); } -} +} \ No newline at end of file diff --git a/src/com_tjnotifications/admin/views/subscription/tmpl/edit.php b/src/com_tjnotifications/admin/views/subscription/tmpl/edit.php index 0c5ba5aa..5077a634 100644 --- a/src/com_tjnotifications/admin/views/subscription/tmpl/edit.php +++ b/src/com_tjnotifications/admin/views/subscription/tmpl/edit.php @@ -18,7 +18,8 @@ HTMLHelper::_('behavior.keepalive'); HTMLHelper::_('behavior.formvalidator'); -HTMLHelper::_('formbehavior.chosen', 'select'); +HTMLHelper::_('behavior.multiselect'); // only for list tables + HTMLHelper::_('bootstrap.tooltip'); $doc = Factory::getDocument(); diff --git a/src/com_tjnotifications/admin/views/subscription/view.html.php b/src/com_tjnotifications/admin/views/subscription/view.html.php index a814ded9..53537dfd 100644 --- a/src/com_tjnotifications/admin/views/subscription/view.html.php +++ b/src/com_tjnotifications/admin/views/subscription/view.html.php @@ -132,33 +132,33 @@ protected function addToolbar() $canDo = ContentHelper::getActions('com_tjnotifications', '', 0); - JToolBarHelper::title(Text::_('COM_TJNOTIFICATIONS_SUBSCRIPTION_PAGE_TITLE'), 'edit.png'); + ToolbarHelper::title(Text::_('COM_TJNOTIFICATIONS_SUBSCRIPTION_PAGE_TITLE'), 'edit.png'); // If not checked out, can save the item. if (!$checkedOut && ($canDo->get('core.edit') || ($canDo->get('core.create')))) { - JToolBarHelper::apply('subscription.apply', 'JTOOLBAR_APPLY'); - JToolBarHelper::save('subscription.save', 'JTOOLBAR_SAVE'); + ToolbarHelper::apply('subscription.apply', 'JTOOLBAR_APPLY'); + ToolbarHelper::save('subscription.save', 'JTOOLBAR_SAVE'); } if (!$checkedOut && ($canDo->get('core.create'))) { - JToolBarHelper::custom('subscription.save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false); + ToolbarHelper::custom('subscription.save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false); } // If an existing item, can save to a copy. if (!$isNew && $canDo->get('core.create')) { - JToolBarHelper::custom('subscription.save2copy', 'save-copy.png', 'save-copy_f2.png', 'JTOOLBAR_SAVE_AS_COPY', false); + ToolbarHelper::custom('subscription.save2copy', 'save-copy.png', 'save-copy_f2.png', 'JTOOLBAR_SAVE_AS_COPY', false); } if (empty($this->item->id)) { - JToolBarHelper::cancel('subscription.cancel', 'JTOOLBAR_CANCEL'); + ToolbarHelper::cancel('subscription.cancel', 'JTOOLBAR_CANCEL'); } else { - JToolBarHelper::cancel('subscription.cancel', 'JTOOLBAR_CLOSE'); + ToolbarHelper::cancel('subscription.cancel', 'JTOOLBAR_CLOSE'); } } } diff --git a/src/com_tjnotifications/admin/views/subscriptions/tmpl/default.php b/src/com_tjnotifications/admin/views/subscriptions/tmpl/default.php index 22d8f001..ede85aa7 100644 --- a/src/com_tjnotifications/admin/views/subscriptions/tmpl/default.php +++ b/src/com_tjnotifications/admin/views/subscriptions/tmpl/default.php @@ -18,7 +18,8 @@ use Joomla\CMS\Uri\Uri; HTMLHelper::_('behavior.multiselect'); -HTMLHelper::_('formbehavior.chosen', 'select'); +HTMLHelper::_('behavior.multiselect'); // only for list tables + HTMLHelper::_('bootstrap.tooltip'); $userId = $this->user->get('id'); diff --git a/src/com_tjnotifications/admin/views/subscriptions/view.html.php b/src/com_tjnotifications/admin/views/subscriptions/view.html.php index b32f06ba..7950cfa7 100644 --- a/src/com_tjnotifications/admin/views/subscriptions/view.html.php +++ b/src/com_tjnotifications/admin/views/subscriptions/view.html.php @@ -40,7 +40,7 @@ class TjnotificationsViewSubscriptions extends HtmlView protected $state; - protected $sidebar; + public $sidebar; protected $user; @@ -75,10 +75,27 @@ public function display($tpl = null) $this->addToolbar(); - $this->sidebar = JHtmlSidebar::render(); + // Joomla 6 compatible sidebar rendering + $this->sidebar = $this->renderSidebar(); + parent::display($tpl); } + /** + * Render the sidebar for Joomla 6 + * + * @return string The rendered sidebar HTML + * + * @since 2.0.0 + */ + protected function renderSidebar() + { + // Joomla 4+ doesn't use sidebars in the same way as Joomla 3 + // The addSubmenu() method handles submenu registration + // Return empty string as sidebar is handled by Joomla core + return ''; + } + /** * Add the page title and toolbar. * @@ -91,7 +108,8 @@ protected function addToolbar() $state = $this->get('State'); $canDo = ContentHelper::getActions('com_tjnotifications', '', 0); - JToolBarHelper::title(Text::_('COM_TJNOTIFICATIONS_SUBSCRIPTIONS_PAGE_TITLE'), 'list.png'); + // Updated for Joomla 6 - removed .png extension from icon + ToolbarHelper::title(Text::_('COM_TJNOTIFICATIONS_SUBSCRIPTIONS_PAGE_TITLE'), 'list'); // Check if the form exists before showing the add/edit buttons $formPath = JPATH_COMPONENT_ADMINISTRATOR . '/views/subscription'; @@ -100,17 +118,19 @@ protected function addToolbar() { if ($canDo->get('core.create')) { - JToolBarHelper::addNew('subscription.add', 'JTOOLBAR_NEW'); + // Updated for Joomla 6 - removed second parameter + ToolbarHelper::addNew('subscription.add'); /*if (isset($this->items[0])) { - ToolbarHelper::custom('subscription.duplicate', 'copy.png', 'copy_f2.png', 'JTOOLBAR_DUPLICATE', true); + ToolbarHelper::custom('subscription.duplicate', 'copy', '', 'TOOLBAR_DUPLICATE', true); }*/ } if ($canDo->get('core.edit') && isset($this->items[0])) { - JToolBarHelper::editList('subscription.edit', 'JTOOLBAR_EDIT'); + // Updated for Joomla 6 - removed second parameter + ToolbarHelper::editList('subscription.edit'); } } @@ -118,25 +138,27 @@ protected function addToolbar() { if (isset($this->items[0]->state)) { - JToolBarHelper::divider(); - JToolBarHelper::custom('subscriptions.publish', 'publish.png', 'publish_f2.png', 'JTOOLBAR_PUBLISH', true); - JToolBarHelper::custom('subscriptions.unpublish', 'unpublish.png', 'unpublish_f2.png', 'JTOOLBAR_UNPUBLISH', true); + ToolbarHelper::divider(); + // Updated for Joomla 6 - removed icon parameters + ToolbarHelper::publish('subscriptions.publish', 'JTOOLBAR_PUBLISH', true); + ToolbarHelper::unpublish('subscriptions.unpublish', 'JTOOLBAR_UNPUBLISH', true); } elseif (isset($this->items[0])) { // If this component does not use state then show a direct delete button as we can not trash - JToolBarHelper::deleteList('', 'subscriptions.delete', 'JTOOLBAR_DELETE'); + ToolbarHelper::deleteList('', 'subscriptions.delete', 'JTOOLBAR_DELETE'); } /*if (isset($this->items[0]->state)) { - JToolBarHelper::divider(); - JToolBarHelper::archiveList('subscriptions.archive', 'JTOOLBAR_ARCHIVE'); + ToolbarHelper::divider(); + ToolbarHelper::archiveList('subscriptions.archive'); }*/ if (isset($this->items[0]->checked_out)) { - JToolBarHelper::custom('subscriptions.checkin', 'checkin.png', 'checkin_f2.png', 'JTOOLBAR_CHECKIN', true); + // Updated for Joomla 6 - removed icon parameters + ToolbarHelper::checkin('subscriptions.checkin', 'JTOOLBAR_CHECKIN', true); } } @@ -145,23 +167,23 @@ protected function addToolbar() { if ($state->get('filter.state') == -2 && $canDo->get('core.delete')) { - JToolBarHelper::deleteList('', 'subscriptions.delete', 'JTOOLBAR_EMPTY_TRASH'); - JToolBarHelper::divider(); + ToolbarHelper::deleteList('', 'subscriptions.delete', 'JTOOLBAR_EMPTY_TRASH'); + ToolbarHelper::divider(); } elseif ($canDo->get('core.edit.state')) { - JToolBarHelper::trash('subscriptions.trash', 'JTOOLBAR_TRASH'); - JToolBarHelper::divider(); + ToolbarHelper::trash('subscriptions.trash'); + ToolbarHelper::divider(); } } if ($canDo->get('core.admin')) { - JToolBarHelper::preferences('com_tjnotifications'); + ToolbarHelper::preferences('com_tjnotifications'); } - // Set sidebar action - New in 3.0 - JHtmlSidebar::setAction('index.php?option=com_tjnotifications&view=subscriptions'); + // Note: Sidebar action setting removed as HTMLHelperSidebar is deprecated in Joomla 6 + // If you need to set action for filters, handle it in the form XML or template } /** @@ -189,4 +211,4 @@ public function getState($state) { return isset($this->state->{$state}) ? $this->state->{$state} : false; } -} +} \ No newline at end of file diff --git a/src/com_tjnotifications/install.tjnotifications.php b/src/com_tjnotifications/install.tjnotifications.php index 5630c7ab..016cacc3 100644 --- a/src/com_tjnotifications/install.tjnotifications.php +++ b/src/com_tjnotifications/install.tjnotifications.php @@ -11,13 +11,14 @@ defined('_JEXEC') or die; use Joomla\CMS\Installer\Installer; -use Joomla\Data\DataObject; +use Joomla\CMS\Installer\InstallerAdapter; use Joomla\CMS\Language\Text; -use Joomla\CMS\Filesystem\File; -use Joomla\CMS\Filesystem\Folder; -use \Joomla\CMS\Factory; -use \Joomla\CMS\Object\CMSObject; +use Joomla\Filesystem\File; +use Joomla\Filesystem\Folder; +use Joomla\CMS\Factory; use Joomla\CMS\Table\Table; +use Joomla\CMS\Log\Log; +use Joomla\Database\DatabaseInterface; /** * Script file of TJNotification component @@ -26,6 +27,21 @@ **/ class Com_TjnotificationsInstallerScript { + /** + * Database driver + * + * @var DatabaseInterface + */ + private $db; + + /** + * Constructor + */ + public function __construct() + { + $this->db = Factory::getContainer()->get(DatabaseInterface::class); + } + /** @var array The list of extra modules and plugins to install */ private $queue = array( // Plugins => { (folder) => { (element) => (published) }* }* @@ -71,11 +87,9 @@ public function install($parent) * * @return void */ - public function uninstall($parent) + public function uninstall(InstallerAdapter $parent): void { - - $db = Factory::getDBO(); - $status = new CMSObject; + $status = new \stdClass; $status->plugins = array(); $src = $parent->getParent()->getPath('source'); @@ -99,7 +113,7 @@ public function uninstall($parent) if ($id) { - $installer = new Installer; + $installer = new Installer(); $result = $installer->uninstall('plugin', $id); $status->plugins[] = array( 'name' => 'plg_' . $plugin, @@ -112,7 +126,6 @@ public function uninstall($parent) } } - return $status; } /** @@ -138,22 +151,21 @@ public function update($parent) * * @return void */ - private function addMissingColumns() + private function addMissingColumns(): void { - $db = Factory::getDbo(); - $columns = $db->getTableColumns('#__tj_notification_template_configs'); + $columns = $this->db->getTableColumns('#__tj_notification_template_configs'); if (!array_key_exists('webhook_url', $columns)) { - $db->setQuery("ALTER TABLE `#__tj_notification_template_configs` ADD COLUMN `webhook_url` text DEFAULT NULL AFTER `body`;"); - $db->execute(); + $this->db->setQuery("ALTER TABLE `#__tj_notification_template_configs` ADD COLUMN `webhook_url` text DEFAULT NULL AFTER `body`;"); + $this->db->execute(); } if (!array_key_exists('use_global_webhook_url', $columns)) { - $db->setQuery("ALTER TABLE `#__tj_notification_template_configs` ADD COLUMN `use_global_webhook_url` TINYINT(1) NOT NULL DEFAULT '1' COMMENT 'Use Global Config Webhook URLs' AFTER `webhook_url`;"); - $db->execute(); + $this->db->setQuery("ALTER TABLE `#__tj_notification_template_configs` ADD COLUMN `use_global_webhook_url` TINYINT(1) NOT NULL DEFAULT '1' COMMENT 'Use Global Config Webhook URLs' AFTER `webhook_url`;"); + $this->db->execute(); } - $columns = $db->getTableColumns('#__tj_notification_logs'); + $columns = $this->db->getTableColumns('#__tj_notification_logs'); if (!array_key_exists('webhook_url', $columns)) { - $db->setQuery("ALTER TABLE `#__tj_notification_logs` ADD COLUMN `webhook_url` TEXT NULL DEFAULT NULL AFTER `body`;"); - $db->execute(); + $this->db->setQuery("ALTER TABLE `#__tj_notification_logs` ADD COLUMN `webhook_url` TEXT NULL DEFAULT NULL AFTER `body`;"); + $this->db->execute(); } } @@ -180,8 +192,7 @@ public function preflight($type, $parent) public function postflight($type, $parent) { $src = $parent->getParent()->getPath('source'); - $db = Factory::getDbo(); - $status = new CMSObject; + $status = new \stdClass; $status->plugins = array(); // Plugins installation @@ -224,7 +235,7 @@ public function postflight($type, $parent) $db->setQuery($query); $count = $db->loadResult(); - $installer = new Installer; +$installer = new Installer(); $result = $installer->install($path); $status->plugins[] = array('name' => 'plg_' . $plugin, 'group' => $folder, 'result' => $result); @@ -259,10 +270,8 @@ public function postflight($type, $parent) * * @return void */ - public function installSqlFiles($parent) + public function installSqlFiles(InstallerAdapter $parent): bool { - $db = Factory::getDbo(); - // Obviously you may have to change the path and name if your installation SQL file if (method_exists($parent, 'extension_root')) { @@ -278,7 +287,7 @@ public function installSqlFiles($parent) if ($buffer !== false) { - $queries = \JDatabaseDriver::splitSql($buffer); + $queries = $this->db->splitSql($buffer); if (count($queries) != 0) { @@ -288,12 +297,19 @@ public function installSqlFiles($parent) if (!empty($query)) { - $db->setQuery($query); + $this->db->setQuery($query); - if (!$db->execute()) + try { - JError::raiseWarning(1, Text::sprintf('JLIB_INSTALLER_ERROR_SQL_ERROR', $db->stderr(true))); - + $this->db->execute(); + } + catch (\RuntimeException $e) + { + Log::add( + Text::sprintf('JLIB_INSTALLER_ERROR_SQL_ERROR', $e->getMessage()), + Log::WARNING, + 'jerror' + ); return false; } } @@ -301,11 +317,7 @@ public function installSqlFiles($parent) } } - $config = Factory::getConfig(); - $configdb = $config->get('db'); - - // Get dbprefix - $dbprefix = $config->get('dbprefix'); + return true; } /** diff --git a/src/com_tjnotifications/media/js/tjnotifications.js b/src/com_tjnotifications/media/js/tjnotifications.js index bf560a1e..9a06b778 100644 --- a/src/com_tjnotifications/media/js/tjnotifications.js +++ b/src/com_tjnotifications/media/js/tjnotifications.js @@ -81,7 +81,7 @@ var tjnotificationsAdmin = { var remainingCharLimit = maxSmsLength - curentSmsLength; var parentDiv = document.querySelector("#"+smsBodyId); var smsSubformFieldNum = smsBodyId.split("jform_sms__smsfields__smsfields")["1"].split("__")["0"]; - var remainingCharLimitMsg = (parseInt(remainingCharLimit) > 0 ) ? remainingCharLimit + " " + Joomla.JText._('COM_TJNOTIFICATIONS_NOTIFICATION_SMS_REMAINING_CHARACTER') : (remainingCharLimit * -1) + " " + Joomla.JText._('COM_TJNOTIFICATIONS_NOTIFICATION_SMS_REMAINING_EXCEEDED'); + var remainingCharLimitMsg = (parseInt(remainingCharLimit) > 0 ) ? remainingCharLimit + " " + Joomla.Text._('COM_TJNOTIFICATIONS_NOTIFICATION_SMS_REMAINING_CHARACTER') : (remainingCharLimit * -1) + " " + Joomla.Text._('COM_TJNOTIFICATIONS_NOTIFICATION_SMS_REMAINING_EXCEEDED'); if(parentDiv.parentNode.parentNode.parentNode.querySelector("p") !== null) { diff --git a/src/com_tjnotifications/media/js/tjnotifications.min.js b/src/com_tjnotifications/media/js/tjnotifications.min.js index 94ca064a..82c77f3d 100644 --- a/src/com_tjnotifications/media/js/tjnotifications.min.js +++ b/src/com_tjnotifications/media/js/tjnotifications.min.js @@ -6,4 +6,4 @@ * @license GNU General Public License version 2 or later. */ -var tjnotifications={},tjnotificationsAdmin={notification:{init:function(){jQuery(document).ready(function(){var e=document.getElementById("sms").querySelector(".ui-sortable").children;for(item of e)null!==item.querySelector("textarea")&&tjnotificationsAdmin.notification.validateSmsLength(item.querySelector("textarea"));document.formvalidator.setHandler("json",function(e){try{JSON.stringify(JSON.parse(e));return!0}catch(e){return!1}}),jQuery("fieldset").click(function(){if(status=this.id+"0",statusChange=this.id+"1","checked"==jQuery("#"+status).attr("checked")){var e=this.id.replace("status","body_ifr");if('
'==jQuery("#"+e).contents().find("body").find("p").html())return alert("Please fill the data"),jQuery("#"+this.id).find("label[for="+statusChange+"]").attr("class","btn active btn-danger"),jQuery("#"+this.id).find("label[for="+status+"]").attr("class","btn"),!1;jQuery("#"+this.id).find("label[for="+status+"]").attr("class","btn active btn-success"),jQuery("#"+this.id).find("label[for="+statusChange+"]").attr("class","btn")}}),jQuery(document).on("subform-row-add",function(e,t){var a=document.getElementById("sms").querySelector(".ui-sortable").children;for(item of a)null!==item.querySelector("textarea")&&tjnotificationsAdmin.notification.validateSmsLength(item.querySelector("textarea"))})})},validateSmsLength:function(e){var t=e.getAttribute("id"),a=160-jQuery("#"+t).val().length,r=document.querySelector("#"+t),i=t.split("jform_sms__smsfields__smsfields")[1].split("__")[0],s=parseInt(a)>0?a+" "+Joomla.JText._("COM_TJNOTIFICATIONS_NOTIFICATION_SMS_REMAINING_CHARACTER"):-1*a+" "+Joomla.JText._("COM_TJNOTIFICATIONS_NOTIFICATION_SMS_REMAINING_EXCEEDED");if(null!==r.parentNode.parentNode.parentNode.querySelector("p")){jQuery(".smsfieldsCharLimit"+i).text(s),r.parentNode.parentNode.parentNode.querySelector("p").getAttribute("class").split(" ").includes("alert-info")&&parseInt(a)<0?(jQuery(".smsfieldsCharLimit"+i).removeClass("alert-info"),jQuery(".smsfieldsCharLimit"+i).addClass("alert-danger")):(jQuery(".smsfieldsCharLimit"+i).removeClass("alert-danger"),jQuery(".smsfieldsCharLimit"+i).addClass("alert-info"))}else{var n=document.createElement("p");newPCustomClass="smsfieldsCharLimit"+i;var l=parseInt(a)>0?"alert-info":"alert-danger";n.setAttribute("class",l+" center "+newPCustomClass);var o=document.createTextNode(s);n.appendChild(o),r.parentNode.parentNode.parentNode.appendChild(n)}}}}; +var tjnotifications={},tjnotificationsAdmin={notification:{init:function(){jQuery(document).ready(function(){var e=document.getElementById("sms").querySelector(".ui-sortable").children;for(item of e)null!==item.querySelector("textarea")&&tjnotificationsAdmin.notification.validateSmsLength(item.querySelector("textarea"));document.formvalidator.setHandler("json",function(e){try{JSON.stringify(JSON.parse(e));return!0}catch(e){return!1}}),jQuery("fieldset").click(function(){if(status=this.id+"0",statusChange=this.id+"1","checked"==jQuery("#"+status).attr("checked")){var e=this.id.replace("status","body_ifr");if('
'==jQuery("#"+e).contents().find("body").find("p").html())return alert("Please fill the data"),jQuery("#"+this.id).find("label[for="+statusChange+"]").attr("class","btn active btn-danger"),jQuery("#"+this.id).find("label[for="+status+"]").attr("class","btn"),!1;jQuery("#"+this.id).find("label[for="+status+"]").attr("class","btn active btn-success"),jQuery("#"+this.id).find("label[for="+statusChange+"]").attr("class","btn")}}),jQuery(document).on("subform-row-add",function(e,t){var a=document.getElementById("sms").querySelector(".ui-sortable").children;for(item of a)null!==item.querySelector("textarea")&&tjnotificationsAdmin.notification.validateSmsLength(item.querySelector("textarea"))})})},validateSmsLength:function(e){var t=e.getAttribute("id"),a=160-jQuery("#"+t).val().length,r=document.querySelector("#"+t),i=t.split("jform_sms__smsfields__smsfields")[1].split("__")[0],s=parseInt(a)>0?a+" "+Joomla.Text._("COM_TJNOTIFICATIONS_NOTIFICATION_SMS_REMAINING_CHARACTER"):-1*a+" "+Joomla.Text._("COM_TJNOTIFICATIONS_NOTIFICATION_SMS_REMAINING_EXCEEDED");if(null!==r.parentNode.parentNode.parentNode.querySelector("p")){jQuery(".smsfieldsCharLimit"+i).text(s),r.parentNode.parentNode.parentNode.querySelector("p").getAttribute("class").split(" ").includes("alert-info")&&parseInt(a)<0?(jQuery(".smsfieldsCharLimit"+i).removeClass("alert-info"),jQuery(".smsfieldsCharLimit"+i).addClass("alert-danger")):(jQuery(".smsfieldsCharLimit"+i).removeClass("alert-danger"),jQuery(".smsfieldsCharLimit"+i).addClass("alert-info"))}else{var n=document.createElement("p");newPCustomClass="smsfieldsCharLimit"+i;var l=parseInt(a)>0?"alert-info":"alert-danger";n.setAttribute("class",l+" center "+newPCustomClass);var o=document.createTextNode(s);n.appendChild(o),r.parentNode.parentNode.parentNode.appendChild(n)}}}}; diff --git a/src/com_tjnotifications/site/controllers/preferences.php b/src/com_tjnotifications/site/controllers/preferences.php index e841058d..0b3e274e 100644 --- a/src/com_tjnotifications/site/controllers/preferences.php +++ b/src/com_tjnotifications/site/controllers/preferences.php @@ -48,7 +48,7 @@ public function save($key = null, $urlVar = '') $model = $this->getModel('Preferences', 'TJNotificationsModel'); $result = $model->save($data); echo json_encode($result); - jexit(); + Factory::getApplication()->close(); } /** @@ -76,6 +76,6 @@ public function delete() $model = $this->getModel('Preferences', 'TJNotificationsModel'); $result = $model->deletePreference($data); echo json_encode($result); - jexit(); + Factory::getApplication()->close(); } } diff --git a/src/com_tjnotifications/tjnotifications.xml b/src/com_tjnotifications/tjnotifications.xml index 4e362d92..743353e3 100644 --- a/src/com_tjnotifications/tjnotifications.xml +++ b/src/com_tjnotifications/tjnotifications.xml @@ -1,13 +1,13 @@ - + com_tjnotifications Techjoomla extensions@techjoomla.com https://techjoomla.com Copyright (C) 2016 - 2025 Techjoomla. All rights reserved. http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL - 14th Mar 2025 - 3.1.0 + 26th November 2025 + 6.0.0 sql/install.mysql.utf8.sql