Page 1 of 1

context.php on line 148: Invalid argument supplied for foreach()

Posted: Fri Aug 23, 2019 10:41 pm
by andreask
Hello creators!
It has been a long time.

But I'll cut right to the point!

I am assigning an array in a block of vars and in that array I have another one array. So far so good everything looks to work "fine".
Except that I get the message of the subject context.php on line 148: Invalid argument supplied for foreach()].

Image

Here is the php part of the problem:

Code: Select all

        $sql = 'SELECT * from ' . $this->utl_table;
        $list_rules = $db->sql_query($sql);
        if($list_rules)
        {
            while ($rule = $db->sql_fetchrow($list_rules))
            {
                $forums = json_decode($rule['utl_rule_forum_ids'], true);
                $sql = 'SELECT forum_name FROM ' . FORUMS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forums);
                $res = $db->sql_query($sql);
                $forum_names = $db->sql_fetchrowset($res);
                foreach ($forum_names as $name)
                {
                    $clean[] = $name['forum_name'];
                }
                $rule = array_merge($rule, array('utl_forum_names' => $clean));
                unset($clean);
                $db->sql_freeresult($res);
                $template->assign_block_vars('andreask_utl_rules', $rule);
            }
            $db->sql_freeresult($list_rules);
        }
And this is my template file:

Code: Select all

<thead>
    <tr>
        <th>{{ lang('NAME') }}</th>
        <th>{{ lang('DAYS') }}</th>
        <th>{{ lang('DAYS_OPTION') }}</th>
        <th>{{ lang('POSTS') }}</th>
        <th>{{ lang('POSTS_OPTION') }}</th>
        <th>{{ lang('MAX_POSTS') }}</th>
        <th>{{ lang('MAX_POSTS_OPTION') }}</th>
        <th>{{ lang('FORUMS') }}</th>
        <th>{{ lang('DATE') }}</th>
        <th>{{ lang('ACTIVE') }}</th>
    </tr>
</thead>
<tbody>
    {% for rule in andreask_utl_rules %}
    <tr>
    <td><a href="{{ rule.S_EDIT_URL }}">{{ rule.utl_rule_name }}</a></td>
    <td>{{ rule.utl_rule_amount_of_days }}</td>
    <td>{{ rule.utl_rule_amount_of_days_opt }}</td>
    <td>{{ rule.utl_rule_amount_of_posts }}</td>
    <td>{{ rule.utl_rule_amount_of_posts_opt }}</td>
    <td>{{ rule.utl_rule_max_posts }}</td>
    <td>{{ rule.utl_rule_max_posts_opt }}</td>
    <td>{% for forum in rule.utl_forum_names %}{{ forum }}</br>{% endfor %}</td>
    <td>{{ rule.utl_rule_created_date }}</td>
    <td>{{ rule.utl_rule_active }}</td>
    </tr>
    {% else %}
    <tr>
        <td colspan="6" style="text-align: center;">{{ lang('ANDREASK_NOTHING_YET')}}</td>
    </tr>
    {% endfor %}
</tbody>
</table>
The nested array is the third for the right in the table.
What am I doing wrong?

Re: context.php on line 148: Invalid argument supplied for foreach()

Posted: Sun Aug 25, 2019 6:17 am
by rxu
I guess in your case assigning nested loops would look like that (untested as there's no whole code to do)

Code: Select all

		while ($rule = $db->sql_fetchrow($list_rules))
		{
			$template->assign_block_vars('andreask_utl_rules', $rule);

			$forums = json_decode($rule['utl_rule_forum_ids'], true);
			$sql = 'SELECT forum_name FROM ' . FORUMS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forums);
			$res = $db->sql_query($sql);
			$forum_names = $db->sql_fetchrowset($res);
			foreach ($forum_names as $name)
			{
				$clean[] = $name['forum_name'];
				$template->assign_block_vars('andreask_utl_rules.utl_forum_names', $clean);
			}
			unset($clean);
			$db->sql_freeresult($res);
		}
Although performing SQL queries in the loop is suboptimal, but that's unrelated to the question.

Re: context.php on line 148: Invalid argument supplied for foreach()

Posted: Sun Aug 25, 2019 12:13 pm
by andreask
Thank you rxu, I understand that it's not the best way to do it.
And I am going to change this.
Could you please tell me what do I have to do in the template file in order to show the list for this part?
$template->assign_block_vars('andreask_utl_rules.utl_forum_names', $clean);

Because when I use this syntax:
<td>{% for forum in rule.utl_forum_names %}{{ forum|length }}</br>{% endfor %}</td>
So far nothing I tried has worked, utl_forum_names.andreask_utl_rules, andreask_utl_rules.utl_forum_names
I get an array instead
While when I was using the array_merge function I was able to see the list just fine! :/

I also have not found any clear documentation here regarding my problem...
I only stumbled upon this which is not for my case. This is with the old tagging where I use the new twig tags and my nested array is not associated as in the small example is given in the documentation.

Thanks again!

Re: context.php on line 148: Invalid argument supplied for foreach()

Posted: Sun Aug 25, 2019 12:29 pm
by mrgoldy
You could try using the $template->assign_block_vars_array() instead.

Moreover, you're performing a SQL query on each loop.
It might be better to retrieve all forum data before looping over all the rows.

Re: context.php on line 148: Invalid argument supplied for foreach()

Posted: Sun Aug 25, 2019 12:56 pm
by andreask
Hi mrgoldy,

I have modified the script and I suppose it does that now. I guess it can be done better, but for now I only want to see the results without any issues and then I'll tweak it.
You can also see it here (github).

Re: context.php on line 148: Invalid argument supplied for foreach()

Posted: Sun Aug 25, 2019 2:11 pm
by rxu
andreask wrote:
Sun Aug 25, 2019 12:13 pm
what do I have to do in the template file in order to show the list for this part
For me, it worked like

Code: Select all

{% for key, forum in rule.utl_forum_names %}{{ forum[key] }}</br>{% endfor %}

Re: context.php on line 148: Invalid argument supplied for foreach()

Posted: Wed Aug 28, 2019 11:49 am
by andreask
I forgot to say, thank you rxu this worked perfectly.
Though I don't understand why... :)

I mean isn't the "key" the key of forum?
Like...
0=>forum=>array()
key=>forum=>array()
at least that is how it is in php right?

I'm confused... :/

Re: context.php on line 148: Invalid argument supplied for foreach()

Posted: Wed Aug 28, 2019 2:35 pm
by rxu
andreask
Sorry, that is just because of random code really.
Proper way to code would look like that (related part changed):

Code: Select all

foreach ($forum_names as $name)
{
	$template->assign_block_vars('andreask_utl_rules.utl_forum_names', ['FORUM_NAME' => $name['forum_name']]);
}
The use of $clean array can be just dropped.
and in template

Code: Select all

<td>{% for forum in rule.utl_forum_names %}{{ forum.FORUM_NAME }}</br>{% endfor %}</td>