CompilesLoops.php
TLDR
This file, CompilesLoops.php
, is a trait that provides methods to compile various loop constructs in PHP templates.
Methods
compileForelse
This method compiles the @forelse
statement in a PHP template into valid PHP code. It parses the given expression to extract the iteratee and iteration variables, and generates the necessary PHP code to loop over the iteratee.
compileEmpty
This method compiles the @empty
statement in a PHP template into valid PHP code. It generates the PHP code to check if the given expression is empty, and generates the code to handle the else block if the expression is empty.
compileEndforelse
This method generates the PHP code to end the @forelse
block.
compileEndEmpty
This method generates the PHP code to end the @empty
block.
compileFor
This method compiles the @for
statement in a PHP template into valid PHP code. It generates the PHP code to start a for loop with the given expression.
compileForeach
This method compiles the @foreach
statement in a PHP template into valid PHP code. It parses the given expression to extract the iteratee and iteration variables, and generates the necessary PHP code to loop over the iteratee.
compileBreak
This method compiles the @break
statement in a PHP template into valid PHP code. It generates the PHP code to break out of a loop, either with a specified number of iterations or without.
compileContinue
This method compiles the @continue
statement in a PHP template into valid PHP code. It generates the PHP code to skip the current iteration of a loop, either with a specified number of iterations or without.
compileEndfor
This method generates the PHP code to end the @for
block.
compileEndforeach
This method generates the PHP code to end the @foreach
block.
compileWhile
This method compiles the @while
statement in a PHP template into valid PHP code. It generates the PHP code to start a while loop with the given expression.
compileEndwhile
This method generates the PHP code to end the @while
block.
<?php
namespace Illuminate\View\Compilers\Concerns;
use Illuminate\Contracts\View\ViewCompilationException;
trait CompilesLoops
{
/**
* Counter to keep track of nested forelse statements.
*
* @var int
*/
protected $forElseCounter = 0;
/**
* Compile the for-else statements into valid PHP.
*
* @param string $expression
* @return string
*
* @throws \Illuminate\Contracts\View\ViewCompilationException
*/
protected function compileForelse($expression)
{
$empty = '$__empty_'.++$this->forElseCounter;
preg_match('/\( *(.+) +as +(.+)\)$/is', $expression ?? '', $matches);
if (count($matches) === 0) {
throw new ViewCompilationException('Malformed @forelse statement.');
}
$iteratee = trim($matches[1]);
$iteration = trim($matches[2]);
$initLoop = "\$__currentLoopData = {$iteratee}; \$__env->addLoop(\$__currentLoopData);";
$iterateLoop = '$__env->incrementLoopIndices(); $loop = $__env->getLastLoop();';
return "<?php {$empty} = true; {$initLoop} foreach(\$__currentLoopData as {$iteration}): {$iterateLoop} {$empty} = false; ?>";
}
/**
* Compile the for-else-empty and empty statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileEmpty($expression)
{
if ($expression) {
return "<?php if(empty{$expression}): ?>";
}
$empty = '$__empty_'.$this->forElseCounter--;
return "<?php endforeach; \$__env->popLoop(); \$loop = \$__env->getLastLoop(); if ({$empty}): ?>";
}
/**
* Compile the end-for-else statements into valid PHP.
*
* @return string
*/
protected function compileEndforelse()
{
return '<?php endif; ?>';
}
/**
* Compile the end-empty statements into valid PHP.
*
* @return string
*/
protected function compileEndEmpty()
{
return '<?php endif; ?>';
}
/**
* Compile the for statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileFor($expression)
{
return "<?php for{$expression}: ?>";
}
/**
* Compile the for-each statements into valid PHP.
*
* @param string $expression
* @return string
*
* @throws \Illuminate\Contracts\View\ViewCompilationException
*/
protected function compileForeach($expression)
{
preg_match('/\( *(.+) +as +(.*)\)$/is', $expression ?? '', $matches);
if (count($matches) === 0) {
throw new ViewCompilationException('Malformed @foreach statement.');
}
$iteratee = trim($matches[1]);
$iteration = trim($matches[2]);
$initLoop = "\$__currentLoopData = {$iteratee}; \$__env->addLoop(\$__currentLoopData);";
$iterateLoop = '$__env->incrementLoopIndices(); $loop = $__env->getLastLoop();';
return "<?php {$initLoop} foreach(\$__currentLoopData as {$iteration}): {$iterateLoop} ?>";
}
/**
* Compile the break statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileBreak($expression)
{
if ($expression) {
preg_match('/\(\s*(-?\d+)\s*\)$/', $expression, $matches);
return $matches ? '<?php break '.max(1, $matches[1]).'; ?>' : "<?php if{$expression} break; ?>";
}
return '<?php break; ?>';
}
/**
* Compile the continue statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileContinue($expression)
{
if ($expression) {
preg_match('/\(\s*(-?\d+)\s*\)$/', $expression, $matches);
return $matches ? '<?php continue '.max(1, $matches[1]).'; ?>' : "<?php if{$expression} continue; ?>";
}
return '<?php continue; ?>';
}
/**
* Compile the end-for statements into valid PHP.
*
* @return string
*/
protected function compileEndfor()
{
return '<?php endfor; ?>';
}
/**
* Compile the end-for-each statements into valid PHP.
*
* @return string
*/
protected function compileEndforeach()
{
return '<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>';
}
/**
* Compile the while statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileWhile($expression)
{
return "<?php while{$expression}: ?>";
}
/**
* Compile the end-while statements into valid PHP.
*
* @return string
*/
protected function compileEndwhile()
{
return '<?php endwhile; ?>';
}
}