Skip to content

Commit 1abb4ea

Browse files
committed
Fix
1 parent a89beb0 commit 1abb4ea

3 files changed

Lines changed: 42 additions & 9 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Rector\Tests\Php85\Rector\ShellExec\ShellExecFunctionCallOverBackticksRector\Fixture;
4+
5+
class SkipEmptyBackticks
6+
{
7+
public function run()
8+
{
9+
``;
10+
}
11+
}

rules-tests/Php85/Rector/ShellExec/ShellExecFunctionCallOverBackticksRector/Fixture/with_variable.php.inc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ class WithVariable
2929
$dir = __DIR__;
3030
$var = 'example';
3131

32-
$output = shell_exec("ls $dir");
33-
$output2 = shell_exec("echo \"value: $var\"");
32+
$output = shell_exec('ls ' . $dir);
33+
$output2 = shell_exec('echo "value: ' . $var . '"');
3434
echo "<pre>$output</pre>";
3535
echo "<pre>$output2</pre>";
3636
}

rules/Php85/Rector/ShellExec/ShellExecFunctionCallOverBackticksRector.php

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use PhpParser\Node;
88
use PhpParser\Node\Arg;
9+
use PhpParser\Node\Expr\BinaryOp\Concat;
910
use PhpParser\Node\Expr\ShellExec;
1011
use PhpParser\Node\InterpolatedStringPart;
1112
use PhpParser\Node\Scalar\String_;
@@ -49,17 +50,38 @@ public function getNodeTypes(): array
4950
/**
5051
* @param ShellExec $node
5152
*/
52-
public function refactor(Node $node): Node
53+
public function refactor(Node $node): ?Node
5354
{
54-
$args = array_map(function (Node $node): Node {
55-
if ($node instanceof InterpolatedStringPart) {
56-
return new Arg(new String_($node->value));
55+
if ($node->parts === []) {
56+
return null;
57+
}
58+
59+
$exprs = [];
60+
foreach ($node->parts as $part) {
61+
if ($part instanceof InterpolatedStringPart) {
62+
// keep as single-quoted string literal and escape single quotes inside
63+
$escaped = str_replace("'", "\\'", $part->value);
64+
$exprs[] = new String_($escaped);
65+
continue;
5766
}
5867

59-
return new Arg($node);
60-
}, $node->parts);
68+
// other parts are Expr (variables, function calls, etc.)
69+
// keep them as-is so they are concatenated
70+
$exprs[] = $part;
71+
}
72+
73+
// reduce to single concatenated expression
74+
if (count($exprs) === 1) {
75+
$argExpr = $exprs[0];
76+
} else {
77+
$argExpr = array_shift($exprs);
78+
foreach ($exprs as $expr) {
79+
$argExpr = new Concat($argExpr, $expr);
80+
}
81+
}
6182

62-
return $this->nodeFactory->createFuncCall('shell_exec', $args);
83+
// create single Arg and call shell_exec
84+
return $this->nodeFactory->createFuncCall('shell_exec', [new Arg($argExpr)]);
6385
}
6486

6587
public function provideMinPhpVersion(): int

0 commit comments

Comments
 (0)