• This forum has been archived. New threads and replies may not be made. All add-ons/resources that are active should be migrated to the Resource Manager. See this thread for more information.

Backward Compatability Breaks!

I dont quite understand what has changed... or how to fix the new bugs...

It looks the same to me, just without any array keys.
 
It looks the same to me, just without any array keys.
That is pretty much it, so it is different. :) It's also JSON encoded as well, so it may not apply to you.

It's significantly smaller in the DB.
 
Well it seems to be giving me errors...
PHP:
$visitorID = XenForo_Visitor::getUserId();

$conditions = array(
	'deleted' => false,
	'moderated' => false,
);

$fetchOptions = array(
	'join' => XenForo_Model_Thread::FETCH_FORUM | XenForo_Model_Thread::FETCH_USER,
	'readUserId' => $visitorID,
	'watchUserId' => $visitorID,
	'postCountUserId' => $visitorID,
	'order' => 'last_post_date',
	'orderDirection' => 'desc',
	'limit' => $params['option']['recentthreads_limit'],
);

$threads = $this->getModelFromCache('XenForo_Model_Thread')->getThreads($conditions, $fetchOptions);

foreach ($threads AS &$thread)
{
	$thread['content_type'] = 'thread';
	$thread['content_id'] = $thread['thread_id'];
}
$threads = $this->getModelFromCache('XenForo_Model_Search')->getViewableSearchResults($threads);

On the last line, I get the following error:
An exception occurred: Undefined offset: 0 in /library/XenForo/Model/Search.php on line 235
  1. XenForo_Application::handlePhpError() in XenForo/Model/Search.php at line 235
  2. XenForo_Model_Search->groupSearchResultsByType() in XenForo/Model/Search.php at line 295
  3. XenForo_Model_Search->getViewableSearchResults() in EWRporta/Block/RecentThreads.php at line 31
  4. EWRporta_Block_RecentThreads->getBypass() in EWRporta/ViewPublic/Portal.php at line 87
  5. EWRporta_ViewPublic_Portal->getModuleParams() in EWRporta/ViewPublic/Portal.php at line 23
  6. EWRporta_ViewPublic_Portal->renderHtml() in XenForo/ViewRenderer/Abstract.php at line 222
  7. XenForo_ViewRenderer_Abstract->renderViewObject() in XenForo/ViewRenderer/HtmlPublic.php at line 67
  8. XenForo_ViewRenderer_HtmlPublic->renderView() in XenForo/FrontController.php at line 533
  9. XenForo_FrontController->renderView() in XenForo/FrontController.php at line 156
  10. XenForo_FrontController->run() in /index.php at line 17
 
Some of the PHPDocs are out of date, oops.

But write into the array via:

$thread[XenForo_Model_Search::CONTENT_TYPE]
$thread[XenForo_Model_Search::CONTENT_ID]

That said, using the search stuff for this really isn't necessary - you can get the permissions with the threads and filter out the results without doing all the search lookups.
 
That said, using the search stuff for this really isn't necessary - you can get the permissions with the threads and filter out the results without doing all the search lookups.
How would I do that?
 
Have a look at XenForo_Search_DataHandler_Thread, particularly getDataForResults and canViewResult.

Really the general concept is get all the thread (make sure you include permissionCombinationId), unserialize the permissions in the list, then loop through the list and unset any records that can't be viewed.

The code in that function is general purpose, so $viewingUser is roughly the visitor. You'll need to explicitly pass in a permissionCombinationId, but you don't need to pass $viewingUser to the permission check if you're checking against a visitor (you do need to pass their permissions though).
 
I still cant get this to work... I tried this:
PHP:
$conditions = array(
	'deleted' => false,
	'moderated' => false,
);

$fetchOptions = array(
	'order' => 'last_post_date',
	'orderDirection' => 'desc',
	'limit' => $options['recentthreads_limit'],
);

$threads = $this->getModelFromCache('XenForo_Model_Thread')->getThreads($conditions, $fetchOptions);
$threadIDs = array_keys($threads);

$visitor = XenForo_Visitor::getInstance();
$handler = XenForo_Search_DataHandler_Abstract::create('thread');

$threads = $handler->getDataForResults($threadIDs, $visitor, $threadIDs);
 
PHP:
/**
     * get the newest threads
     */
    protected function getThreads(){
        $nodeModel = $this->getModelFromCache('XenForo_Model_Node');
        $threadModel = $this->getModelFromCache('XenForo_Model_Thread');

        $viewableNodeList = $nodeModel->getViewableNodeList();      // check if this returns pages too, if yes, we need an other way

        $condition = array(
            'forum_ids' => array_keys($viewableNodeList), // had to overwrite the model to provide this feature
            'moderated' => false,
            'deleted' => false
        );

        $fetchOptions = array(
            'order' => 'last_post_date',
            'orderDirection' => 'desc',
            'join' => XenForo_Model_Thread::FETCH_FIRSTPOST,
            'limit' => XenForo_Application::get('options')->ragtek_feed_maxThreads
        );

        return $threadModel->getThreads($condition,$fetchOptions);
    }
that's what i'm using in http://xenforo.com/community/threads/global-rss-xml-feed.7856/
 
Okay... I got it using this:
PHP:
$conditions = array(
	'deleted' => false,
	'moderated' => false,
);

$fetchOptions = array(
	'order' => 'last_post_date',
	'orderDirection' => 'desc',
	'limit' => $options['recentthreads_limit'],
);

$threads = $this->getModelFromCache('XenForo_Model_Thread')->getThreads($conditions, $fetchOptions);

$threadIDs = array_keys($threads);
$visitor = XenForo_Visitor::getInstance()->toArray();
$handler = XenForo_Search_DataHandler_Abstract::create('XenForo_Search_DataHandler_Thread');

$threads = $handler->getDataForResults($threadIDs, $visitor, $threadIDs);

foreach ($threads AS &$thread)
{
	$thread = $this->getModelFromCache('XenForo_Model_Thread')->prepareThread($thread, $thread);
	$thread['canInlineMod'] = false;
	$thread['showForumLink'] = true;
}

return $threads;
 
I don't see how this affects styles...any insight on that, or what would be messed up if my style isn't up-to-date?
 
Jaxel, this is derived from the first set of code you provided. Your latest code does some different stuff (in terms of what it fetches and preparation), and I'm not sure if it's intentional.

I also haven't tested it at all - just typed it up in a text editor, so there might be parse errors. :)

PHP:
$visitor = XenForo_Visitor::getInstance();
$visitorID = $visitor['user_id'];

$conditions = array(
    'deleted' => false,
    'moderated' => false,
);

$fetchOptions = array(
    'join' => XenForo_Model_Thread::FETCH_FORUM | XenForo_Model_Thread::FETCH_USER,
    'permissionCombinationId' => $visitor['permission_combination_id'],
    'readUserId' => $visitorID,
    'watchUserId' => $visitorID,
    'postCountUserId' => $visitorID,
    'order' => 'last_post_date',
    'orderDirection' => 'desc',
    'limit' => $params['option']['recentthreads_limit'],
);

$threadModel = $this->getModelFromCache('XenForo_Model_Thread');

$threads = $threadModel->getThreads($conditions, $fetchOptions);
$threads = $threadModel->unserializePermissionsInList($threads, 'node_permission_cache');

foreach ($threads AS $threadId => $thread)
{
    if (!$threadModel->canViewThreadAndContainer($thread, $thread, $null, $thread['permissions']))
    {
        unset($threads[$threadId]);
    }
}
 
Jaxel, this is derived from the first set of code you provided. Your latest code does some different stuff (in terms of what it fetches and preparation), and I'm not sure if it's intentional.

I also haven't tested it at all - just typed it up in a text editor, so there might be parse errors. :)

PHP:
$visitor = XenForo_Visitor::getInstance();
$visitorID = $visitor['user_id'];

$conditions = array(
    'deleted' => false,
    'moderated' => false,
);

$fetchOptions = array(
    'join' => XenForo_Model_Thread::FETCH_FORUM | XenForo_Model_Thread::FETCH_USER,
    'permissionCombinationId' => $visitor['permission_combination_id'],
    'readUserId' => $visitorID,
    'watchUserId' => $visitorID,
    'postCountUserId' => $visitorID,
    'order' => 'last_post_date',
    'orderDirection' => 'desc',
    'limit' => $params['option']['recentthreads_limit'],
);

$threadModel = $this->getModelFromCache('XenForo_Model_Thread');

$threads = $threadModel->getThreads($conditions, $fetchOptions);
$threads = $threadModel->unserializePermissionsInList($threads, 'node_permission_cache');

foreach ($threads AS $threadId => $thread)
{
    if (!$threadModel->canViewThreadAndContainer($thread, $thread, $null, $thread['permissions']))
    {
        unset($threads[$threadId]);
    }
}

With this way it's not possible to get n Elements back.
If you limit 20 and 5 from them are not viable, the user will get only 15 back!
That's why we need an official way in the thread model, to use a list of forumids . (just like in http://xenforo.com/community/threads/backward-compatability-breaks.13290/#post-174050 )
 
With this way it's not possible to get n Elements back.
If you limit 20 and 5 from them are not viable, the user will get only 15 back!
That's why we need an official way in the thread model, to use a list of forumids . (just like in http://xenforo.com/community/threads/backward-compatability-breaks.13290/#post-174050 )
All you can do is select more than you need and hope that when you filter them, you have n remaining. Any more than that, you can chop off.

(This is the principle behind pretty much every search engine that has to manage diverse data)
 
All you can do is select more than you need and hope that when you filter them, you have n remaining. Any more than that, you can chop off.

(This is the principle behind pretty much every search engine that has to manage diverse data)
I have sleepless nights because of this because i don't understand it:D

Is there really no other way?
Isn't this extrem overhead?

Is there no easier way to get the last 50 new threads?
The readable forums are known because of $nodemodell->getViewableNodeList.

if i select ALL threads which are not moderated and not deleted and thread.node_id is in ( 1,2,4,6) shouldn't all results be viewable?
Why should i check them once again with the canViewThreadAndContainer method
 
The readable forums are known because of $nodemodell->getViewableNodeList.
There are far more variables involved than just that. What about soft-deleted threads, or threads in the moderation queue, or threads subject to other viewing restrictions?
 
There are far more variables involved than just that. What about soft-deleted threads, or threads in the moderation queue,
I thought the condition part is handling this?

$condition = array(
'moderated' => false,
'deleted' => false
);

Hm, i'll check this tommorow, before i go on your nerves^^
 
There are far more variables involved than just that. What about soft-deleted threads, or threads in the moderation queue, or threads subject to other viewing restrictions?
Is this a better way, as the code ragtek posted?

PHP:
 protected function _getThreads()
    {
        $visitor = XenForo_Visitor::getInstance();
        $visitorID = $visitor['user_id'];

        $conditions = array(
            'deleted' => false,
            'moderated' => false,
        );

        $fetchOptions = array(
            'join' => XenForo_Model_Thread::FETCH_FORUM |
                      XenForo_Model_Thread::FETCH_USER |
                      XenForo_Model_Thread::FETCH_FIRSTPOST,
            'permissionCombinationId' => $visitor['permission_combination_id'],
            'readUserId' => $visitorID,
            'watchUserId' => $visitorID,
            'postCountUserId' => $visitorID,
            'order' => 'last_post_date',
            'orderDirection' => 'desc',
            'limit' => XenForo_Application::get('options')->ragtek_feed_maxThreads * 2, // get more as we need because of the cut off, we'll remove them later
        );

        /** @var $threadModel XenForo_Model_Thread */
        $threadModel = $this->getModelFromCache('XenForo_Model_Thread');

        $threads = $threadModel->getThreads($conditions, $fetchOptions);
        $threads = $threadModel->unserializePermissionsInList($threads, 'node_permission_cache');

        foreach ($threads AS $threadId => $thread)
        {
            if (!$threadModel->canViewThreadAndContainer($thread, $thread, $null, $thread['permissions'])) {
                unset($threads[$threadId]);
            }
        }
        // make sure that we only return max. threads
        $threads = array_slice($threads, 0,XenForo_Application::get('options')->ragtek_feed_maxThreads);
        return $threads;
    }
 
Top Bottom