From 54cbbdd8e90f871e71c8aa0abfd5dc929ed003cb Mon Sep 17 00:00:00 2001 From: Alex Oliver Date: Sun, 20 Nov 2022 23:33:38 +0000 Subject: [PATCH] Add loop functionality and tests --- src/brace.php | 69 +++++++++++++++++-- tests/logs/testdox.txt | 2 + .../iterators/iteration-loop-ascending.tpl | 3 + .../iterators/iteration-loop-descending.tpl | 3 + tests/tests/iterators/iteratorTest.php | 26 +++++++ 5 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 tests/tests/iterators/iteration-loop-ascending.tpl create mode 100644 tests/tests/iterators/iteration-loop-descending.tpl diff --git a/src/brace.php b/src/brace.php index 5b30dc4..691a1f2 100644 --- a/src/brace.php +++ b/src/brace.php @@ -264,16 +264,29 @@ private function processLine(string $this_line, array $dataset, bool $render): v } /** Process if condition or each block */ - if (!$this->is_block && preg_match_all('/{{if (.*?)}}|{{each (.*?)}}/i', $this_line, $matches, PREG_SET_ORDER)) { + if (!$this->is_block && preg_match_all('/{{if (.*?)}}|{{each (.*?)}}|{{loop (.*?)}}/i', $this_line, $matches, PREG_SET_ORDER)) { /** Set block variables */ $this->block_condition = $matches[0]; /** Set condition type */ $condition_type = $this->block_condition[0]; - $this->block_condition[] = (preg_match('/{{if/', $condition_type) ? 'if' : (preg_match('/{{each/', $condition_type) ? 'each' : '')); - $this->block_spaces = strpos($this_line, '{{' . (isset($this->block_condition[3]) ? $this->block_condition[3] : $this->block_condition[2])); + preg_match('/{{(.*?) /', $condition_type, $match_types); + $block_type = ''; + + if (isset($match_types[1])) { + switch ($match_types[1]) { + case 'if': + case 'each': + case 'loop': + $block_type = $match_types[1]; + break; + } + } + + $this->block_condition[] = $block_type; + $this->block_spaces = strpos($this_line, '{{' . $block_type); $this->is_block = true; /** Blank line */ @@ -353,10 +366,11 @@ private function processBlock(string $block_string, array $conditions, array $da $process_content = ''; /** Set is If or Each statement */ - $if_or_each = (isset($conditions[3]) ? $conditions[3] : (isset($conditions[2]) ? $conditions[2] : false)); + $block_type = end($conditions); + // $if_or_each = (isset($conditions[3]) ? $conditions[3] : (isset($conditions[2]) ? $conditions[2] : false)); - if ($if_or_each) { - switch ($if_or_each) { + if ($block_type) { + switch ($block_type) { case 'if': /** new core parser class instance */ $processBlock = new Parser(); @@ -396,12 +410,55 @@ private function processBlock(string $block_string, array $conditions, array $da case 'each': $process_content = $this->processEachStatement($conditions[2], $block_string, $dataset); break; + case 'loop': + $process_content = $this->processLoop($conditions[3], $block_string); + break; } } return $process_content; } + /** + * Process loop + * @param string $loop_statement + * @param string $block_content + * @return string + */ + private function processLoop(string $loop_statement, string $block_content): string + { + $loop_components = explode(' ', trim($loop_statement)); + $return_string = ''; + + if (count($loop_components) === 3 && $loop_components[1] === 'to') { + $from = intval($loop_components[0]); + $to = intval($loop_components[2]); + + /** new core parser class instance */ + $process_each_block = new Parser(); + $process_each_block->template_path = $this->template_path; + + if ($from < $to) { + for ($i = $from; $i <= $to; $i += 1) { + $process_each_block->parseInputString($block_content, [ + '_KEY' => $i + ], false); + $return_string .= $process_each_block->return(); + $process_each_block->export_string = ''; + } + } else { + for ($i = $from; $i >= $to; $i -= 1) { + $process_each_block->parseInputString($block_content, [ + '_KEY' => $i + ], false); + $return_string .= $process_each_block->return(); + $process_each_block->export_string = ''; + } + } + } + + return $return_string; + } /** * Process each statement diff --git a/tests/logs/testdox.txt b/tests/logs/testdox.txt index acc04a5..921fe22 100644 --- a/tests/logs/testdox.txt +++ b/tests/logs/testdox.txt @@ -54,6 +54,8 @@ Iterators (ConditionTests\Iterators) [x] Iterator key value [x] Iterator key value type two [x] Inline iterator key value + [x] Loop iteration ascending + [x] Loop iteration descending Shortcode (ConditionTests\Shortcode) [x] Shortcode diff --git a/tests/tests/iterators/iteration-loop-ascending.tpl b/tests/tests/iterators/iteration-loop-ascending.tpl new file mode 100644 index 0000000..4fcadc8 --- /dev/null +++ b/tests/tests/iterators/iteration-loop-ascending.tpl @@ -0,0 +1,3 @@ +{{loop 1 to 3}} +
  • {{_KEY}}
  • +{{end}} \ No newline at end of file diff --git a/tests/tests/iterators/iteration-loop-descending.tpl b/tests/tests/iterators/iteration-loop-descending.tpl new file mode 100644 index 0000000..b222f71 --- /dev/null +++ b/tests/tests/iterators/iteration-loop-descending.tpl @@ -0,0 +1,3 @@ +{{loop 3 to 1}} +
  • {{_KEY}}
  • +{{end}} \ No newline at end of file diff --git a/tests/tests/iterators/iteratorTest.php b/tests/tests/iterators/iteratorTest.php index f1de70a..d5a3264 100644 --- a/tests/tests/iterators/iteratorTest.php +++ b/tests/tests/iterators/iteratorTest.php @@ -213,4 +213,30 @@ public function testInlineIteratorKeyValue(): void ], false)->return() ); } + + public function testLoopIterationAscending(): void + { + $brace = new Brace\Parser(); + $brace->template_path = __DIR__ . '/'; + + $this->assertEquals( + "
  • 1
  • \n" . + "
  • 2
  • \n" . + "
  • 3
  • \n", + $brace->parseInputString('[@include iteration-loop-ascending]', [], false)->return() + ); + } + + public function testLoopIterationDescending(): void + { + $brace = new Brace\Parser(); + $brace->template_path = __DIR__ . '/'; + + $this->assertEquals( + "
  • 3
  • \n" . + "
  • 2
  • \n" . + "
  • 1
  • \n", + $brace->parseInputString('[@include iteration-loop-descending]', [], false)->return() + ); + } }