Confirmed Forum's allowed_thread_types drops the first configured extra thread type

stromb0li

Well-known member
Licensed customer
Affected version
2.3.11
XF\ForumType\DiscussionHandler::addTypeConfigToApiResult() builds the API's allowed_thread_types with the array union operator: 'allowed_thread_types' => [$this->getDefaultThreadType($forum)] + $forum->type_config['allowed_thread_types'],

+ keeps the left operand's keys and only adds keys the left side doesn't have. type_config['allowed_thread_types'] is a compact, 0-indexed list, so key 0 — the first enabled extra thread type — is always discarded:

PHP:
["discussion"] + ["poll"]             => ["discussion"]
["discussion"] + ["poll", "question"] => ["discussion", "question"]

Steps to reproduce:

1. ACP > Nodes > edit a Discussion forum > Allowed thread types: tick Poll only. Save.
2. GET /api/forums/{node_id} (or /api/nodes/) with an API key.
3. type_data.discussion.allowed_thread_types is ["discussion"]. Expected ["discussion", "poll"].
4. Tick Poll and Question instead: the API returns ["discussion", "question"] — whichever type is first in the forum's (drag-sortable) list is the one dropped.

The new-thread form uses Forum::getCreatableThreadTypes(), which uses array_unshift(). Only the API result takes the union shortcut, so the two disagree about the same forum.

Impact: an API client rendering a thread type picker can't tell that a forum accepts polls or questions, and hides options the forum will happily accept. The list can only ever be short, never over-permissive, so POSTs still validate correctly server-side.

Suggested fix — array_merge instead of the union:

PHP:
    'allowed_thread_types' => array_merge(
        [$this->getDefaultThreadType($forum)],
        $forum->type_config['allowed_thread_types']
    ),

or simply $this->getCreatableThreadTypes($forum), which is the same list the new-thread form offers and keeps the API and front end in step by construction.
 
This looks like a pretty straightforward bug, but it could easily cause confusion for API users. The fact that the first extra thread type gets dropped explains why the forum and API can show different options. Using array_merge() or the same method as the new-thread form seems like a clean fix.
Would using getCreatableThreadTypes() be the safer option to keep both sides consistent?
 
Back
Top Bottom