XF 2.2 Example Code to get threads with API

Robert9

Well-known member
There are a lot of texts about API, but i cant find any example code how to get threads.
I am able to add threads without any problems, but I cant get threads.

$response = $client->request('GET', 'api_url/threads/',
'headers' => ...

and then the result is

$response->threads?
 
Last edited:
here is my result, but where are my threads?

Code:
GuzzleHttp\Psr7\Response Object
(
    [reasonPhrase:GuzzleHttp\Psr7\Response:private] => OK
    [statusCode:GuzzleHttp\Psr7\Response:private] => 200
    [headers:GuzzleHttp\Psr7\Response:private] => Array
        (
            [Content-Type] => Array
                (
                    [0] => application/json; charset=utf-8
                )

            [Content-Length] => Array
                (
                    [0] => 26102
                )

            [Connection] => Array
                (
                    [0] => keep-alive
                )

            [Keep-Alive] => Array
                (
                    [0] => timeout=15
                )

            [Date] => Array
                (
                    [0] => Sun, 07 May 2023 07:28:51 GMT
                )

            [Server] => Array
                (
                    [0] => Apache
                )

            [XF-Latest-Api-Version] => Array
                (
                    [0] => 1
                )

            [XF-Used-Api-Version] => Array
                (
                    [0] => 1
                )

            [XF-Request-User] => Array
                (
                    [0] => 2
                )

            [XF-Request-User-Extras] => Array
                (
                    [0] => {"conversations_unread":0,"alerts_unviewed":1}
                )

            [Expires] => Array
                (
                    [0] => Thu, 19 Nov 1981 08:52:00 GMT
                )

            [Cache-Control] => Array
                (
                    [0] => private, no-cache, max-age=0
                )

        )

    [headerNames:GuzzleHttp\Psr7\Response:private] => Array
        (
            [content-type] => Content-Type
            [content-length] => Content-Length
            [connection] => Connection
            [keep-alive] => Keep-Alive
            [date] => Date
            [server] => Server
            [xf-latest-api-version] => XF-Latest-Api-Version
            [xf-used-api-version] => XF-Used-Api-Version
            [xf-request-user] => XF-Request-User
            [xf-request-user-extras] => XF-Request-User-Extras
            [expires] => Expires
            [cache-control] => Cache-Control
        )

    [protocol:GuzzleHttp\Psr7\Response:private] => 1.1
    [stream:GuzzleHttp\Psr7\Response:private] => GuzzleHttp\Psr7\Stream Object
        (
            [stream:GuzzleHttp\Psr7\Stream:private] => Resource id #209
            [size:GuzzleHttp\Psr7\Stream:private] =>
            [seekable:GuzzleHttp\Psr7\Stream:private] => 1
            [readable:GuzzleHttp\Psr7\Stream:private] => 1
            [writable:GuzzleHttp\Psr7\Stream:private] => 1
            [uri:GuzzleHttp\Psr7\Stream:private] => php://temp
            [customMetadata:GuzzleHttp\Psr7\Stream:private] => Array
                (
                )

        )

)
 
Life could be so wonderful with some more hints or docs ... so back to php and mysql ... needs 200 instead of 5 lines, but what can i do ...

api.jpg
 
You're getting back a Guzzle PSR-7 response object, which you can view the documentation for here:


You can peak at other places the HTTP client is used in XF, which would generally reveal something like:
PHP:
$contents = $response->getBody()->getContents();
$json = \GuzzleHttp\json_decode($contents, true);
 
Thank you. What I dont understand:

if print_r($response) i see for example: getStatusCode

$code = $response->getStatusCode() = 200.

Ok.

But where in this is my "threads", in which {container} i can find "threads".

Where ->getBody()->getContents() will find my threads?
 
Per my post above, the decoded JSON response would be available in the $json variable. You can dump it to inspect the contents.

Though I would note that if you're writing an add-on and trying to fetch threads from the same installation the add-on belongs to, you're probably better off working with finders/entities directly. The API is more for cross-installation or cross-software communication.
 
This works for me. Thank you.


Next problem: I cant get a thread by thread_id; i have to get it be a field xf_thread.source_id;
source_id is done with setup and listener and 'api'=true

But this does not work.
/api/threads?source_id=0

What is needed to use more fields than the ones her, please?





Maybe i was wrong with that?
old_item_table.item_id => do a new thread and save item_id in thread.source_id

Maybe I have to save the new thread_id in the old item_table instead?
 
That only controls whether the values are present in API responses. You would have to extend the API to add additional sorting/filtering just as you would the usual interface. See \XF\Api\Controller\Threads::actionGet and \XF\Api\ControllerPlugin::applyThreadListFilters in this case.
 
When I get threads, it seems i get all fields?
1. What we do with 'api' => true in structure, please?
2. What is protected function setupApiResultData( for
3. Above i will watch immediately, thank you.
 
Ok, i need to add to XF\Api\ControllerPlugin; something like:

Code:
        $sourceId = $this->filter('source_id', 'uint');
        if ($sourceId)
        {
            $threadFinder->where('source_id', $sourceId);
            $filters['source_id'] = $sourceId;
        }

It works added to source_code;


but how should I extend here?

public function applyThreadListFilters(\XF\Finder\Thread $threadFinder, \XF\Entity\Forum $forum = null)
 
Last edited:
It seems this works:

PHP:
namespace Xencafe\ExtThread\XF\Api\ControllerPlugin;

class Thread extends XFCP_Thread
{

    public function applyThreadListFilters(\XF\Finder\Thread $threadFinder, \XF\Entity\Forum $forum = null)
    {
        
        $myFinder = parent::applyThreadListFilters($threadFinder);

        $sourceId = $this->filter('source_id', 'uint');
        if ($sourceId)
        {
            $threadFinder->where('source_id', $sourceId);
            $filters['source_id'] = $sourceId;
        }

        return $myFinder;
    }
}
 
This is try and error; because:

the original function is called with $threadFinder and $forum
i take the parent value of threadFinder and add something, then return it.

but $filter is something magic always there? So i don't need to take it, manipulate it and give it back?
I just add something?
 
Top Bottom