|
| 1 | +# Thread & forum types |
| 2 | +Threads and forums are a huge part of Xenforo. |
| 3 | +This page will cover the basics of how you can set up your own custom thread and forum type, and how you can give it basic unique functionality. |
| 4 | + |
| 5 | +## Registering new types |
| 6 | +Xenforo stores each type of thread and forum in the database table `xf_thread_type` and `xf_forum_type`. |
| 7 | +What we need to do is add a new row to these tables for each new type we want to create and then refresh the cache: `rebuildThreadTypeCache`, and `rebuildForumTypeCache`. |
| 8 | + |
| 9 | +To do this we can use built in methods in our `setup.php` |
| 10 | +```php title="setup.php" |
| 11 | +<?php |
| 12 | + |
| 13 | +namespace Vendor\Addon; |
| 14 | + |
| 15 | +use XF\AddOn\AbstractSetup; |
| 16 | +use XF\AddOn\StepRunnerInstallTrait; |
| 17 | +use XF\AddOn\StepRunnerUninstallTrait; |
| 18 | +use XF\AddOn\StepRunnerUpgradeTrait; |
| 19 | + |
| 20 | +class Setup extends AbstractSetup |
| 21 | +{ |
| 22 | + use StepRunnerInstallTrait; |
| 23 | + use StepRunnerUpgradeTrait; |
| 24 | + use StepRunnerUninstallTrait; |
| 25 | + |
| 26 | + public function installStep1(): void |
| 27 | + { |
| 28 | + $this->insertThreadType('thread_type_identifier', 'Vendor\Addon:Example', 'Vendor/Addon'); |
| 29 | + } |
| 30 | + |
| 31 | + public function installStep2(): void |
| 32 | + { |
| 33 | + $this->insertForumType('forum_type_identifier', 'Vendor\Addon:Example', 'Vendor/Addon'); |
| 34 | + } |
| 35 | +} |
| 36 | +``` |
| 37 | +What this will do is insert a new row into the `xf_thread_type` and `xf_forum_type` tables with the given identifier, handler and add-on. |
| 38 | + |
| 39 | +The parameters for `insertThreadType` and `insertForumType` are: |
| 40 | + |
| 41 | +- `identifier` - The identifier of the thread or forum type. This is a string you will be using to refer to the type in your code. |
| 42 | +- `handler` - The handler class for the thread or forum type. This can be in the format `Vendor\Addon:Class` or a full path to the class `Vendor\Addon\ForumType\ExampleHandler`. |
| 43 | +- `addon_id` - The add-on ID of the thread or forum type. This is the ID of the add-on that the thread or forum type belongs to. |
| 44 | +- `rebuildCache` - Whether to rebuild the cache. This is set to `true` by default. |
| 45 | + |
| 46 | +### What is a handler? |
| 47 | +A handler is a class that is responsible for handling the logic of a specific type of thread or forum. |
| 48 | +You can see Xenforo's default handlers in the `XF\ThreadType\*` and `XF\ForumType\*` classes. |
| 49 | + |
| 50 | +You will always want to extend the `XF\ThreadType\AbstractHandler` or `XF\ForumType\AbstractHandler` class when making your own handler. |
| 51 | + |
| 52 | +## Creating type handlers |
| 53 | +What is a handler responsible for? |
| 54 | + |
| 55 | +A handler is responsible for handling the logic of a specific type of thread or forum. |
| 56 | + |
| 57 | +### Thread type handlers |
| 58 | +To create a thread type handler, you will need to create a new class that extends `XF\ThreadType\AbstractHandler`. |
| 59 | +In your add-ons folder you will need to create a new folder called `ThreadType` and then create a new class called `ExampleHandler`. |
| 60 | + |
| 61 | +```php title="ThreadType/ExampleHandler.php" |
| 62 | +<?php |
| 63 | + |
| 64 | +namespace Vendor\Addon\ThreadType; |
| 65 | + |
| 66 | +use XF\Entity\Thread; |
| 67 | +use XF\ThreadType\AbstractHandler; |
| 68 | + |
| 69 | +class ExampleHandler extends AbstractHandler |
| 70 | +{ |
| 71 | + // Here we can add a font awesome icon for our thread type. |
| 72 | + public function getTypeIconClass(): string |
| 73 | + { |
| 74 | + return 'fa-user'; |
| 75 | + } |
| 76 | +} |
| 77 | +``` |
| 78 | + |
| 79 | +By default, the `getTypeIconClass` method will need to be in your handler. |
| 80 | + |
| 81 | +Let's add some functionality to our handler before moving on. |
| 82 | +To see all the methods available to you, I'd highly recommend checking out the class `XF\ThreadType\AbstractHandler`. |
| 83 | + |
| 84 | +```php title="ThreadType/ExampleHandler.php" |
| 85 | +public function onThreadPreSave(Thread $thread, bool $isTypeEnter): void |
| 86 | +{ |
| 87 | + parent::onThreadPreSave($thread, $isTypeEnter); |
| 88 | + \XF::logError("TestHandler: Wow a thread has been saved!"); |
| 89 | +} |
| 90 | +``` |
| 91 | + |
| 92 | +What this will do is run this event before a thread is saved. |
| 93 | +In this case the method will return a log in the admin console under `Server error log`. |
| 94 | + |
| 95 | +### Forum type handlers |
| 96 | +To create a forum type handler, you will need to create a new class that extends `XF\ForumType\AbstractHandler`. |
| 97 | +In your add-ons folder you will need to create a new folder called `ForumType` and then create a new class called `ExampleHandler`. |
| 98 | + |
| 99 | +```php title="ForumType/ExampleHandler.php" |
| 100 | +<?php |
| 101 | + |
| 102 | +namespace Vendor\Addon\ForumType; |
| 103 | + |
| 104 | +use XF\Entity\Forum; |
| 105 | +use XF\ForumType\AbstractHandler; |
| 106 | + |
| 107 | +class ExampleHandler extends AbstractHandler |
| 108 | +{ |
| 109 | + // Here we can set the default thread type for our forum type. |
| 110 | + // This will be used when a new thread is created in the forum. |
| 111 | + public function getDefaultThreadType(Forum $forum): string |
| 112 | + { |
| 113 | + return 'thread_type_identifier'; |
| 114 | + } |
| 115 | + |
| 116 | + // When creating a node in the admin control panel, |
| 117 | + // this value affects the order in which the forum type appears. |
| 118 | + public function getDisplayOrder(): int |
| 119 | + { |
| 120 | + return 1; |
| 121 | + } |
| 122 | + |
| 123 | + // Here we can add a font awesome icon for our forum type. |
| 124 | + public function getTypeIconClass(): string |
| 125 | + { |
| 126 | + return 'fa-user'; |
| 127 | + } |
| 128 | +} |
| 129 | +``` |
| 130 | + |
| 131 | +By default, the `getDefaultThreadType`, `getDisplayOrder`, `getTypeIconClass` methods will need to be in your handler. |
| 132 | + |
| 133 | +Let's add some functionality to our handler before moving on. |
| 134 | +To see all the methods available to you, I'd highly recommend checking out the class `XF\ForumType\AbstractHandler`. |
| 135 | + |
| 136 | +```php title="ForumType/ExampleHandler.php" |
| 137 | +public function getExtraAllowedThreadTypes(Forum $forum): array |
| 138 | +{ |
| 139 | + return ['thread_type_identifier', 'discussion']; |
| 140 | +} |
| 141 | +``` |
| 142 | + |
| 143 | +What this will do is add the discussion thread type to the forum type. |
| 144 | +Letting users create a discussion thread in the forum, as well as our custom thread type. |
| 145 | + |
| 146 | +## Uninstalling types |
| 147 | +To uninstall a type, you will need to remove the row from the `xf_thread_type` and `xf_forum_type` tables. |
| 148 | + |
| 149 | +```php title="setup.php" |
| 150 | + public function uninstallStep1(): void |
| 151 | + { |
| 152 | + $this->db()->delete('xf_thread_type', 'thread_type_id = ?', 'test'); |
| 153 | + |
| 154 | + $iconRepo = $this->app->repository(IconRepository::class); |
| 155 | + $iconRepo->enqueueUsageAnalyzer('thread_type'); |
| 156 | + |
| 157 | + \XF::runOnce('rebuildThreadTypeCache', function () |
| 158 | + { |
| 159 | + $this->app->repository(ThreadTypeRepository::class)->rebuildThreadTypeCache(); |
| 160 | + }); |
| 161 | + } |
| 162 | + |
| 163 | + public function uninstallStep2(): void |
| 164 | + { |
| 165 | + $this->db()->delete('xf_forum_type', 'forum_type_id = ?', 'test'); |
| 166 | + |
| 167 | + $iconRepo = $this->app->repository(IconRepository::class); |
| 168 | + $iconRepo->enqueueUsageAnalyzer('forum_type'); |
| 169 | + |
| 170 | + \XF::runOnce('rebuildForumTypeCache', function () |
| 171 | + { |
| 172 | + $this->app->repository(ForumTypeRepository::class)->rebuildForumTypeCache(); |
| 173 | + }); |
| 174 | + } |
| 175 | +``` |
| 176 | + |
| 177 | +This will remove the row from the `xf_thread_type` and `xf_forum_type` tables and then rebuild the cache. |
0 commit comments