Skip to content

Commit

Permalink
Forum: Rework prefix feature (#888)
Browse files Browse the repository at this point in the history
**Reworked the prefix feature**
- Added the tables 'forum_prefixes' and 'forum_prefixes_items'.
- Added an UI to add and edit prefixes. These can then be assigned to forums as before.
- Added a mapper and a model to handle prefixes.
- Existing prefixes get converted to the new system on update if possible.
- Renamed the prefix getter and setter in the ForumItem model to getPrefixes and setPrefixes as they handle a comma separated string of prefix ids.
- Fixes #838 
- Use UTC_TIMESTAMP() when creating the first topic on install.

NOW() returns the local time, whereas other parts of the forum work with the UTC time and translate to local time. This might cause the first topic to be in the future and causing problems with marking them as read.

* PSR Änderungen

---------

Co-authored-by: Dennis Reilard <[email protected]>
  • Loading branch information
blackcoder87 and hhunderter authored Dec 19, 2023
1 parent 0ac260d commit 2505ba8
Show file tree
Hide file tree
Showing 47 changed files with 826 additions and 151 deletions.
132 changes: 127 additions & 5 deletions application/modules/forum/config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ public function uninstall()
DROP TABLE `[prefix]_forum_topics`;
DROP TABLE `[prefix]_forum_groupranking`;
DROP TABLE `[prefix]_forum_accesses`;
DROP TABLE `[prefix]_forum_prefixes_items`;
DROP TABLE `[prefix]_forum_prefixes`;
DROP TABLE `[prefix]_forum_items`;
DROP TABLE `[prefix]_forum_ranks`;
DROP TABLE `[prefix]_forum_reports`;
Expand All @@ -93,7 +95,7 @@ public function uninstall()
DELETE FROM `[prefix]_emails` WHERE `moduleKey` = 'forum';");
}

public function getInstallSql()
public function getInstallSql(): string
{
return 'CREATE TABLE IF NOT EXISTS `[prefix]_forum_groupranking` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
Expand All @@ -109,10 +111,24 @@ public function getInstallSql()
`type` TINYINT(1) NOT NULL,
`title` VARCHAR(255) NOT NULL,
`description` VARCHAR(255) NOT NULL,
`prefix` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci AUTO_INCREMENT=1;
CREATE TABLE IF NOT EXISTS `[prefix]_forum_prefixes` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`prefix` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `[prefix]_forum_prefixes_items` (
`item_id` INT(11) NOT NULL,
`prefix_id` INT(11) NOT NULL,
INDEX `FK_[prefix]_forum_prefixes_items_[prefix]_forum_items` (`item_id`) USING BTREE,
INDEX `FK_[prefix]_forum_prefixes_items_[prefix]_forum_prefixes` (`prefix_id`) USING BTREE,
CONSTRAINT `FK_[prefix]_forum_prefixes_items_[prefix]_forum_items` FOREIGN KEY (`item_id`) REFERENCES `[prefix]_forum_items` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE,
CONSTRAINT `FK_[prefix]_forum_prefixes_items_[prefix]_forum_prefixes` FOREIGN KEY (`prefix_id`) REFERENCES `[prefix]_forum_prefixes` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `[prefix]_forum_accesses` (
`item_id` INT(11) NOT NULL,
`group_id` INT(11) NOT NULL,
Expand Down Expand Up @@ -229,13 +245,13 @@ public function getInstallSql()
(2, 10, 1, 1, "Mein Forum", "Mein erstes Forum");
INSERT INTO `[prefix]_forum_topics` (`id`, `topic_title`, `creator_id`, `date_created`, `forum_id`) VALUES
(1, "Willkommen bei Ilch!", 0, NOW(), 2);
(1, "Willkommen bei Ilch!", 0, UTC_TIMESTAMP(), 2);
INSERT INTO `[prefix]_forum_posts` (`id`, `topic_id`, `text`, `user_id`, `date_created`, `forum_id`) VALUES
(1, 1, "Willkommen im Ilch 2 Forum!\n\nBei Fragen oder Probleme im <a target=\"_blank\" href=\"https://www.ilch.de/forum.html\" rel=\"noopener\">Ilch Forum</a> melden.
Viel Erfolg
Ilch", 0, NOW(), 2);
Ilch", 0, UTC_TIMESTAMP(), 2);
INSERT INTO `[prefix]_forum_ranks` (`id`, `title`, `posts`) VALUES
(1, "Anfänger", 0),
Expand Down Expand Up @@ -798,7 +814,113 @@ public function getUpdate(string $installedVersion): string

// no break
case "1.34.1":
// no break
case "1.34.2":
case "1.34.3":
case "1.34.4":
// Create new tables 'forum_prefixes' and 'forum_prefixes_items'.
$this->db()->queryMulti('CREATE TABLE IF NOT EXISTS `[prefix]_forum_prefixes` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`prefix` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;');

$this->db()->queryMulti('CREATE TABLE IF NOT EXISTS `[prefix]_forum_prefixes_items` (
`item_id` INT(11) NOT NULL,
`prefix_id` INT(11) NOT NULL,
INDEX `FK_[prefix]_forum_prefixes_items_[prefix]_forum_items` (`item_id`) USING BTREE,
INDEX `FK_[prefix]_forum_prefixes_items_[prefix]_forum_prefixes` (`prefix_id`) USING BTREE,
CONSTRAINT `FK_[prefix]_forum_prefixes_items_[prefix]_forum_items` FOREIGN KEY (`item_id`) REFERENCES `[prefix]_forum_items` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE,
CONSTRAINT `FK_[prefix]_forum_prefixes_items_[prefix]_forum_prefixes` FOREIGN KEY (`prefix_id`) REFERENCES `[prefix]_forum_prefixes` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;');

// Convert old data for the prefix feature to the new system.
// Get all non-empty values of prefix for every forum.
$prefixRows = $this->db()->select(['id', 'prefix'])
->from('forum_items')
->where(['type' => 1, 'prefix <>' => ''])
->execute()
->fetchList('prefix', 'id');

// Get all topics with a prefix. Ignore 0, which stands for no prefix.
$topicsWithPrefix = $this->db()->select(['id', 'forum_id', 'topic_prefix'])
->from('forum_topics')
->where(['topic_prefix <>' => 0])
->execute()
->fetchRows();

// Create a list of unique prefixes that need to be added to the new 'forum_prefixes' table.
$mapTopicIdToPrefix = [];
$mapItemIdToPrefixes = [];
$existingPrefixes = [];
foreach ($prefixRows as $item_id => $prefixes) {
$prefixes = explode(', ', $prefixes);

// Map the topic id to the used prefix.
foreach ($topicsWithPrefix as $topic) {
$mapTopicIdToPrefix[$topic['id']] = $prefixes[$topic['topic_prefix']] ?? '';
}

$existingPrefixes = array_merge($existingPrefixes, $prefixes);
$mapItemIdToPrefixes[$item_id] = $prefixes;
}
$uniquePrefixes = array_unique($existingPrefixes);

// Add the unique prefixes in chunks of 25 to the 'forum_prefixes' table.
$chunks = array_chunk($uniquePrefixes, 25);
foreach ($chunks as $chunk) {
$this->db()->insert('forum_prefixes')
->columns(['prefix'])
->values($chunk)
->execute();
}

// Update the 'topic_prefix' column of the 'forum_topics' table to contain the id of the prefix.
$existingPrefixes = $this->db()->select(['id', 'prefix'])
->from('forum_prefixes')
->execute()
->fetchRows();

foreach ($topicsWithPrefix as $topic) {
foreach ($existingPrefixes as $existingPrefix) {
if (!$mapTopicIdToPrefix[$topic['id']]) {
$this->db()->update('forum_topics')
->values(['topic_prefix' => 0])
->where(['id' => $topic['id']])
->execute();
break;
}
if ($mapTopicIdToPrefix[$topic['id']] = $existingPrefix['prefix']) {
$this->db()->update('forum_topics')
->values(['topic_prefix' => $existingPrefix['id']])
->where(['id' => $topic['id']])
->execute();
break;
}
}
}

// Add currently allowed prefixes for the forum items.
$forumPrefixesItemsRows = [];
foreach ($mapItemIdToPrefixes as $item_id => $prefixes) {
foreach ($prefixes as $prefix) {
foreach ($existingPrefixes as $existingPrefix) {
if ($prefix === $existingPrefix['prefix']) {
$forumPrefixesItemsRows[] = ['item_id' => $item_id, 'prefix_id' => $existingPrefix['id']];
break;
}
}
}
}
$chunks = array_chunk($forumPrefixesItemsRows, 25);
foreach ($chunks as $chunk) {
$this->db()->insert('forum_prefixes_items')
->columns(['item_id', 'prefix_id'])
->values($chunk)
->execute();
}

// Delete the no longer used column 'prefix' of the 'forum_items' table.
$this->db()->query('ALTER TABLE `[prefix]_forum_items` DROP COLUMN `prefix`;');
}

return '"' . $this->config['key'] . '" Update function executed.';
Expand Down
8 changes: 7 additions & 1 deletion application/modules/forum/controllers/Newtopic.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,20 @@
use Ilch\Controller\Frontend;
use Ilch\Date;
use Modules\Forum\Mappers\Forum as ForumMapper;
use Modules\Forum\Mappers\Prefixes as PrefixMapper;
use Modules\Forum\Mappers\Topic as TopicMapper;
use Modules\Forum\Models\ForumTopic as ForumTopicModel;
use Modules\Forum\Mappers\Post as PostMapper;
use Modules\Forum\Models\ForumPost as ForumPostModel;
use Ilch\Validation;
use Modules\Forum\Models\Prefix as PrefixModel;

class Newtopic extends Frontend
{
public function indexAction()
{
$forumMapper = new ForumMapper();
$prefixMapper = new PrefixMapper();
$id = $this->getRequest()->getParam('id');

if (empty($id) || !is_numeric($id)) {
Expand Down Expand Up @@ -72,7 +75,9 @@ public function indexAction()
$dateTime = new Date();

$topicModel = new ForumTopicModel();
$topicModel->setTopicPrefix($this->getRequest()->getPost('topicPrefix') ?? '')
$prefixModel = new PrefixModel();
$prefixModel->setId($this->getRequest()->getPost('topicPrefix') ?? 0);
$topicModel->setTopicPrefix($prefixModel)
->setTopicTitle($this->getRequest()->getPost('topicTitle'))
->setForumId($id)
->setCreatorId($this->getUser()->getId())
Expand Down Expand Up @@ -102,5 +107,6 @@ public function indexAction()

$this->getView()->set('cat', $cat);
$this->getView()->set('forum', $forum);
$this->getView()->set('prefixes', $prefixMapper->getPrefixes());
}
}
2 changes: 1 addition & 1 deletion application/modules/forum/controllers/Showactivetopics.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public function indexAction()
if ($post->getDateCreated() < $date->format('Y-m-d H:i:s', true) && $post->getDateCreated() > $dateLessHours->format('Y-m-d H:i:s', true)) {
$topicsToShow[] = [
'topic' => $topics[$post->getTopicId()],
'forumPrefix' => $forums[$topics[$post->getTopicId()]->getForumId()]->getPrefix(),
'forumPrefix' => $forums[$topics[$post->getTopicId()]->getForumId()]->getPrefixes(),
'lastPost' => $post,
];
}
Expand Down
2 changes: 1 addition & 1 deletion application/modules/forum/controllers/Shownewposts.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function indexAction()
if (!$post->getRead()) {
$topicsToShow[] = [
'topic' => $topics[$post->getTopicId()],
'forumPrefix' => $forums[$topics[$post->getTopicId()]->getForumId()]->getPrefix(),
'forumPrefix' => $forums[$topics[$post->getTopicId()]->getForumId()]->getPrefixes(),
'lastPost' => $post,
];
}
Expand Down
32 changes: 16 additions & 16 deletions application/modules/forum/controllers/Showposts.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Ilch\Mail;
use Ilch\Pagination;
use Modules\Forum\Mappers\Forum as ForumMapper;
use Modules\Forum\Mappers\Prefixes as PrefixMapper;
use Modules\Forum\Mappers\Topic as TopicMapper;
use Modules\Forum\Mappers\Post as PostMapper;
use Modules\Forum\Mappers\Rank as RankMapper;
Expand Down Expand Up @@ -62,17 +63,16 @@ public function indexAction()

$cat = $forumMapper->getCatByParentId($forum->getParentId());
$posts = $postMapper->getPostsByTopicId($topicId, $pagination, $this->getConfig()->get('forum_DESCPostorder'), ($this->getUser()) ? $this->getUser()->getId() : null);
$post = $topicMapper->getTopicById($topicId);
$topic = $topicMapper->getTopicById($topicId);

$prefix = '';
if ($forum->getPrefix() != '' && $post->getTopicPrefix() > 0) {
$prefixes = explode(',', $forum->getPrefix());
array_unshift($prefixes, '');

foreach ($prefixes as $key => $value) {
if ($post->getTopicPrefix() == $key) {
$value = trim($value);
$prefix = '[' . $value . '] ';
if ($forum->getPrefixes() != '' && $topic->getTopicPrefix()->getId() > 0) {
$prefixIds = explode(',', $forum->getPrefixes());
array_unshift($prefixIds, '');

foreach ($prefixIds as $prefixId) {
if ($topic->getTopicPrefix()->getId() == $prefixId) {
$prefix = '[' . $topic->getTopicPrefix()->getPrefix() . '] ';
}
}
}
Expand All @@ -81,16 +81,16 @@ public function indexAction()
->add($this->getTranslator()->trans('forum'))
->add($cat->getTitle())
->add($forum->getTitle())
->add($prefix . $post->getTopicTitle());
->add($prefix . $topic->getTopicTitle());
$this->getLayout()->set('metaDescription', $this->getTranslator()->trans('forum') . ' - ' . $forum->getDesc());
$this->getLayout()->getHmenu()
->add($this->getTranslator()->trans('forum'), ['controller' => 'index', 'action' => 'index'])
->add($cat->getTitle(), ['controller' => 'showcat', 'action' => 'index', 'id' => $cat->getId()])
->add($forum->getTitle(), ['controller' => 'showtopics', 'action' => 'index', 'forumid' => $forum->getId()])
->add($prefix . $post->getTopicTitle(), ['controller' => 'showposts', 'action' => 'index', 'topicid' => $topicId]);
->add($prefix . $topic->getTopicTitle(), ['controller' => 'showposts', 'action' => 'index', 'topicid' => $topicId]);

$topicModel->setId($topicId);
$topicModel->setVisits($post->getVisits() + 1);
$topicModel->setVisits($topic->getVisits() + 1);
$topicMapper->saveVisits($topicModel);

$rememberedPostIds = [];
Expand Down Expand Up @@ -130,7 +130,7 @@ public function indexAction()
$reportedPostsIds[] = $reportedPost->getPostId();
}

$this->getView()->set('post', $post);
$this->getView()->set('post', $topic);
$this->getView()->set('cat', $cat);
$this->getView()->set('posts', $posts);
$this->getView()->set('forum', $forum);
Expand Down Expand Up @@ -175,6 +175,7 @@ public function editAction()
$postMapper = new PostMapper();
$forumMapper = new ForumMapper();
$topicMapper = new TopicMapper();
$prefixMapper = new PrefixMapper();

$postId = $this->getRequest()->getParam('id');
$topicId = $this->getRequest()->getParam('topicid');
Expand Down Expand Up @@ -254,9 +255,7 @@ public function editAction()
// This ensures that only the autor or an admin can change the topic title
if ($isFirstPost) {
$topicMapper->update($topicId, 'topic_title', $this->getRequest()->getPost('topicTitle'));
if (!empty($this->getRequest()->getPost('topicPrefix'))) {
$topicMapper->update($topicId, 'topic_prefix', $this->getRequest()->getPost('topicPrefix'));
}
$topicMapper->update($topicId, 'topic_prefix', $this->getRequest()->getPost('topicPrefix') ?? 0);
}

$this->redirect()
Expand All @@ -271,6 +270,7 @@ public function editAction()
->to(['controller' => 'showposts', 'action' => 'edit', 'id' => $postId, 'topicid' => $topicId]);
}

$this->getView()->set('prefixes', $prefixMapper->getPrefixes());
$this->getView()->set('forum', $forum);
$this->getView()->set('topic', $topic);
$this->getView()->set('post', $postMapper->getPostById($postId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function indexAction()
foreach ($posts ?? [] as $post) {
$topicsToShow[] = [
'topic' => $topics[$post->getTopicId()],
'forumPrefix' => $forums[$topics[$post->getTopicId()]->getForumId()]->getPrefix(),
'forumPrefix' => $forums[$topics[$post->getTopicId()]->getForumId()]->getPrefixes(),
'lastPost' => $post,
];
}
Expand Down
11 changes: 10 additions & 1 deletion application/modules/forum/controllers/admin/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use Ilch\Controller\Admin;
use Modules\Forum\Mappers\Forum as ForumMapper;
use Modules\Forum\Mappers\Prefixes as PrefixMapper;
use Modules\Forum\Models\ForumItem;
use Modules\User\Mappers\Group as UserGroupMapper;
use Ilch\Validation;
Expand All @@ -30,6 +31,12 @@ public function init()
'icon' => 'fa-solid fa-table-list',
'url' => $this->getLayout()->getUrl(['controller' => 'ranks', 'action' => 'index'])
],
[
'name' => 'menuPrefixes',
'active' => false,
'icon' => 'fa-solid fa-table-list',
'url' => $this->getLayout()->getUrl(['controller' => 'prefixes', 'action' => 'index'])
],
[
'name' => 'menuReports',
'active' => false,
Expand Down Expand Up @@ -57,6 +64,7 @@ public function indexAction()

$forumMapper = new ForumMapper();
$userGroupMapper = new UserGroupMapper();
$prefixMapper = new PrefixMapper();

// Saves the item tree to database.
if ($this->getRequest()->isPost()) {
Expand Down Expand Up @@ -113,7 +121,7 @@ public function indexAction()
$forumItem->setDesc($item['desc']);
// Don't try to store these values for a category. This avoids storing "undefined" from JS in the database.
if ($item['type'] != 0) {
$forumItem->setPrefix($item['prefix']);
$forumItem->setPrefixes($item['prefixes'] ?? '');
$forumItem->setReadAccess($item['readAccess']);
$forumItem->setReplyAccess($item['replyAccess']);
$forumItem->setCreateAccess($item['createAccess']);
Expand Down Expand Up @@ -154,5 +162,6 @@ public function indexAction()

$this->getView()->set('forumItems', $forumMapper->getForumItemsAdmincenterByParentIds([0]));
$this->getView()->set('userGroupList', $userGroupMapper->getGroupList());
$this->getView()->set('prefixes', $prefixMapper->getPrefixes());
}
}
Loading

0 comments on commit 2505ba8

Please sign in to comment.