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

FIX Loop over current scope when no argument passed to loop block #11251

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/View/SSTemplateParser.peg
Original file line number Diff line number Diff line change
Expand Up @@ -1031,13 +1031,13 @@ class SSTemplateParser extends Parser implements TemplateParser
function ClosedBlock_Handle_Loop(&$res)
{
if ($res['ArgumentCount'] > 1) {
throw new SSTemplateParseException('Either no or too many arguments in control block. Must be one ' .
'argument only.', $this);
throw new SSTemplateParseException('Too many arguments in control block. Must be one or no' .
'arguments only.', $this);
}

//loop without arguments loops on the current scope
if ($res['ArgumentCount'] == 0) {
$on = '$scope->obj(\'Up\', null)->obj(\'Foo\', null)';
$on = '$scope->locally()->obj(\'Me\', null, true)';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is identical to what it renders out if you do a <% loop $Me %>

} else { //loop in the normal way
$arg = $res['Arguments'][0];
if ($arg['ArgumentMode'] == 'string') {
Expand Down
13 changes: 9 additions & 4 deletions src/View/SSTemplateParser.php
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file has not been manually edited. The comments were already in the .peg file and were likely manually removed from this file at some stage.

Original file line number Diff line number Diff line change
Expand Up @@ -1886,6 +1886,8 @@ function PresenceCheck_Argument(&$res, $sub)
$res['php'] .= '((bool)'.$sub['php'].')';
} else {
$php = ($sub['ArgumentMode'] == 'default' ? $sub['lookup_php'] : $sub['php']);
// TODO: kinda hacky - maybe we need a way to pass state down the parse chain so
// Lookup_LastLookupStep and Argument_BareWord can produce hasValue instead of XML_val
$res['php'] .= str_replace('$$FINAL', 'hasValue', $php ?? '');
}
}
Expand Down Expand Up @@ -4257,13 +4259,13 @@ function ClosedBlock__finalise(&$res)
function ClosedBlock_Handle_Loop(&$res)
{
if ($res['ArgumentCount'] > 1) {
throw new SSTemplateParseException('Either no or too many arguments in control block. Must be one ' .
'argument only.', $this);
throw new SSTemplateParseException('Too many arguments in control block. Must be one or no' .
'arguments only.', $this);
}

//loop without arguments loops on the current scope
if ($res['ArgumentCount'] == 0) {
$on = '$scope->obj(\'Up\', null)->obj(\'Foo\', null)';
$on = '$scope->locally()->obj(\'Me\', null, true)';
} else { //loop in the normal way
$arg = $res['Arguments'][0];
if ($arg['ArgumentMode'] == 'string') {
Expand Down Expand Up @@ -5290,6 +5292,8 @@ function Text__finalise(&$res)
$text = stripslashes($text ?? '');
$text = addcslashes($text ?? '', '\'\\');

// TODO: This is pretty ugly & gets applied on all files not just html. I wonder if we can make this
// non-dynamically calculated
$code = <<<'EOC'
(\SilverStripe\View\SSViewer::getRewriteHashLinksDefault()
? \SilverStripe\Core\Convert::raw2att( preg_replace("/^(\\/)+/", "/", $_SERVER['REQUEST_URI'] ) )
Expand Down Expand Up @@ -5328,7 +5332,8 @@ public function compileString($string, $templateName = "", $includeDebuggingComm

$this->includeDebuggingComments = $includeDebuggingComments;

// Ignore UTF8 BOM at beginning of string.
// Ignore UTF8 BOM at beginning of string. TODO: Confirm this is needed, make sure SSViewer handles UTF
// (and other encodings) properly
if (substr($string ?? '', 0, 3) == pack("CCC", 0xef, 0xbb, 0xbf)) {
$this->pos = 3;
}
Expand Down
9 changes: 9 additions & 0 deletions tests/php/View/SSViewerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,15 @@ public function testLocalFunctionsTakePriorityOverGlobals()
);
}

public function testCurrentScopeLoop(): void
{
$data = new ArrayList([['Val' => 'one'], ['Val' => 'two'], ['Val' => 'three']]);
$this->assertEqualIgnoringWhitespace(
'one two three',
$this->render('<% loop %>$Val<% end_loop %>', $data)
);
}

public function testCurrentScopeLoopWith()
{
// Data to run the loop tests on - one sequence of three items, each with a subitem
Expand Down
Loading