diff --git a/src/Illuminate/View/Compilers/BladeCompiler.php b/src/Illuminate/View/Compilers/BladeCompiler.php index b20e7c4924b8..b61c19d4ffb0 100644 --- a/src/Illuminate/View/Compilers/BladeCompiler.php +++ b/src/Illuminate/View/Compilers/BladeCompiler.php @@ -507,6 +507,7 @@ protected function compileStatements($template) { preg_match_all('/\B@(@?\w+(?:::\w+)?)([ \t]*)(\( ( [\S\s]*? ) \))?/x', $template, $matches); + $offset = 0; for ($i = 0; isset($matches[0][$i]); $i++) { $match = [ $matches[0][$i], @@ -538,12 +539,35 @@ protected function compileStatements($template) $match[4] = $match[4].$rest; } - $template = Str::replaceFirst($match[0], $this->compileStatement($match), $template); + dump($this->compileStatement($match)); + [$template, $offset] = $this->replaceFirst( + $match[0], + $this->compileStatement($match), + $template, + $offset + ); } return $template; } + public function replaceFirst($search, $replace, $subject, $offset) + { + $search = (string) $search; + + if ($search === '') { + return $subject; + } + + $position = strpos($subject, $search, $offset); + + if ($position !== false) { + return [substr_replace($subject, $replace, $position, strlen($search)), $position + strlen($search) - 1]; + } + + return [$subject, 0]; + } + /** * Determine if the given expression has the same number of opening and closing parentheses. * diff --git a/tests/View/Blade/BladeEscapedTest.php b/tests/View/Blade/BladeEscapedTest.php index 36701398921c..5b5389652c4d 100644 --- a/tests/View/Blade/BladeEscapedTest.php +++ b/tests/View/Blade/BladeEscapedTest.php @@ -16,4 +16,19 @@ public function testEscapedWithAtDirectivesAreCompiled() $i as $x )')); } + + public function testNestedEscapes() + { + $template = ' +@foreach($cols as $col) + @@foreach($issues as $issue_45915) + @@endforeach +@endforeach'; + $compiled = ' +addLoop($__currentLoopData); foreach($__currentLoopData as $col): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?> + @foreach($issues as $issue_45915) + @endforeach +popLoop(); $loop = $__env->getLastLoop(); ?>'; + $this->assertSame($compiled, $this->compiler->compileString($template)); + } }