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

Discussion forum for Extension Writers regarding Extension Development.
Post Reply
andreask
Registered User
Posts: 752
Joined: Fri Feb 27, 2009 6:13 pm
Name: Andreas

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

Post 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?
Here is what I am working on right now...
Inactive User Manager for phpBB
Give it a try...
If you would like to buy me a bier ;) for my work I will drink it on a hot summer day and thank you!!!
rxu
Extensions Development Team
Posts: 3711
Joined: Wed Oct 25, 2006 12:46 pm
Location: Siberia, Russian Federation
Contact:

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

Post 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.
andreask
Registered User
Posts: 752
Joined: Fri Feb 27, 2009 6:13 pm
Name: Andreas

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

Post 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!
Last edited by Kailey on Sun Aug 25, 2019 4:42 pm, edited 1 time in total.
Reason: Fixed URL BBCode :)
Here is what I am working on right now...
Inactive User Manager for phpBB
Give it a try...
If you would like to buy me a bier ;) for my work I will drink it on a hot summer day and thank you!!!
User avatar
mrgoldy
Former Team Member
Posts: 1394
Joined: Tue Oct 06, 2009 7:34 pm
Location: The Netherlands
Name: Gijs
Contact:

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

Post 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.
phpBB Studio / Member of the Studio

Contributing: You can do it too! Including testing Pull Requests (PR).
phpBB Development and Testing made easy.
andreask
Registered User
Posts: 752
Joined: Fri Feb 27, 2009 6:13 pm
Name: Andreas

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

Post 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).
Here is what I am working on right now...
Inactive User Manager for phpBB
Give it a try...
If you would like to buy me a bier ;) for my work I will drink it on a hot summer day and thank you!!!
rxu
Extensions Development Team
Posts: 3711
Joined: Wed Oct 25, 2006 12:46 pm
Location: Siberia, Russian Federation
Contact:

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

Post 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 %}
andreask
Registered User
Posts: 752
Joined: Fri Feb 27, 2009 6:13 pm
Name: Andreas

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

Post 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... :/
Here is what I am working on right now...
Inactive User Manager for phpBB
Give it a try...
If you would like to buy me a bier ;) for my work I will drink it on a hot summer day and thank you!!!
rxu
Extensions Development Team
Posts: 3711
Joined: Wed Oct 25, 2006 12:46 pm
Location: Siberia, Russian Federation
Contact:

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

Post 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>
Post Reply

Return to “Extension Writers Discussion”