• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

[PAID] Fix this page

|Jordan|

Active member
#1
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:

|Jordan|

Active member
#6
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).
 

cclaerhout

Well-known member
#8
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);
 

LPH

Well-known member
#9
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.