Skip to content

Commit

Permalink
Prevent Blade from parsing Blade codeinside the @php and @endphp blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
sileence committed Jul 14, 2017
1 parent f111352 commit bfde6de
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 39 deletions.
47 changes: 33 additions & 14 deletions src/Illuminate/View/Compilers/BladeCompiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,18 @@ class BladeCompiler extends Compiler implements CompilerInterface
protected $footer = [];

/**
* Placeholder to temporary mark the position of verbatim blocks.
* Placeholder to temporary mark the position of raw blocks.
*
* @var string
*/
protected $verbatimPlaceholder = '@__verbatim__@';
protected $rawPlaceholder = '@__raw-block__@';

/**
* Array to temporary store the verbatim blocks found in the template.
* Array to temporary store the raw blocks found in the template.
*
* @var array
*/
protected $verbatimBlocks = [];
protected $rawBlocks = [];

/**
* Compile the view at the given path.
Expand Down Expand Up @@ -157,23 +157,27 @@ public function setPath($path)
*/
public function compileString($value)
{
$result = '';

if (strpos($value, '@verbatim') !== false) {
$value = $this->storeVerbatimBlocks($value);
}

$this->footer = [];

if (strpos($value, '@php') !== false) {
$value = $this->storePhpBlocks($value);
}

$result = '';

// Here we will loop through all of the tokens returned by the Zend lexer and
// parse each one into the corresponding valid PHP. We will then have this
// template as the correctly rendered PHP that can be rendered natively.
foreach (token_get_all($value) as $token) {
$result .= is_array($token) ? $this->parseToken($token) : $token;
}

if (! empty($this->verbatimBlocks)) {
$result = $this->restoreVerbatimBlocks($result);
if (! empty($this->rawBlocks)) {
$result = $this->restoreRawContent($result);
}

// If there are any footer lines that need to get added to a template we will
Expand All @@ -195,9 +199,24 @@ public function compileString($value)
protected function storeVerbatimBlocks($value)
{
return preg_replace_callback('/(?<!@)@verbatim(.*?)@endverbatim/s', function ($matches) {
$this->verbatimBlocks[] = $matches[1];
$this->rawBlocks[] = $matches[1];

return $this->rawPlaceholder;
}, $value);
}

/**
* Store the PHP blocks and replace them with a temporary placeholder.
*
* @param string $value
* @return string
*/
protected function storePhpBlocks($value)
{
return preg_replace_callback('/(?<!@)@php(.*?)@endphp/s', function ($matches) {
$this->rawBlocks[] = "<?php{$matches[1]}?>";

return $this->verbatimPlaceholder;
return $this->rawPlaceholder;
}, $value);
}

Expand All @@ -207,13 +226,13 @@ protected function storeVerbatimBlocks($value)
* @param string $result
* @return string
*/
protected function restoreVerbatimBlocks($result)
protected function restoreRawContent($result)
{
$result = preg_replace_callback('/'.preg_quote($this->verbatimPlaceholder).'/', function () {
return array_shift($this->verbatimBlocks);
$result = preg_replace_callback('/'.preg_quote($this->rawPlaceholder).'/', function () {
return array_shift($this->rawBlocks);
}, $result);

$this->verbatimBlocks = [];
$this->rawBlocks = [];

return $result;
}
Expand Down
14 changes: 4 additions & 10 deletions src/Illuminate/View/Compilers/Concerns/CompilesRawPhp.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,11 @@ trait CompilesRawPhp
*/
protected function compilePhp($expression)
{
return $expression ? "<?php {$expression}; ?>" : '<?php ';
}
if ($expression) {
return "<?php {$expression}; ?>";
}

/**
* Compile end-php statements into valid PHP.
*
* @return string
*/
protected function compileEndphp()
{
return ' ?>';
return '@php';
}

/**
Expand Down
1 change: 1 addition & 0 deletions tests/Filesystem/tmp/file.txt

Large diffs are not rendered by default.

13 changes: 0 additions & 13 deletions tests/View/Blade/BladeEndphpStatementsTest.php

This file was deleted.

30 changes: 28 additions & 2 deletions tests/View/Blade/BladePhpStatementsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,36 @@ public function testPhpStatementsWithExpressionAreCompiled()
$this->assertEquals($expected, $this->compiler->compileString($string));
}

public function testPhpStatementsWithoutExpressionAreCompiled()
public function testPhpStatementsWithoutExpressionAreIgnored()
{
$string = '@php';
$expected = '<?php ';
$expected = '@php';
$this->assertEquals($expected, $this->compiler->compileString($string));

$string = '{{ "Ignore: @php" }}';
$expected = '<?php echo e("Ignore: @php"); ?>';
$this->assertEquals($expected, $this->compiler->compileString($string));
}

public function testPhpStatementsDontParseBladeCode()
{
$string = '@php echo "{{ This is a blade tag }}" @endphp';
$expected = '<?php echo "{{ This is a blade tag }}" ?>';
$this->assertEquals($expected, $this->compiler->compileString($string));
}

public function testVerbatimAndPhpStatementsDontGetMixedUp()
{
$string = "@verbatim {{ Hello, I'm not blade! }}"
."\n@php echo 'And I'm not PHP!' @endphp"
."\n@endverbatim {{ 'I am Blade' }}"
."\n@php echo 'I am PHP {{ not Blade }}' @endphp";

$expected = " {{ Hello, I'm not blade! }}"
."\n@php echo 'And I'm not PHP!' @endphp"
."\n <?php echo e('I am Blade'); ?>"
."\n\n<?php echo 'I am PHP {{ not Blade }}' ?>";

$this->assertEquals($expected, $this->compiler->compileString($string));
}
}

0 comments on commit bfde6de

Please sign in to comment.