[PAID] Fix this page

|Jordan|

Active member
Licensed customer
This will probably take the average Xenforo coder seconds to fix but i have a php file that displays the latest 4 threads from specific nodes and dispalys the thread title and 400 characters of the first post.

I only want certain html tags to be included in the post output: Bold, Italic, Underline, Link, Ordered List, Unordered List, Indent and Outdent. If the message contains any of the tags i dont want displayed, then it shouldn't include what was in those tags (for example [media]http://youtube.com[/media] ).

Here's my code:

PHP:
<?php

$forumUrl = 'https://ftwgamer.com'; //Forum URL, must end with slash
$limit = 4;
$nodes = array("18", "2");

$startTime = microtime( true );

// Set to forum location - See XenForo index.php for information
$fileDir = '../';

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' );

$threads = $threadModel->getModelFromCache('XenForo_Model_Thread')->getThreads( array(
    'discussion_state'        => 'visible',
    'node_id'          => $nodes,
), array(
    'limit'          => $limit,
    'order'          => 'thread_id',
    'orderDirection' => 'desc'
) );

foreach ($threads as $thread) {
            $postModel = XenForo_Model::create('XenForo_Model_Post');
            $post = $postModel->getPostById($thread['first_post_id']);
        
            $bbCodeParser = new XenForo_BbCode_Parser(new XenForo_BbCode_Formatter_Wysiwyg);
            $bbCodeOptions = array(
                'showSignature' => false,
                'states' => array(
                    'viewAttachments' => false,
                    'stopLineBreakConversion' => true,
                )
            );
            $threadTitle = $thread['title'];
            $threadUrl = $threadUrl = $forumUrl. XenForo_Link::buildPublicLink('threads', $thread);
            $message = XenForo_ViewPublic_Helper_Message::getBbCodeWrapper($post, $bbCodeParser, $bbCodeOptions);
         

        echo
            "<h3><a href=\"$threadUrl\">"
            . XenForo_Helper_String::wholeWordTrim($threadTitle, 50)
            . "</a></h3>"
            . XenForo_Helper_String::wholeWordTrim($message, 400)
            ;
        }
     
?>

I dont know how much something like this would cost, but i assume it wouldn't take longer than a few minutes to make.

I need this done ASAP. Any takers?
 
Last edited:
I think the addon [bd] Widget Framework do it. You can take your time to look up about that ;)
 
I think the addon [bd] Widget Framework do it. You can take your time to look up about that ;)

Pretty sure this is running outside of the Xenforo Instance since its calling up the autoloader. Don't think he is displaying this within the xenforo powered site.
 
I can't use widget framework because this file will be in a directory outside of Xenforo.
 
That can be done?!?

I have no idea how to do that though. That's why i went with this method (found code examples on forum and merged them).
 
As requested by pm,

The customized loader (pastebin):
PHP:
<?php
$limit = 4;
$nodes = array("18", "2");

$startTime = microtime( true );

// Set to forum location - See XenForo index.php for information
$fileDir = './xenforo';

// Init autoloader
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 );

//Customize Code
   $xenOptions = XenForo_Application::get('options');
   $forumUrl = $xenOptions->boardUrl;

   $threadModel = XenForo_Model::create( 'XenForo_Model_Thread' );
   $threads = $threadModel->getModelFromCache('XenForo_Model_Thread')->getThreads( array(
     'discussion_state'  => 'visible',
     'node_id'  => $nodes,
   ), array(
     'limit'  => $limit,
     'order'  => 'thread_id',
     'orderDirection' => 'desc'
   ));

   $postModel = XenForo_Model::create('XenForo_Model_Post');
   /*PHP 5.5*/ $postIds = array_column($threads, 'first_post_id');
   /*PHP 5.3*/ //$postIds = array_map(function ($a) { return $a['first_post_id']; }, $threads);   
   $posts = $postModel->getPostsByIds($postIds);

   $bbCodeFormatter = XenForo_BbCode_Formatter_Base::create('Sedo_Demo_BbCode_Formatter_BaseFilter');
   $bbCodeFormatter->setBaseFilterInvisible(false);
   
   $allowedTags = array('b', 'i', 'u');
   $bbCodeFormatter->setBaseFilterAllowedTags($allowedTags);

   $bbCodeParser =  XenForo_BbCode_Parser::create($bbCodeFormatter);
  $bbCodeOptions = array(
     'showSignature' => false,
     'states' => array(
       'viewAttachments' => false,
       'stopLineBreakConversion' => true
     )
   );

   foreach($posts as $post)
   {
     $threadId = $post['thread_id'];
     $thread = $threads[$threadId];

     $threadTitle = $thread['title'];
     $threadUrl = $threadUrl = $forumUrl . '/' . XenForo_Link::buildPublicLink('threads', $thread);

     /*Method A*/
     //$message = $bbCodeParser->render($post['message']);

     /*Method B*/
     // You can customize this method with the $bbCodeOptions ; you set 'stopLineBreakConversion', so there won't have any line breaks
     $message = XenForo_ViewPublic_Helper_Message::getBbCodeWrapper($post, $bbCodeParser, $bbCodeOptions);
     $message = $message->__toString(); //we're not in XenForo template
   
    echo
     "<h3><a href=\"$threadUrl\">"
     . XenForo_Helper_String::wholeWordTrim($threadTitle, 50)
     . "</a></h3>"
     . XenForo_Helper_String::wholeWordTrim($message, 400)
     ;       
   }
   
   //Zend_Debug::dump($contents);

The customized Base formatter (pastebin):
PHP:
<?php
class Sedo_Demo_BbCode_Formatter_BaseFilter extends XenForo_BbCode_Formatter_Base
{
   protected $baseFilterAllowedTags = array();
   protected $baseFilterOriginalParentTags;
   protected $baseFilterInvisibleTags = false;

   public function setBaseFilterAllowedTags(array $tags)
   {
     $this->baseFilterAllowedTags = $tags;
     $this->_tags = $this->getTags();
   }

   public function setBaseFilterInvisible($value = false)
   {
     $this->baseFilterInvisibleTags = $value;
   }

   public function getTags()
   {
     $tags = parent::getTags();
     
     if($this->baseFilterOriginalParentTags !== null)
     {
       return $this->_baseFilterTags($this->baseFilterOriginalParentTags);
     }

     $this->baseFilterOriginalParentTags = $tags;
     return $this->_baseFilterTags($tags);
   }

   public function addCustomTags(array $tags)
   {
     $tags = $this->_baseFilterTags($tags);
     return parent::addCustomTags($tags);
   }   

   protected function _baseFilterTags($tags)
   {
     //Raw Bb Code return
     if(!$this->baseFilterInvisibleTags)
     {
       return array_intersect_key($tags, array_flip($this->baseFilterAllowedTags));
     }

     //Customized Bb Code return
     foreach($tags as $bbCode => $data)
     {
       if(!in_array($bbCode, $this->baseFilterAllowedTags))
       {
         if(!isset($tags[$bbCode]['bb_code_mode']))
         {
           //Normal Bb Code
           if(isset($tags[$bbCode]['callback']))
           {
             unset($tags[$bbCode]['callback']);
           }
           $tags[$bbCode]['replace'] = array('', '');
         }
         else
         {
           //Custom Bb Code
           $tags[$bbCode]['bb_code_mode'] = 'replace';
           $tags[$bbCode]['replace_html'] = '{text}';
         }
       }
     }
     
     return $tags;     
   }
}
//Zend_Debug::dump($bbCodeFormatter);
 
I like what you've done but the $forumUrl is not necessary. Simply use canonical:threads

PHP:
$threadUrl= XenForo_Link::buildPublicLink( 'canonical:threads', $thread );

Next, it might be nice to collapse some of the code to remove other unnecessary variables.

PHP:
$postModel = XenForo_Model::create('XenForo_Model_Post');
$post = $postModel->getPostById($thread['first_post_id']);

Would become:
PHP:
$post = XenForo_Model::create('XenForo_Model_Post')->getPostById($thread['first_post_id']);

Next, remove

PHP:
$xenOptions = XenForo_Application::get('options');
$forumUrl = $xenOptions->boardUrl;

Finally, there is an issue with this code displaying all results rather than only from those with permissions. The permission code would need to be added. Otherwise it works fine.
 
Back
Top Bottom