From 91f4ba15f15970638da5091639e35daae17f3c6f Mon Sep 17 00:00:00 2001 From: Hamish Friedlander Date: Sat, 11 Feb 2012 15:30:46 +1300 Subject: [PATCH] ENHANCEMENT: supporting "current scope" loop and with: (with Children) (loop) $Title (end_loop) (end_with) --- tests/view/SSViewerTest.php | 45 +++++++++++++++++++++++++++++++---- view/SSTemplateParser.php | 21 +++++++++------- view/SSTemplateParser.php.inc | 21 +++++++++------- 3 files changed, 67 insertions(+), 20 deletions(-) diff --git a/tests/view/SSViewerTest.php b/tests/view/SSViewerTest.php index 78f2e8695..45e6da12e 100644 --- a/tests/view/SSViewerTest.php +++ b/tests/view/SSViewerTest.php @@ -121,21 +121,58 @@ SS )); //call method with lots of arguments - $result = $this->render('<% control Page %>$lotsOfArguments11("a","b","c","d","e","f","g","h","i","j","k")<% end_control %>',$data); + $result = $this->render('<% with Page %>$lotsOfArguments11("a","b","c","d","e","f","g","h","i","j","k")<% end_with %>',$data); $this->assertEquals("abcdefghijk",$result, "Function can accept up to 11 arguments"); //call method that does not exist - $result = $this->render('<% control Page %><% if IDoNotExist %>hello<% end_if %><% end_control %>',$data); + $result = $this->render('<% with Page %><% if IDoNotExist %>hello<% end_if %><% end_with %>',$data); $this->assertEquals("",$result, "Method does not exist - empty result"); //call if that does not exist - $result = $this->render('<% control Page %>$IDoNotExist("hello")<% end_control %>',$data); + $result = $this->render('<% with Page %>$IDoNotExist("hello")<% end_with %>',$data); $this->assertEquals("",$result, "Method does not exist - empty result"); //call method with same name as a global method (local call should take priority) - $result = $this->render('<% control Page %>$absoluteBaseURL<% end_control %>',$data); + $result = $this->render('<% with Page %>$absoluteBaseURL<% end_with %>',$data); $this->assertEquals("testLocalFunctionPriorityCalled",$result, "Local Object's function called. Did not return the actual baseURL of the current site"); } + + function testCurrentScopeLoopWith() { + // Data to run the loop tests on - one sequence of three items, each with a subitem + $data = new ArrayData(array( + 'Foo' => new DataObjectSet(array( + 'Subocean' => new ArrayData(array( + 'Name' => 'Higher' + )), + new ArrayData(array( + 'Sub' => new ArrayData(array( + 'Name' => 'SubKid1' + )) + )), + new ArrayData(array( + 'Sub' => new ArrayData(array( + 'Name' => 'SubKid2' + )) + )), + new SSViewerTest_Page('Number6') + )) + )); + + $result = $this->render('<% loop Foo %>$Number<% if Sub %><% with Sub %>$Name<% end_with %><% end_if %><% end_loop %>',$data); + $this->assertEquals("SubKid1SubKid2Number6",$result, "Loop works"); + + $result = $this->render('<% loop Foo %>$Number<% if Sub %><% with Sub %>$Name<% end_with %><% end_if %><% end_loop %>',$data); + $this->assertEquals("SubKid1SubKid2Number6",$result, "Loop works"); + + $result = $this->render('<% with Foo %>$Count<% end_with %>',$data); + $this->assertEquals("4",$result, "4 items in the DataObjectSet"); + + $result = $this->render('<% with Foo %><% loop Up.Foo %>$Number<% if Sub %><% with Sub %>$Name<% end_with %><% end_if %><% end_loop %><% end_with %>',$data); + $this->assertEquals("SubKid1SubKid2Number6",$result, "Loop in with Up.Foo scope works"); + + $result = $this->render('<% with Foo %><% loop %>$Number<% if Sub %><% with Sub %>$Name<% end_with %><% end_if %><% end_loop %><% end_with %>',$data); + $this->assertEquals("SubKid1SubKid2Number6",$result, "Loop in current scope works"); + } function testObjectDotArguments() { $this->assertEquals( diff --git a/view/SSTemplateParser.php b/view/SSTemplateParser.php index 15caa835c..82528bf4c 100644 --- a/view/SSTemplateParser.php +++ b/view/SSTemplateParser.php @@ -2960,17 +2960,22 @@ class SSTemplateParser extends Parser { * This is an example of a block handler function. This one handles the loop tag. */ function ClosedBlock_Handle_Loop(&$res) { - if ($res['ArgumentCount'] != 1) { + if ($res['ArgumentCount'] > 1) { throw new SSTemplateParseException('Either no or too many arguments in control block. Must be one argument only.', $this); } - - $arg = $res['Arguments'][0]; - if ($arg['ArgumentMode'] == 'string') { - throw new SSTemplateParseException('Control block cant take string as argument.', $this); + + //loop without arguments loops on the current scope + if ($res['ArgumentCount'] == 0) { + $on = '$scope->obj(\'Up\', null, true)->obj(\'Foo\', null, true)'; + } else { //loop in the normal way + $arg = $res['Arguments'][0]; + if ($arg['ArgumentMode'] == 'string') { + throw new SSTemplateParseException('Control block cant take string as argument.', $this); + } + $on = str_replace('$$FINAL', 'obj', ($arg['ArgumentMode'] == 'default') ? $arg['lookup_php'] : $arg['php']); } - - $on = str_replace('$$FINAL', 'obj', ($arg['ArgumentMode'] == 'default') ? $arg['lookup_php'] : $arg['php']); - return + + return $on . '; $scope->pushScope(); while (($key = $scope->next()) !== false) {' . PHP_EOL . $res['Template']['php'] . PHP_EOL . '}; $scope->popScope(); '; diff --git a/view/SSTemplateParser.php.inc b/view/SSTemplateParser.php.inc index 2feae83b5..88202e93d 100644 --- a/view/SSTemplateParser.php.inc +++ b/view/SSTemplateParser.php.inc @@ -638,17 +638,22 @@ class SSTemplateParser extends Parser { * This is an example of a block handler function. This one handles the loop tag. */ function ClosedBlock_Handle_Loop(&$res) { - if ($res['ArgumentCount'] != 1) { + if ($res['ArgumentCount'] > 1) { throw new SSTemplateParseException('Either no or too many arguments in control block. Must be one argument only.', $this); } - - $arg = $res['Arguments'][0]; - if ($arg['ArgumentMode'] == 'string') { - throw new SSTemplateParseException('Control block cant take string as argument.', $this); + + //loop without arguments loops on the current scope + if ($res['ArgumentCount'] == 0) { + $on = '$scope->obj(\'Up\', null, true)->obj(\'Foo\', null, true)'; + } else { //loop in the normal way + $arg = $res['Arguments'][0]; + if ($arg['ArgumentMode'] == 'string') { + throw new SSTemplateParseException('Control block cant take string as argument.', $this); + } + $on = str_replace('$$FINAL', 'obj', ($arg['ArgumentMode'] == 'default') ? $arg['lookup_php'] : $arg['php']); } - - $on = str_replace('$$FINAL', 'obj', ($arg['ArgumentMode'] == 'default') ? $arg['lookup_php'] : $arg['php']); - return + + return $on . '; $scope->pushScope(); while (($key = $scope->next()) !== false) {' . PHP_EOL . $res['Template']['php'] . PHP_EOL . '}; $scope->popScope(); ';