expressionengine - PHP explode not working on string, fetched from EECMS template
I'm building an ExpressionEngine module in PHP.
In ExpressionEngine, one can access parameters passed to the module in a template using:$my_param = $this->EE->TMPL->fetch_param('my_param');
However, when I fetch a string that way, explode does not work on it:
public function get_tyres()
{
$tyres = $this->EE->TMPL->fetch_param('tyres');
echo($tyres);
// this shows: '205/55R16M+S|205/55R16|205/55R16'
// now I want to split it into single tyres, using the pipe as a delimiter
$tyre_array = explode("|", $tyres);
foreach($tyre_array as $tyre)
{
echo($tyre . '<br>');
}
// the above produces: '205/55R16M+S|205/55R16|205/55R16',
// where I'd expect it to produce:
// 205/55R16M+S
// 205/55R16
// 205/55R16
}
I've tried to specifically cast to a string using$tyres = (string) $this->EE->TMPL->fetch_param('tyres');
, with no luck.
I've also tried manually creating and exploding a string:$tyres = '205/55R16M+S|205/55R16|205/55R16';
which worked, but obviously I need to get the param from the template, not hard code it.
Lastly, I tried using preg_split and a regex, with no luck either:$tyre_array = preg_split('/\|/', $tyres);
which also returned an array with the entire string in it.
What could be at work here? Is this a scope related thing? Is it an encoding-related thing? What to look for next?
Update
Okay, we're getting somewhere. I've added the following to the function:
for($i = 0; $i < strlen($tyres); $i++) {
echo substr($tyres, $i, 1) . ", ";
}
Which returns...{, v, e, r, s, i, o, n, :, t, y, r, e, s, },
and that is in fact the variable passed to PHP in the HTML template:
{exp:my_module:tyres tyres="{version:tyres}"}
<h1>{tyre:name}</h1>
... more irrelevant HTML
{/exp:my_module:tyres}
This means it has something to do with the parsing order of ExpressionEngine. Apparently, the variable{version:tyres}
isn't parsed yet. So I pass that variable to the module, it tries to explode it by the pipe character, but the string{version:tyres}
does not contain a pipe, meaning it can't be exploded. ExpressionEngine then returns{version:tyres}
as a whole, passes it back in to the template and then the variable is parsed as205/55R16M+S|205/55R16|205/55R16
.
I've tested this, and can confirm that exploding by ':' returns the array:
array (size=2)
0 => string '{version' (length=8)
1 => string 'tyres}' (length=6)
I will now look in to ExpressionEngine parse order. If anyone has an idea on how to work around this, I'd be happy to know ;-).
Answer
Solution:
I tested your code, copy and pasting your test string, and it works fine for me. Make sure your pipe ("|") is really the character you think it is, and not, say, some crazy unicode stuff that just looks like a pipe, but is actually Klingon for for 'staff', or something.
Try something like this as a reality check:
Answer
Solution:
The answer lies in the ExpressionEngine parse order, as outlined here: https://ellislab.com/expressionengine/user-guide/templates/template_engine.html#rendering-stages
Because the template tag {exp:my_module:tyres} used a variable passed to it by a template tag that it was nested in, the variable wasn't parsed yet as the innermost tags are parsed first.
Adding the parameter
parse="inward"
to the outer template tag makes ExpressionEngine parse that tag first, passing the correct variable to the inner template tag.See https://ellislab.com/expressionengine/user-guide/templates/plugins.html#changing-parsing-order for more on changing the parsing order.