diff --git a/src/Runtime/LoopContext.php b/src/Runtime/LoopContext.php index 66755987a..4e4d238f8 100644 --- a/src/Runtime/LoopContext.php +++ b/src/Runtime/LoopContext.php @@ -38,7 +38,7 @@ final class LoopContext public function getRevindex0(): int { - return $this->loop->getLength('revindex0') - $this->getIndex(); + return max(0, $this->loop->getLength('revindex0') - $this->getIndex()); } public function getRevindex(): int diff --git a/src/Runtime/LoopIterator.php b/src/Runtime/LoopIterator.php index 275545b70..44c623e7a 100644 --- a/src/Runtime/LoopIterator.php +++ b/src/Runtime/LoopIterator.php @@ -74,8 +74,8 @@ final class LoopIterator implements \Iterator public function rewind(): void { $this->seq->rewind(); + $this->previous = ['valid' => false, 'key' => null, 'value' => null]; if ($this->seq->valid()) { - $this->previous = ['valid' => false, 'key' => null, 'value' => null]; $this->current = ['valid' => $this->seq->valid(), 'key' => $this->seq->key(), 'value' => $this->seq->current()]; } else { // EmptyIterator @@ -123,7 +123,12 @@ final class LoopIterator implements \Iterator { if (!$this->next) { $this->seq->next(); - $this->next = ['valid' => $this->seq->valid(), 'key' => $this->seq->key(), 'value' => $this->seq->current()]; + if ($this->seq->valid()) { + $this->next = ['valid' => $this->seq->valid(), 'key' => $this->seq->key(), 'value' => $this->seq->current()]; + } else { + // EmptyIterator + $this->next = ['valid' => false, 'key' => null, 'value' => null]; + } } return $this->next; diff --git a/tests/Fixtures/tags/for/loop_in_else.test b/tests/Fixtures/tags/for/loop_in_else.test new file mode 100644 index 000000000..abc8bf19f --- /dev/null +++ b/tests/Fixtures/tags/for/loop_in_else.test @@ -0,0 +1,62 @@ +--TEST-- +"for" tag loop behavior in an else clause +--TEMPLATE-- +{% for item in [] %} +{% else %} +{{ loop.previous is null ? 'OK' : 'KO' }} +{{ loop.next is null ? 'OK' : 'KO' }} +{{ loop.first ? 'OK' : 'KO' }} +{{ loop.last ? 'OK' : 'KO' }} +{{ loop.index0 is same as 0 ? 'OK' : 'KO' }} +{{ loop.revindex0 is same as 0 ? 'OK' : 'KO' }} +{{ loop.length is same as 0 ? 'OK' : 'KO' }} +{{ loop.depth is same as 1 ? 'OK' : 'KO' }} +{% endfor %} + +{% for item in empty_it %} +{% else %} +{{ loop.previous is null ? 'OK' : 'KO' }} +{{ loop.next is null ? 'OK' : 'KO' }} +{{ loop.first ? 'OK' : 'KO' }} +{{ loop.last ? 'OK' : 'KO' }} +{{ loop.index0 is same as 0 ? 'OK' : 'KO' }} +{{ loop.depth is same as 1 ? 'OK' : 'KO' }} +{% endfor %} + +{% for item in yielding_it %} +{% else %} +{{ loop.previous is null ? 'OK' : 'KO' }} +{{ loop.next is null ? 'OK' : 'KO' }} +{{ loop.first ? 'OK' : 'KO' }} +{{ loop.last ? 'OK' : 'KO' }} +{{ loop.index0 is same as 0 ? 'OK' : 'KO' }} +{{ loop.depth is same as 1 ? 'OK' : 'KO' }} +{% endfor %} +--DATA-- +return [ + 'empty_it' => new \EmptyIterator(), + 'yielding_it' => (function (): \Generator { return; yield; })(), +] +--EXPECT-- +OK +OK +OK +OK +OK +OK +OK +OK + +OK +OK +OK +OK +OK +OK + +OK +OK +OK +OK +OK +OK