Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: [Parser] Cascading Data causes ErrorException #7096

Closed
fraigo opened this issue Jan 11, 2023 · 3 comments · Fixed by #7103
Closed

Bug: [Parser] Cascading Data causes ErrorException #7096

fraigo opened this issue Jan 11, 2023 · 3 comments · Fixed by #7103
Labels
documentation Pull requests for documentation only waiting for info Issues or pull requests that need further clarification from the author

Comments

@fraigo
Copy link

fraigo commented Jan 11, 2023

PHP Version

7.4

CodeIgniter4 Version

4.2.11

CodeIgniter4 Installation Method

Composer (using codeigniter4/appstarter)

Which operating systems have you tested for this bug?

macOS, Linux

Which server did you use?

apache

Database

No response

What happened?

The following code example extracted from https://codeigniter4.github.io/userguide/outgoing/view_parser.html#cascading-data triggers an exception

ErrorException
foreach() argument must be of type array|object, string given
SYSTEMPATH/View/Parser.php at line 318

<?php

$template = '{name} lives in {location}{city} on {planet}{/location}.';

$data = [
    'name'     => 'George',
    'location' => ['city' => 'Red City', 'planet' => 'Mars'],
];

return $parser->setData($data)->renderString($template);
// Result: George lives in Red City on Mars.

Parser::parsePair(string $variable, array $data, string $template) expects an list of items with key/value pairs for the $data parameter. In this case $data is ['city' => 'Red City', 'planet' => 'Mars'].

It works fine with loop substitutions like in this example https://codeigniter4.github.io/userguide/outgoing/view_parser.html#loop-substitutions
It does not work with the above example or in any 'nested' substitution like this example https://codeigniter4.github.io/userguide/outgoing/view_parser.html#nested-substitutions

Steps to Reproduce

Run this code from a controller:

<?php
$parser = \Config\Services::parser();

$template = '{name} lives in {location}{city} on {planet}{/location}.';

$data = [
    'name'     => 'George',
    'location' => ['city' => 'Red City', 'planet' => 'Mars'],
];

return $parser->setData($data)->renderString($template);

Expected Output

George lives in Red City on Mars.

Anything else?

Backtrace:

SYSTEMPATH/View/Parser.php : 318 — CodeIgniter\Debug\Exceptions->errorHandler
SYSTEMPATH/View/Parser.php : 242 — CodeIgniter\View\Parser->parsePair
Arguments

$variable: location
$data: Array (
    [city] => Red City
    [planet] => Mars
)
$template: George lives in {location}{city} on {planet}{/location}.
@fraigo fraigo added the bug Verified issues on the current code behavior or pull requests that will fix them label Jan 11, 2023
@kenjis kenjis changed the title Bug: Bug: [Parser] Cascading Data causes ErrorException Jan 11, 2023
@kenjis kenjis added the documentation Pull requests for documentation only label Jan 12, 2023
@kenjis
Copy link
Member

kenjis commented Jan 12, 2023

Thank you for reporting.
I sent a PR to fix: #7103

fraigo added a commit to fraigo/CodeIgniter4 that referenced this issue Jan 12, 2023
fraigo added a commit to fraigo/CodeIgniter4 that referenced this issue Jan 12, 2023
@fraigo
Copy link
Author

fraigo commented Jan 12, 2023

@kenjis the example under 'Nested substitutions' has the same issue using the same data format for blog_entry value
https://codeigniter4.github.io/userguide/outgoing/view_parser.html#nested-substitutions

        $parser = \Config\Services::parser();
        $data = [
            'blog_title'   => 'My Blog Title',
            'blog_heading' => 'My Blog Heading',
            'blog_entry'   => [
                'title' => 'Title 1',
                'body'  => 'Body 1',
            ],
        ];
        return $parser->setData($data)->renderString("<h1>{blog_title} - {blog_heading}</h1>
        {blog_entry}
            <div>
                <h2>{title}</h2>
                <p>{body}</p>
            </div>
        {/blog_entry}");

In both cases, I think adding support for a single object of array/value pairs will allow this simple syntax to be parsed correctly without changing the documentation examples. I've sent a PR to implement this fix: #7109

@kenjis
Copy link
Member

kenjis commented Jan 13, 2023

@fraigo I fixed the sample code in my PR.

{vars}...{/vars} is for multiple data.
Why do you need to set a single data?

@kenjis kenjis added waiting for info Issues or pull requests that need further clarification from the author and removed bug Verified issues on the current code behavior or pull requests that will fix them labels Jan 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Pull requests for documentation only waiting for info Issues or pull requests that need further clarification from the author
Projects
None yet
2 participants