How to display latest posts externally from xF?

Tim Jay

Active member
I use the above code in many places so it's best for you to paste what you are trying to use.

Also, $thread['message'] can be found by doing the var_dump. For example, in the foreach loop:

PHP:
foreach ( $threads AS $thread ) {
        var_dump($thread);
}

This will show you what is available in $thread. You could also use Zend_Debug::dump($thread); in the loop.

When I do var_dump($thread); I don't see 'message' anywhere.
 

LPH

Well-known member
Sorry to come here 3 years later... but is there a possibility to select several nodes, not just 1?

I've never tried but you'd end up with nesting the foreach loop inside another foreach loop of a nodes array. This is untested:

PHP:
<?php

// set the amount of posts to display
$limit = 2;

$startTime = microtime( true );

// Set to forum location - See XenForo index.php for information
$fileDir = '/Users/layneheiny/Documents/Sites/xenword2018/xenforo';

require( $fileDir . '/library/XenForo/Autoloader.php' );
XenForo_Autoloader::getInstance()->setupAutoloader( $fileDir . '/library' );

XenForo_Application::initialize( $fileDir . '/library', $fileDir );
XenForo_Application::set( 'page_start_time', $startTime );

$threadModel = XenForo_Model::create( 'XenForo_Model_Thread' );

$node_ids = array( 2, 3 );

foreach ( $node_ids AS $node_id ) {
   echo '<hr />';
   var_dump($node_id);
   $threads = $threadModel->getModelFromCache( 'XenForo_Model_Thread' )
                          ->getThreads(
                             array(
                                'discussion_state' => 'visible',
                                'node_id'        => $node_id,
                             ),
                             array(
                                'limit'          => $limit,
                                'order'          => 'thread_id',
                                'orderDirection' => 'desc',
                             ) );

   echo '<hr/>';
   foreach ( $threads AS $thread ) {
      var_dump($thread);
      echo(
         "<div class='entry-meta'><a href='"
         . XenForo_Link::buildPublicLink( 'canonical:threads',
            $thread )
         . "'>"
         . XenForo_Helper_String::wholeWordTrim( $thread['title'],
            40 )
         . "</a></div>"
      );
   }
}
 

EasyExpat

Member
Thanks @LPH. Since then I found a solution. A bit brutal maybe ...
I put the code to find the latest threads in a function then I call the function for each node, merge the arrays and sort out by latest post... works form me so far ;-)

PHP:
function getForumThreads($forumname, $limit)
{
    //Get Thread_array
    $threadModel = XenForo_Model::create( 'XenForo_Model_Thread' );

    if($forumname != "rss" && $forumname != "")
    {
        //Get Thread_array
        $db = XenForo_Application::getDb();
        $sql="SELECT node_id FROM xf_node WHERE node_name = '".$forumname."'";
        $data = $db->fetchOne ($sql);

        $threads = $threadModel->getModelFromCache('XenForo_Model_Thread')->getThreads( array(
            'discussion_state'        => 'visible',
            'node_id'        => $data,
                ), array(
                'limit'            => $limit,
                'order'            => 'thread_id',
                'orderDirection'=> 'desc' 
            ) );
    }
    else
    {
        $threads = $threadModel->getModelFromCache('XenForo_Model_Thread')->getThreads( array(
            'discussion_state'        => 'visible',
                ), array(
                'limit'            => $limit,
                'order'            => 'thread_id',
                'orderDirection'=> 'desc' 
            ) );
    }
    return $threads;
}
function sortBy($field, &$array, $direction = 'desc')
{
    usort($array, create_function('$a, $b', '
        $a = $a["' . $field . '"];
        $b = $b["' . $field . '"];

        if ($a == $b) return 0;

        $direction = strtolower(trim($direction));

        return ($a ' . ($direction == 'desc' ? '>' : '<') .' $b) ? -1 : 1;
    '));

    return true;
}

$limit=5;
$threads = getForumThreads('node_name1', $limit);
$threads2= getForumThreads('node_name2', $limit);
$threads = array_merge($threads, $threads2);
sortBy('last_post_date', $threads, 'desc');

//Display
$page = 999999999;
$count=1;

foreach ( $threads AS $thread ) {
if ($count++ > $limit)
break;
//Zend_Debug::dump($thread);

//Node name & translate if possible
$nodeModel = XenForo_Model::create('XenForo_Model_Node');
$curNode = $nodeModel->getNodeById($thread['node_id']);
//Zend_Debug::dump($curNode);
$forumname = $curNode['title'];                                 

echo "<li>";
echo "<a href=\"".XenForo_Link::buildPublicLink( 'canonical:threads',$thread, array('page' => $page) )."\">";
echo $forumname.": ".XenForo_Helper_String::wholeWordTrim( $thread['title'], 55 );
echo "</a>";
echo "</li>";
}
 
Last edited:

LPH

Well-known member
In my opinion, it’s a bad idea to use sql directly when conditions can be set. The sort and limits can also be done in the arrays so that you can optimize the code.
 

EasyExpat

Member
But I'm not using SQL here... :unsure: surely it can be optimized and nicely written, but I don't see hw to make the limit in the sorting as we need first to sort the all lot to find what comes first.
 

EasyExpat

Member
Oops :oops: yes (I will blame it on being very late for me...), completely forgot this one... I did not know how to get the node_id if you have only the node_name (and use router rules). Obviously there is certainly a way to avoid SQL here...:unsure:
 

LPH

Well-known member
Oops :oops: yes (I will blame it on being very late for me...), completely forgot this one... I did not know how to get the node_id if you have only the node_name (and use router rules). Obviously there is certainly a way to avoid SQL here...:unsure:

If you open the file XenForo->Model->Node (which is where XenForo_Model_Node comes from for code) then you will see two methods: getNodeByName and getNodeIdsFromNames.

Hope this helps.
 

Lukas W.

Well-known member
It is possible. Launch the XF app externally (code has been posted here in the dev forum a few times by now) and use the entity/finder system.
 
Top