-
-
diff --git a/src/admin/forms/filter_logs.xml b/src/admin/forms/filter_logs.xml new file mode 100644 index 00000000000..e2a1c2f2817 --- /dev/null +++ b/src/admin/forms/filter_logs.xml @@ -0,0 +1,125 @@ + +
\ No newline at end of file diff --git a/src/admin/language/en-GB/en-GB.com_kunena.views.ini b/src/admin/language/en-GB/en-GB.com_kunena.views.ini index a0c08a662de..ccf5013e334 100644 --- a/src/admin/language/en-GB/en-GB.com_kunena.views.ini +++ b/src/admin/language/en-GB/en-GB.com_kunena.views.ini @@ -1292,7 +1292,7 @@ COM_KUNENA_LOG_USER_UNBAN = "User Unbanned" COM_KUNENA_LOG_USER_UNBLOCK = "User Unblocked" COM_KUNENA_LOG_USER_WARNING = "User Warning" COM_KUNENA_LOG_CALENDAR_PLACEHOLDER_START_DATE = "Enter the start date" -COM_KUNENA_LOG_CALENDAR_PLACEHOLDER_END_DATE = "Enter the end date" +COM_KUNENA_LOG_CALENDAR_PLACEHOLDER_STOP_DATE = "Enter the stop date" COM_KUNENA_LOG_CLEAN_ENTRIES = "Clean entries" COM_KUNENA_CLEAN_LOGS_ENTRIES = "Clean" COM_KUNENA_LOG_CLEAN_DESC = "The clean log entries allow you to remove entries which are old from a specific days" @@ -1303,6 +1303,7 @@ COM_KUNENA_LOG_USER_REPORT_STOPFORUMSPAM = "Report to stop forum spam" COM_KUNENA_LOG_TOPIC_FAVORITE = "Favorite topic" COM_KUNENA_LOG_TOPIC_UNFAVORITE = "Unfavorite topic" COM_KUNENA_LOG_TIME_SORT_LABEL = "Time" +COM_KUNENA_LOG_OPERATION_SORT_LABEL = "Operation" COM_KUNENA_LOG_TYPE_SORT_LABEL = "Type" COM_KUNENA_LOG_USER_SORT_LABEL = "User" COM_KUNENA_LOG_CATEGORY_SORT_LABEL = "Category" @@ -1367,47 +1368,67 @@ COM_KUNENA_A_SMARTAUTOLINK = "Smart Auto Linking" COM_KUNENA_A_SMARTAUTOLINK_DESC = "Shows the real titles on the urls. (Can result a high cpu usage)" ; Back-end Filter strings -COM_KUNENA_FILTER_FIELD_USERNAME_ASC="Username Ascending" -COM_KUNENA_FILTER_FIELD_USERNAME_DESC="Username Descending" +COM_KUNENA_FILTER_FIELD_BANNED_ASC="Banned Ascending" +COM_KUNENA_FILTER_FIELD_BANNED_DESC="Banned Descending" +COM_KUNENA_FILTER_FIELD_CATEGORY_ASC="Category Ascending" +COM_KUNENA_FILTER_FIELD_CATEGORY_DESC="Category Descending" +COM_KUNENA_FILTER_FIELD_CODE_ASC="Code Ascending" +COM_KUNENA_FILTER_FIELD_CODE_DESC="Code Descending" COM_KUNENA_FILTER_FIELD_EMAIL_ASC="Email Ascending" COM_KUNENA_FILTER_FIELD_EMAIL_DESC="Email Descending" -COM_KUNENA_FILTER_FIELD_IP_ASC="IP Ascending" -COM_KUNENA_FILTER_FIELD_IP_DESC="IP Descending" -COM_KUNENA_FILTER_FIELD_RANK_ASC="Rank Ascending" -COM_KUNENA_FILTER_FIELD_RANK_DESC="Rank Descending" -COM_KUNENA_FILTER_FIELD_SIGNATURE_ASC="Signature Ascending" -COM_KUNENA_FILTER_FIELD_SIGNATURE_DESC="Signature Descending" COM_KUNENA_FILTER_FIELD_ENABLED_ASC="Enabled Ascending" COM_KUNENA_FILTER_FIELD_ENABLED_DESC="Enabled Descending" -COM_KUNENA_FILTER_FIELD_BANNED_ASC="Banned Ascending" -COM_KUNENA_FILTER_FIELD_BANNED_DESC="Banned Descending" -COM_KUNENA_FILTER_FIELD_MODERATOR_ASC="Moderator Ascending" -COM_KUNENA_FILTER_FIELD_MODERATOR_DESC="Moderator Descending" -COM_KUNENA_FILTER_SELECT_SIGNATURE="- Select Signature -" -COM_KUNENA_FILTER_SELECT_ENABLED="- Select Enabled -" -COM_KUNENA_FILTER_SELECT_BANNED="- Select Banned -" -COM_KUNENA_FILTER_SELECT_SPECIAL="- Select Special -" -COM_KUNENA_FILTER_SELECT_RANKSMIN="- Select Minimum Post Count -" -COM_KUNENA_FILTER_SELECT_MODERATOR="- Select Moderator -" -COM_KUNENA_TASK_BAN_USER="Ban User" -COM_KUNENA_TASK_UNBAN_USER="Unban User" -COM_KUNENA_TASK_UNBLOCK_USER="Enable User" -COM_KUNENA_TASK_BLOCK_USER="Block User" COM_KUNENA_FILTER_FIELD_FILENAME_ASC="Filename Ascending" COM_KUNENA_FILTER_FIELD_FILENAME_DESC="Filename Descending" -COM_KUNENA_FILTER_FIELD_FILETYPE_ASC="Filetype Ascending" -COM_KUNENA_FILTER_FIELD_FILETYPE_DESC="Filetype Descending" COM_KUNENA_FILTER_FIELD_FILESIZE_ASC="Filesize Ascending" COM_KUNENA_FILTER_FIELD_FILESIZE_DESC="Filesize Descending" +COM_KUNENA_FILTER_FIELD_FILETYPE_ASC="Filetype Ascending" +COM_KUNENA_FILTER_FIELD_FILETYPE_DESC="Filetype Descending" +COM_KUNENA_FILTER_FIELD_IP_ASC="IP Ascending" +COM_KUNENA_FILTER_FIELD_IP_DESC="IP Descending" +COM_KUNENA_FILTER_FIELD_MODERATOR_ASC="Moderator Ascending" +COM_KUNENA_FILTER_FIELD_MODERATOR_DESC="Moderator Descending" +COM_KUNENA_FILTER_FIELD_OPERATION_ASC="Operation Ascending" +COM_KUNENA_FILTER_FIELD_OPERATION_DESC="Operation Descending" COM_KUNENA_FILTER_FIELD_POST_ASC="Message Ascending" COM_KUNENA_FILTER_FIELD_POST_DESC="Message Descending" -COM_KUNENA_FILTER_FIELD_RANKTITLE_ASC="Title Ascending" -COM_KUNENA_FILTER_FIELD_RANKTITLE_DESC="Title Descending" -COM_KUNENA_FILTER_FIELD_RANKSPECIAL_ASC="Special Ascending" -COM_KUNENA_FILTER_FIELD_RANKSPECIAL_DESC="Special Descending" COM_KUNENA_FILTER_FIELD_RANKSMIN_ASC="Minimum Post Count Ascending" COM_KUNENA_FILTER_FIELD_RANKSMIN_DESC="Minimum Post Count Descending" -COM_KUNENA_FILTER_FIELD_CODE_ASC="Code Ascending" -COM_KUNENA_FILTER_FIELD_CODE_DESC="Code Descending" +COM_KUNENA_FILTER_FIELD_RANKSPECIAL_ASC="Special Ascending" +COM_KUNENA_FILTER_FIELD_RANKSPECIAL_DESC="Special Descending" +COM_KUNENA_FILTER_FIELD_RANKTITLE_ASC="Title Ascending" +COM_KUNENA_FILTER_FIELD_RANKTITLE_DESC="Title Descending" +COM_KUNENA_FILTER_FIELD_RANK_ASC="Rank Ascending" +COM_KUNENA_FILTER_FIELD_RANK_DESC="Rank Descending" +COM_KUNENA_FILTER_FIELD_SIGNATURE_ASC="Signature Ascending" +COM_KUNENA_FILTER_FIELD_SIGNATURE_DESC="Signature Descending" +COM_KUNENA_FILTER_FIELD_TARGETUSER_ASC="Target User Ascending" +COM_KUNENA_FILTER_FIELD_TARGETUSER_DESC="Target User Descending" +COM_KUNENA_FILTER_FIELD_TIME_ASC="Time Ascending" +COM_KUNENA_FILTER_FIELD_TIME_DESC="Time Descending" +COM_KUNENA_FILTER_FIELD_TOPIC_ASC="Topic Ascending" +COM_KUNENA_FILTER_FIELD_TOPIC_DESC="Topic Descending" +COM_KUNENA_FILTER_FIELD_TYPE_ASC="Type Ascending" +COM_KUNENA_FILTER_FIELD_TYPE_DESC="Type Descending" COM_KUNENA_FILTER_FIELD_URL_ASC="URL Ascending" COM_KUNENA_FILTER_FIELD_URL_DESC="URL Descending" +COM_KUNENA_FILTER_FIELD_USERNAME_ASC="Username Ascending" +COM_KUNENA_FILTER_FIELD_USERNAME_DESC="Username Descending" +COM_KUNENA_FILTER_FIELD_USER_ASC="User Ascending" +COM_KUNENA_FILTER_FIELD_USER_DESC="User Descending" +COM_KUNENA_FILTER_SELECT_BANNED="- Select Banned -" +COM_KUNENA_FILTER_SELECT_CATEGORY="- Select Category -" +COM_KUNENA_FILTER_SELECT_ENABLED="- Select Enabled -" +COM_KUNENA_FILTER_SELECT_MODERATOR="- Select Moderator -" +COM_KUNENA_FILTER_SELECT_OPERATION="- Select Operation -" +COM_KUNENA_FILTER_SELECT_RANKSMIN="- Select Minimum Post Count -" +COM_KUNENA_FILTER_SELECT_SIGNATURE="- Select Signature -" +COM_KUNENA_FILTER_SELECT_SPECIAL="- Select Special -" +COM_KUNENA_FILTER_SELECT_TARGETUSER="- Select Target User -" +COM_KUNENA_FILTER_SELECT_TOPIC="- Select Topic -" +COM_KUNENA_FILTER_SELECT_TYPE="- Select Type -" +COM_KUNENA_FILTER_SELECT_USER="- Select User -" +COM_KUNENA_TASK_BAN_USER="Ban User" +COM_KUNENA_TASK_BLOCK_USER="Block User" +COM_KUNENA_TASK_UNBAN_USER="Unban User" +COM_KUNENA_TASK_UNBLOCK_USER="Enable User" \ No newline at end of file diff --git a/src/admin/media/css/theme.min.css b/src/admin/media/css/theme.min.css index ddcc760ecd3..4f2d266d46f 100644 --- a/src/admin/media/css/theme.min.css +++ b/src/admin/media/css/theme.min.css @@ -8810,4 +8810,14 @@ select.form-control { .kwho-blocked, .kwho-banned { color: #A39D49; +} +.wrapword { + white-space: pre-wrap; + /* Modern browsers */ + word-wrap: break-word; + /* Additional support for older browsers */ +} + +p.select_to_clipboard { + cursor: pointer; } \ No newline at end of file diff --git a/src/admin/src/Field/KunenaoperationlistField.php b/src/admin/src/Field/KunenaoperationlistField.php new file mode 100644 index 00000000000..c462bcbdf1b --- /dev/null +++ b/src/admin/src/Field/KunenaoperationlistField.php @@ -0,0 +1,82 @@ +PLEASE COMPLETE KUNENA INSTALLATION'; + + return ''; + } + + Factory::getApplication()->bootComponent('com_kunena'); + KunenaFactory::loadLanguage('com_kunena'); + + $reflection = new ReflectionClass('Kunena\Forum\Libraries\Log\KunenaLog'); + + $constants = $reflection->getConstants(); + ksort($constants); + $operationOptions = []; + + foreach ($constants as $key => $value) { + if (strpos($key, 'LOG_') === 0) { + $operationOptions[] = (object) [ + 'text' => $key, + 'value' => Text::_("COM_KUNENA_{$value}"), + ]; + } + } + + $options = parent::getOptions(); + + if (empty($options)) { + $options[] = HTMLHelper::_('select.option', '', Text::_('COM_KUNENA_FILTER_SELECT_OPERATION')); + } + + return array_merge($options, $operationOptions); + } +} diff --git a/src/admin/src/Model/LogsModel.php b/src/admin/src/Model/LogsModel.php index 88672db59e1..1aeb3f2f642 100644 --- a/src/admin/src/Model/LogsModel.php +++ b/src/admin/src/Model/LogsModel.php @@ -16,15 +16,9 @@ \defined('_JEXEC') or die(); use Exception; -use Joomla\CMS\Date\Date; use Joomla\CMS\Factory; use Joomla\CMS\MVC\Model\ListModel; -use Joomla\CMS\User\User; -use Kunena\Forum\Libraries\Access\KunenaAccess; -use Kunena\Forum\Libraries\Collection\KunenaCollection; -use Kunena\Forum\Libraries\Forum\Topic\KunenaTopicHelper; -use Kunena\Forum\Libraries\Log\KunenaLogFinder; -use Kunena\Forum\Libraries\User\KunenaUserHelper; +use Joomla\Database\QueryInterface; /** * Logs Model for Kunena @@ -80,35 +74,6 @@ public function getForm($data = [], $loadData = true) // TODO: Implement getForm() method. } - /** - * Method to get the total number of items for the data set. - * - * @return integer The total number of items available in the data set. - * - * @throws Exception - * @since Kunena 5.0 - */ - public function getTotal(): int - { - // Get a storage key. - $store = $this->getStoreId('getTotal'); - - // Try to load the data from internal storage. - if (isset($this->cache[$store])) { - return $this->cache[$store]; - } - - // Load the total. - $finder = $this->getFinder(); - - $total = (int) $finder->count(); - - // Add the total to the internal cache. - $this->cache[$store] = $total; - - return $this->cache[$store]; - } - /** * Method to get a store id based on model configuration state. * @@ -141,223 +106,6 @@ protected function getStoreId($id = ''): string return parent::getStoreId($id); } - /** - * Build a finder query to load the list data. - * - * @return KunenaLogFinder - * - * @throws Exception - * @since Kunena 6.0 - */ - protected function getFinder(): KunenaLogFinder - { - // Get a storage key. - $store = $this->getStoreId('getFinder'); - - // Try to load the data from internal storage. - if (isset($this->cache[$store])) { - return $this->cache[$store]; - } - - // Create a new query object. - $db = $this->getDatabase(); - $finder = new KunenaLogFinder(); - - // Filter by type. - $filter = $this->getState('filter.type'); - - if (!empty($filter)) { - $finder->where('a.type', '=', $filter); - } - - // Filter by username or name. - $filter = $this->getState('filter.user'); - - if (!empty($filter)) { - $filter = $db->quote('%' . $db->escape($filter, true) . '%'); - $finder->innerJoin('#__users AS u ON u.id=a.user_id'); - $finder->where('u.username', 'LIKE', $filter, false); - } - - // Filter by category. - $filter = $this->getState('filter.category'); - - if (!empty($filter)) { - $filter = $db->quote('%' . $db->escape($filter, true) . '%'); - $finder->innerJoin('#__kunena_categories AS c ON c.id=a.category_id'); - $finder->where('c.name', 'LIKE', $filter, false); - } - - // Filter by topic. - $filter = $this->getState('filter.topic'); - - if (!empty($filter)) { - $filter = $db->quote('%' . $db->escape($filter, true) . '%'); - $finder->innerJoin('#__kunena_topics AS t ON t.id=a.topic_id'); - $finder->where('t.subject', 'LIKE', $filter, false); - } - - // Filter by target username or name. - $filter = $this->getState('filter.target_user'); - - if (!empty($filter)) { - $filter = $db->quote('%' . $db->escape($filter, true) . '%'); - $finder->innerJoin('#__users AS tu ON tu.id=a.target_user'); - $finder->where('tu.username', 'LIKE', $filter, false); - } - - // Filter by IP address. - $filter = $this->getState('filter.ip'); - - if (!empty($filter)) { - $filter = $db->quote('%' . $db->escape($filter, true) . '%'); - $finder->where('a.ip', 'LIKE', $filter, false); - } - - // Filter by time. - $start = $this->getState('filter.time_start'); - $stop = $this->getState('filter.time_stop'); - - if ($start || $stop) { - $start = $start ? new Date($start) : null; - $stop = $stop ? new Date($stop . ' +1 day') : null; - $finder->filterByTime($start, $stop); - } - - // Filter by operation. - $filter = $this->getState('filter.operation'); - - if (!empty($filter)) { - $finder->where('a.operation', '=', $filter); - } - - // Add the list ordering clause. - $direction = $this->state->get('list.direction') == 'asc' ? 1 : -1; - - switch ($this->state->get('list.ordering')) { - case 'type': - $finder->order('type', $direction); - break; - case 'user': - $finder->order('user_id', $direction); - break; - case 'category': - $finder->order('category_id', $direction); - break; - case 'topic': - $finder->order('topic_id', $direction); - break; - case 'target_user': - $finder->order('target_user', $direction); - break; - case 'ip': - $finder->order('ip', $direction); - break; - case 'time': - $finder->order('time', $direction); - break; - case 'operation': - $finder->order('operation', $direction); - break; - case 'id': - default: - $finder->order('id', $direction); - } - - $usertypes = $this->state->get('filter.usertypes'); - - // Filter by user type. - - if (is_numeric($usertypes)) { - $access = KunenaAccess::getInstance(); - - switch ($usertypes) { - case 0: - $finder->where('user_id', '=', 0); - break; - case 1: - $finder->where('user_id', '>', 0); - break; - case 2: - $finder->where('user_id', '>', 0); - $finder->where('user_id', 'NOT IN', array_keys($access->getAdmins() + $access->getModerators())); - break; - case 3: - $finder->where('user_id', 'IN', array_keys($access->getModerators())); - break; - case 4: - $finder->where('user_id', 'IN', array_keys($access->getAdmins())); - break; - case 5: - $finder->where('user_id', 'IN', array_keys($access->getAdmins() + $access->getModerators())); - break; - } - } - - $group = $this->getState('group'); - - if ($group) { - $finder->select('MAX(a.id) AS id, MAX(a.time) AS time, COUNT(*) AS count'); - - foreach ($group as $field) { - $finder->group($field); - } - } - - // Add the finder to the internal cache. - $this->cache[$store] = $finder; - - return $this->cache[$store]; - } - - /** - * Method to get User objects of data items. - * - * - * @return KunenaCollection - * @throws Exception - * - * @throws null - * @since Kunena 5.0 - */ - public function getItems(): KunenaCollection - { - // Get a storage key. - $store = $this->getStoreId(); - - // Try to load the data from internal storage. - if (isset($this->cache[$store])) { - return $this->cache[$store]; - } - - // Load the list items. - $items = $this->getFinder() - ->start((int) $this->getStart()) - ->limit((int) $this->getState('list.limit')) - ->find(); - - $userIds1 = $items->map(function ($item, $key) { - return $item->user_id; - }); - - $userIds2 = $items->map(function ($item, $key) { - return $item->target_user; - }); - - $userIds = array_unique(array_merge($userIds1->all(), $userIds2->all())); - - KunenaUserHelper::loadUsers($userIds); - - KunenaTopicHelper::getTopics($items->map(function ($item, $key) { - return $item->topic_id; - })->all()); - - // Add the items to the internal cache. - $this->cache[$store] = $items; - - return $this->cache[$store]; - } - /** * Method to auto-populate the model state. * @@ -371,56 +119,56 @@ public function getItems(): KunenaCollection * @throws Exception * @since Kunena 6.0 */ - protected function populateState($ordering = null, $direction = null) + protected function populateState($ordering = 'id', $direction = 'desc') { $app = Factory::getApplication(); // Adjust the context to support modal layouts. - $layout = $app->input->get('layout'); + $layout = $app->input->get('layout'); + $this->context = 'com_kunena.admin.logs'; if ($layout) { $this->context .= '.' . $layout; } - $filterActive = ''; - - $filterActive .= $value = $this->getUserStateFromRequest($this->context . '.filter.id', 'filter_id', '', 'string'); - $this->setState('filter.id', $value); + $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); + $this->setState('filter.search', $search); - $filterActive .= $value = $this->getUserStateFromRequest($this->context . '.filter.type', 'filterType', '', 'string'); - $this->setState('filter.type', $value); + $id = $this->getUserStateFromRequest($this->context . '.filter.id', 'filter_id', ''); + $this->setState('filter.id', $id); - $filterActive .= $value = $this->getUserStateFromRequest($this->context . '.filter.user', 'filter_user', '', 'string'); - $this->setState('filter.user', $value); + $type = $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', ''); + $this->setState('filter.type', $type); - $filterActive .= $value = $this->getUserStateFromRequest($this->context . '.filter.category', 'filter_category', '', 'string'); - $this->setState('filter.category', $value); + $user = $this->getUserStateFromRequest($this->context . '.filter.user', 'filter_user', ''); + $this->setState('filter.user', $user); - $filterActive .= $value = $this->getUserStateFromRequest($this->context . '.filter.topic', 'filter_topic', '', 'string'); - $this->setState('filter.topic', $value); + $category = $this->getUserStateFromRequest($this->context . '.filter.category', 'filter_category', ''); + $this->setState('filter.category', $category); - $filterActive .= $value = $this->getUserStateFromRequest($this->context . '.filter.target_user', 'filter_target_user', '', 'string'); - $this->setState('filter.target_user', $value); + $topic = $this->getUserStateFromRequest($this->context . '.filter.topic', 'filter_topic', ''); + $this->setState('filter.topic', $topic); - $filterActive .= $value = $this->getUserStateFromRequest($this->context . '.filter.ip', 'filter_ip', '', 'string'); - $this->setState('filter.ip', $value); + $target_user = $this->getUserStateFromRequest($this->context . '.filter.target_user', 'filter_target_user', ''); + $this->setState('filter.target_user', $target_user); - $filterActive .= $value = $this->getUserStateFromRequest($this->context . '.filter.time_start', 'filter_time_start', '', 'string'); - $this->setState('filter.time_start', $value); + $ip = $this->getUserStateFromRequest($this->context . '.filter.ip', 'filter_ip', ''); + $this->setState('filter.ip', $ip); - $filterActive .= $value = $this->getUserStateFromRequest($this->context . '.filter.time_stop', 'filter_time_stop', '', 'string'); - $this->setState('filter.time_stop', $value); + $time_start = $this->getUserStateFromRequest($this->context . '.filter.time_start', 'filter_time_start', ''); + $this->setState('filter.time_start', $time_start); - $filterActive .= $value = $this->getUserStateFromRequest($this->context . '.filter.operation', 'filter_operation', '', 'string'); - $this->setState('filter.operation', $value); + $time_stop = $this->getUserStateFromRequest($this->context . '.filter.time_stop', 'filter_time_stop', ''); + $this->setState('filter.time_stop', $time_stop); - $filterActive .= $value = $this->getUserStateFromRequest($this->context . '.filter.usertypes', 'filter_usertypes', '', 'string'); - $this->setState('filter.usertypes', $value); + $operation = $this->getUserStateFromRequest($this->context . '.filter.operation', 'filter_operation', ''); + $this->setState('filter.operation', $operation); - $filterActive .= $value = $this->getUserStateFromRequest($this->context . '.filter.userfields', 'filter_userfields', '', 'string'); - $this->setState('filter.userfields', $value); + $usertypes = $this->getUserStateFromRequest($this->context . '.filter.usertypes', 'filter_usertypes', ''); + $this->setState('filter.usertypes', $usertypes); - $this->setState('filter.active', !empty($filterActive)); + $userfields = $this->getUserStateFromRequest($this->context . '.filter.userfields', 'filter_userfields', ''); + $this->setState('filter.userfields', $userfields); $group = []; @@ -455,6 +203,154 @@ protected function populateState($ordering = null, $direction = null) $this->setState('group', $group); // List state information. - parent::populateState('id', 'desc'); + parent::populateState($ordering, $direction); + } + + /** + * Build an SQL query to load the list data. + * + * @return QueryInterface + * + * @since Kunena 6.3.0-BETA3 + */ + protected function getListQuery(): QueryInterface + { + // Create a new query object. + $db = $this->getDatabase(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'kl.*, u.name AS user_name, u.username AS user_username, tu.name AS targetuser_name, tu.username AS targetuser_username, + kc.name AS category_name, kt.subject AS topic_subject' + ) + ); + $query->from($db->quoteName('#__kunena_logs', 'kl')); + + // Join over the users for the linked user. + $query->join('LEFT', $db->quoteName('#__users', 'u') . ' ON u.id = kl.user_id'); + + // Join over the users for the linked target_user. + $query->join('LEFT', $db->quoteName('#__users', 'tu') . ' ON tu.id = kl.target_user'); + + // Join over the categories for the linked category + $query->join('LEFT', $db->quoteName('#__kunena_categories', 'kc') . ' ON kc.id = kl.category_id'); + + // Join over the topics for the linked topic + $query->join('LEFT', $db->quoteName('#__kunena_topics', 'kt') . ' ON kt.id = kl.topic_id'); + + + // Filter by search. + $search = $this->getState('filter.search'); + + if (!empty($search)) { + if (stripos($search, 'id:') === 0) { + $query->where('kl.id = ' . (int) substr($search, 3)); + } else { + $search = $db->quote('%' . $db->escape($search, true) . '%'); + $query->where('(u.username LIKE ' . $search + . ' OR u.name LIKE ' . $search + . ' OR tu.name LIKE ' . $search + . ' OR tu.username LIKE ' . $search + . ' OR kc.name LIKE ' . $search + . ' OR kt.subject LIKE ' . $search + . ' OR kl.ip LIKE ' . $search + . ')'); + } + } + + // Filter by type. + $type = $this->getState('filter.type'); + + if (!empty($type)) { + $type = $db->quote('%' . $db->escape($type, true) . '%'); + $query->where('kl.type LIKE ' . $type); + } + + // Filter by operation. + $operation = $this->getState('filter.operation'); + + if (!empty($operation)) { + $operation = $db->quote('%' . $db->escape($operation, true) . '%'); + $query->where('kl.operation LIKE ' . $operation); + } + + // Filter by user. + $user = $this->getState('filter.user'); + + if ($user !== '') { + $query->where('kl.user_id = ' . (int) $user); + } + + // Filter by target_user. + $target_user = $this->getState('filter.target_user'); + + if ($target_user !== '') { + $query->where('kl.target_user = ' . (int) $target_user); + } + + // Filter by category. + $category = $this->getState('filter.category'); + + if ($category !== '') { + $query->where('kl.category_id = ' . (int) $category); + } + + // Filter by topic. + $topic = $this->getState('filter.topic'); + + if ($topic !== '') { + $query->where('kl.topic_id = ' . (int) $topic); + } + + // Filter by time_start state. + $time_start = $this->getState('filter.time_start'); + + if ($time_start !== '') { + $query->where("kl.time > {$db->quote(strtotime($time_start))}"); + } + + // Filter by time_stop state. + $time_stop = $this->getState('filter.time_stop'); + + if ($time_stop !== '') { + $query->where("kl.time < {$db->quote(strtotime($time_stop))}"); + } + // Add the list ordering clause. + $direction = strtoupper($this->state->get('list.direction')); + + switch ($this->state->get('list.ordering')) { + case 'id': + $query->order('kl.id ' . $direction); + break; + case 'time': + $query->order('kl.time ' . $direction); + break; + case 'type': + $query->order('kl.type ' . $direction); + break; + case 'operation': + $query->order('kl.operation ' . $direction); + break; + case 'user': + $query->order('user_username ' . $direction); + break; + case 'category': + $query->order('category_name ' . $direction); + break; + case 'topic': + $query->order('topic_subject ' . $direction); + break; + case 'target_user': + $query->order('targetuser_username ' . $direction); + break; + case 'ip': + $query->order('kl.ip ' . $direction); + break; + } + + return $query; } } diff --git a/src/admin/src/View/Logs/HtmlView.php b/src/admin/src/View/Logs/HtmlView.php index d19959da8b2..e2fbec71e41 100644 --- a/src/admin/src/View/Logs/HtmlView.php +++ b/src/admin/src/View/Logs/HtmlView.php @@ -59,9 +59,7 @@ protected function setToolbarClean(): void { // Set the title bar text ToolbarHelper::title(Text::_('COM_KUNENA') . ': ' . Text::_('COM_KUNENA_LOG_MANAGER'), 'users'); - ToolbarHelper::spacer(); ToolbarHelper::custom('logs.clean', 'delete.png', 'delete_f2.png', 'COM_KUNENA_CLEAN_LOGS_ENTRIES', false); - ToolbarHelper::spacer(); ToolbarHelper::cancel(); } @@ -76,35 +74,12 @@ protected function setToolbarClean(): void */ public function display($tpl = null) { - $this->state = $this->get('state'); - $this->group = $this->state->get('group'); - $this->items = $this->get('items'); - $this->pagination = $this->get('Pagination'); - - $this->filterUserFields = $this->getFilterUserFields(); - $this->sortFields = $this->getSortFields(); - $this->sortDirectionFields = $this->getSortDirectionFields(); - - $this->filter = new \stdClass(); - $this->filter->TypeFields = $this->getFilterTypeFields(); - $this->filter->OperationFields = $this->getFilterOperationFields(); - $this->filter->Search = $this->escape($this->state->get('filter.search')); - $this->filter->Type = $this->escape($this->state->get('filter.type')); - $this->filter->User = $this->escape($this->state->get('filter.user')); - $this->filter->Category = $this->escape($this->state->get('filter.category')); - $this->filter->Topic = $this->escape($this->state->get('filter.topic')); - $this->filter->Active = $this->escape($this->state->get('filter.active')); - $this->filter->TargetUser = $this->escape($this->state->get('filter.target_user')); - $this->filter->Ip = $this->escape($this->state->get('filter.ip')); - $this->filter->TimeStart = $this->escape($this->state->get('filter.time_start')); - $this->filter->TimeStop = $this->escape($this->state->get('filter.time_stop')); - $this->filter->Operation = $this->escape($this->state->get('filter.operation')); - $this->filter->Usertypes = $this->escape($this->state->get('filter.usertypes')); - $this->filter->UserFields = $this->escape($this->state->get('filter.userfields')); - - $this->list = new \stdClass(); - $this->list->Ordering = $this->escape($this->state->get('list.ordering')); - $this->list->Direction = $this->escape($this->state->get('list.direction')); + $this->state = $this->get('state'); + $this->group = $this->state->get('group'); + $this->items = $this->get('items'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); $document = Factory::getApplication()->getDocument(); $document->setTitle(Text::_('Forum Logs')); @@ -118,58 +93,8 @@ public function display($tpl = null) * @return array * * @since Kunena 6.0 - */ - protected function getFilterUserFields(): array - { - $filterFields = []; - $filterFields[] = HTMLHelper::_('select.option', 0, Text::_('COM_KUNENA_LOG_GUESTS_FILTER_USERTYPE_LABEL')); - $filterFields[] = HTMLHelper::_('select.option', 1, Text::_('COM_KUNENA_LOG_REGISTERED_FILTER_USERTYPE_LABEL')); - $filterFields[] = HTMLHelper::_('select.option', 2, Text::_('COM_KUNENA_LOG_REGULAR_FILTER_USERTYPE_LABEL')); - $filterFields[] = HTMLHelper::_('select.option', 3, Text::_('COM_KUNENA_LOG_MODERATORS_FILTER_USERTYPE_LABEL')); - $filterFields[] = HTMLHelper::_('select.option', 4, Text::_('COM_KUNENA_LOG_ADMINISTRATORS_FILTER_USERTYPE_LABEL')); - $filterFields[] = HTMLHelper::_('select.option', 5, Text::_('COM_KUNENA_LOG_MOD_AND_ADMIN_FILTER_USERTYPE_LABEL')); - - return $filterFields; - } - - /** - * @return array - * - * @since Kunena 6.0 - */ - protected function getSortFields(): array - { - $sortFields = []; - - $sortFields[] = HTMLHelper::_('select.option', 'id', Text::_('COM_KUNENA_LOG_ID_SORT_FIELD_LABEL')); - $sortFields[] = HTMLHelper::_('select.option', 'type', Text::_('COM_KUNENA_LOG_TYPE_SORT_FIELD_LABEL')); - $sortFields[] = HTMLHelper::_('select.option', 'user', Text::_('COM_KUNENA_LOG_USER_SORT_FIELD_LABEL')); - $sortFields[] = HTMLHelper::_('select.option', 'category', Text::_('COM_KUNENA_LOG_CATEGORY_SORT_FIELD_LABEL')); - $sortFields[] = HTMLHelper::_('select.option', 'topic', Text::_('COM_KUNENA_LOG_TOPIC_SORT_FIELD_LABEL')); - $sortFields[] = HTMLHelper::_('select.option', 'target_user', Text::_('COM_KUNENA_LOG_TARGET_USER_SORT_FIELD_LABEL')); - $sortFields[] = HTMLHelper::_('select.option', 'time', Text::_('COM_KUNENA_LOG_TIME_SORT_FIELD_LABEL')); - - return $sortFields; - } - - /** - * @return array - * - * @since Kunena 6.0 - */ - protected function getSortDirectionFields(): array - { - $sortDirection = []; - $sortDirection[] = HTMLHelper::_('select.option', 'asc', Text::_('COM_KUNENA_FIELD_LABEL_ASCENDING')); - $sortDirection[] = HTMLHelper::_('select.option', 'desc', Text::_('COM_KUNENA_FIELD_LABEL_DESCENDING')); - - return $sortDirection; - } - - /** - * @return array - * - * @since Kunena 6.0 + * + * @deprecated Kunena 6.3 will be removed in Kunena 7.0 without replacement */ protected function getFilterTypeFields(): array { @@ -186,6 +111,8 @@ protected function getFilterTypeFields(): array * @return array * * @since Kunena 6.0 + * + * @deprecated Kunena 6.3 will be removed in Kunena 7.0 without replacement */ protected function getFilterOperationFields(): array { @@ -216,9 +143,10 @@ protected function addToolbar(): void { // Set the title bar text ToolbarHelper::title(Text::_('COM_KUNENA') . ': ' . Text::_('COM_KUNENA_LOG_MANAGER'), 'users'); - - ToolbarHelper::spacer(); ToolbarHelper::custom('logs.cleanEntries', 'trash.png', 'trash_f2.png', 'COM_KUNENA_LOG_CLEAN_ENTRIES', false); + + $helpUrl = 'https://docs.kunena.org/en/manual/backend/users'; + ToolbarHelper::help('COM_KUNENA', false, $helpUrl); } /** @@ -227,6 +155,8 @@ protected function addToolbar(): void * @return string * * @since Kunena 6.0 + * + * @deprecated Kunena 6.3 will be removed in Kunena 7.0 without replacement */ public function getType(int $id): string { @@ -241,6 +171,8 @@ public function getType(int $id): string * @return string * * @since Kunena 6.0 + * + * @deprecated Kunena 6.3 will be removed in Kunena 7.0 without replacement */ public function getGroupCheckbox(string $name): string { diff --git a/src/admin/tmpl/logs/default.php b/src/admin/tmpl/logs/default.php index ccbb6b6aaad..7f08c68d62a 100644 --- a/src/admin/tmpl/logs/default.php +++ b/src/admin/tmpl/logs/default.php @@ -13,352 +13,198 @@ defined('_JEXEC') or die(); +use Joomla\CMS\Factory; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; +use Joomla\CMS\Layout\LayoutHelper; use Kunena\Forum\Libraries\Date\KunenaDate; -use Kunena\Forum\Libraries\Forum\Category\KunenaCategoryHelper; -use Kunena\Forum\Libraries\Forum\Topic\KunenaTopicHelper; use Kunena\Forum\Libraries\Html\KunenaParser; use Kunena\Forum\Libraries\Route\KunenaRoute; -use Kunena\Forum\Libraries\User\KunenaUserHelper; use Kunena\Forum\Libraries\Version\KunenaVersion; -$filterItem = $this->escape($this->state->get('item.id')); +/** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */ +$wa = $this->document->getWebAssetManager(); +$wa->useScript('table.columns') + ->useScript('multiselect') + ->useScript('jquery'); +$inlineScript = <<