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

Invalid argument supplied for foreach

Mythotical

Well-known member
#1
Ok this is odd, haven't gotten this error ever and I can not figure it out.

Here is the error:
Template Errors: xportal_latest_threads

  1. Invalid argument supplied for foreach() in C:\Program Files (x86)\Zend\Apache2\htdocs\xenforo\library\XenForo\Template\Abstract.php(208) : eval()'d code, line 6:
    5: ';
    6: foreach ($t AS $i)
    7: {
Model File: LatestThreads.php
PHP:
class xPortal_Model_LatestThreads extends XenForo_Model
{
    public function getThreads($id)
    {
        $ltOption = XenForo_Application::get('options')->xportal_latestThreads;
        $lThreads = $this->limitQueryResults('
            SELECT thread_id, title, user_id, username, post_date, last_post_user_id, last_post_username
            FROM xf_thread WHERE node_id = ' . $ltOption . ' ORDER BY thread_id ', 5);

        return $this->_getDb()->fetchAll($lThreads);
    }
}
Pulling data in ControllerPublic/Index.php:
PHP:
        $xpThreadModel = $this->getModelFromCache('xPortal_Model_LatestThreads');
        $t = $xpThreadModel->getThreads(5);
        $viewParams = array(
            't' => $t
        );
        return $this->responseView('xPortal_ViewPublic_Portal', 'xportal_index', $viewParams);
ViewPublic/Portal.php file:
PHP:
class xPortal_ViewPublic_Portal extends XenForo_ViewPublic_Base
{
    public function renderHtml()
    {
        $blocksModel = new xPortal_Model_Blocks;
        $left = $blocksModel->getLeft();
        $mid = $blocksModel->getMid();
        $right = $blocksModel->getRight();
        
        $leftBlocks = "";
        foreach ($left AS $lft)
        {
            $leftTemplate = $lft['temp_template'];
            $leftBlocks .= $this->createTemplateObject($leftTemplate);
        }
        $this->_params['leftBlocks'] = $leftBlocks;
        
        $midBlocks = "";
        foreach ($mid AS $m)
        {
            $midTemplate = $m['temp_template'];
            $midBlocks .= $this->createTemplateObject($midTemplate);
        }
        $this->_params['midBlocks'] = $midBlocks;
        
        $rightBlocks = "";
        foreach ($right AS $rgt)
        {
            $rightTemplate = $rgt['temp_template'];
            $rightBlocks .= $this->createTemplateObject($rightTemplate); 
        }
        $this->_params['rightBlocks'] = $rightBlocks;
    }
}
Might be a bit of info but giving all info I think would help in determining the issue.
 

Jeremy

Well-known member
#2
Are you trying to extend a function that returns a view? If so, you gotta do $var = parent::actionBlah(); and then set either $var->params OR $var->subView->params.

Edit: actually... what's the template code?
 

Mythotical

Well-known member
#3
HTML:
<div class="heading">Latest Threads</div>
<div class="secondaryContent">
<ol>
<xen:foreach loop="$t" value="$i">
<li>{xen:raw $i.title}</li>
</xen:foreach>
</ol>
</div>
<div>&nbsp;</div>
Thanks KK
 

Shadab

Well-known member
#4
Could be that your model isn't returning any threads. What's the output if you replace your template with:
Code:
<div class="heading">Latest Threads</div>
<div class="secondaryContent">
	{xen:helper dump, $t}
</div>
 

Jeremy

Well-known member
#5
I haven't really looked into it, but is renderHTML() overwriting a function in XenForo to render the template? If it is, do a Zend_Debug::dump($this->_params[]). As it is because $t is not set in the template (that was my problem for BB Code Manager).
 

Jeremy

Well-known member
#7
I hadn't looked for the fact that I'm writing a paper, but the snippets of code confused the heck out of me. But wasn't sure if his View was overwriting anything. Also not sure where his template is being used, but I'm most likely going to go with what you originally mentioned and say it isn't returning something.
 

Mythotical

Well-known member
#8
Could be that your model isn't returning any threads. What's the output if you replace your template with:
Code:
<div class="heading">Latest Threads</div>
<div class="secondaryContent">
	{xen:helper dump, $t}
</div>
Returns NULL in my block.
 

Jeremy

Well-known member
#9
Returns NULL in my block.
Which means that your getThreads() method is not working / returning any results. Attempt Zend_Debug::dump($t); and Zend_Debug::dump($ltOption); to see the results. Then take it and run the query yourself to see the results. Plus, $id never gets used, so throw that out (no need for extra variables).
 

Mythotical

Well-known member
#11
Ok apparently it is doing the query right but not returning any threads for some reason. I will just dig more on it after some sleep.
 

Shadab

Well-known member
#12
Just curious, why are you creating your own model to fetch the latest threads when you can easily accomplish this via xenforo's thread model (XenForo_Model_Thread) ?
 

Mythotical

Well-known member
#14
I still haven't gotten this stupid error figured out. I get a return of NULL I have tried to alter quite a few things but I have to be missing something.
 

Lawrence

Well-known member
#15
Steve, I tested your model for you, on my add-on I am currently working on, and dumped the results of $t:

PHP:
array(5) {
  [0] => array(7) {
    ["thread_id"] => int(1)
    ["title"] => string(22) "How to Create an Addon"
    ["user_id"] => int(1)
    ["username"] => string(8) "lawrence"
    ["post_date"] => int(1286387673)
    ["last_post_user_id"] => int(1)
    ["last_post_username"] => string(8) "lawrence"
  }
  [1] => array(7) {
    ["thread_id"] => int(2)
    ["title"] => string(9) "Test Post"
    ["user_id"] => int(2)
    ["username"] => string(6) "Dakota"
    ["post_date"] => int(1287580701)
    ["last_post_user_id"] => int(2)
    ["last_post_username"] => string(6) "Dakota"
  }
  [2] => array(7) {
    ["thread_id"] => int(3)
    ["title"] => string(17) "Test For Sticking"
    ["user_id"] => int(2)
    ["username"] => string(6) "Dakota"
    ["post_date"] => int(1289659226)
    ["last_post_user_id"] => int(2)
    ["last_post_username"] => string(6) "Dakota"
  }
  [3] => array(7) {
    ["thread_id"] => int(4)
    ["title"] => string(29) "Sticky Permission for a Group"
    ["user_id"] => int(2)
    ["username"] => string(6) "Dakota"
    ["post_date"] => int(1289659513)
    ["last_post_user_id"] => int(2)
    ["last_post_username"] => string(6) "Dakota"
  }
  [4] => array(7) {
    ["thread_id"] => int(5)
    ["title"] => string(25) "Attachment Uploading Test"
    ["user_id"] => int(1)
    ["username"] => string(8) "lawrence"
    ["post_date"] => int(1289666674)
    ["last_post_user_id"] => int(1)
    ["last_post_username"] => string(8) "lawrence"
  }
}
So it does work, and $t does come back as an array.

Here is what I did to get it to work. I created a new Model (remember it is within my Add-ons directory). I copied your code exactly, within the function, with the exception of setting $ltOptions to a value I know exists in my DB.

PHP:
<?php

/*
 * Model for Testing for Steve
 *
*/

class XenAms_Model_FetchThreads extends XenForo_Model
{

    public function getLatestThreads()
    {
        $ltOption = 2;
        $lThreads = $this->limitQueryResults('
            SELECT thread_id, title, user_id, username, post_date, last_post_user_id, last_post_username
            FROM xf_thread WHERE node_id = ' . $ltOption . ' ORDER BY thread_id ', 5);

        return $this->_getDb()->fetchAll($lThreads);
    }
}
I then edited one of my Listeners I am using to call the function and spit out the results. Here is the code I used to test your Model:

PHP:
$t = $this->_getThreadData();
Zend_Debug::dump($t);

    protected function _getThreadData()
    {

        return $this->_getThreadsModel()->getLatestThreads();
    }

    public function _getThreadsModel()
    {

        return XenForo_Model::create('XenAms_Model_FetchThreads');
    }
As you can see by the very first php code block in this post, $t came back as an array with 5 threads. It looks like to me, that your node_id set by your options was not correct. When I set it to a value I know doesn't exist, $t dumps with this:
PHP:
array(0) {
}
It looks like this is causing the problem (is the setting an array, or maybe the node_id put in doesn't exist?):

PHP:
$ltOption = XenForo_Application::get('options')->xportal_latestThreads
 

Mythotical

Well-known member
#16
Ahhh that would explain it then. Odd though guess back to the drawing board on that. Thanks though, now for latest threads overall using XF how would I handle that for displaying the latest 5 threads from the entire forum?
 

Lawrence

Well-known member
#17
Ahhh that would explain it then. Odd though guess back to the drawing board on that. Thanks though, now for latest threads overall using XF how would I handle that for displaying the latest 5 threads from the entire forum?
You can use the same model for the latest threads of the forum, like this:

PHP:
class XenAms_Model_FetchThreads extends XenForo_Model
{

    public function getLatestThreads($ltOption = 0)
    {
        $whereclause= "";

        if ($ltOption)
        {
            $whereclause =  " WHERE node_id = ".$ltOption;
        }

        $lThreads = $this->limitQueryResults('
            SELECT thread_id, title, user_id, username, post_date, last_post_user_id, last_post_username
            FROM xf_thread ' . $whereclause . ' ORDER BY thread_id DESC', 5);

        return $this->_getDb()->fetchAll($lThreads);

    }

}
Have you already taken permissions into account?
 

Lawrence

Well-known member
#19
Lawrence, what about the error I sent you in a convo?
Sorry, I had the flu bug for a bit, and then spent the last two days learning node types, and then all the possible different combination's you can have with the current ones. I needed to focus on that for displaying of a banner based on where the user is within the site, reguardless if it is a Page, Forum, or Category, or a child of any of those.

For the error you sent me: is your Threads.php method located in xPortal/ or xPortal/Model/ ? The error shows xPortal/ so if Threads.php is not located in that directory it won't find the method.