diff --git a/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_defined_int_or_string.php.inc b/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_defined_int_or_string.php.inc new file mode 100644 index 00000000000..0c8fdabc771 --- /dev/null +++ b/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_defined_int_or_string.php.inc @@ -0,0 +1,39 @@ + + */ + private array $todos = [ + 0 => [ + 'unique_key' => 1, + 'label' => 'test 1', + ], + 1 => [ + 'unique_key' => 'fallback_todo', + 'label' => 'fallback todo 1', + ], + ]; + + /** + * @var array + */ + public array $selectedTodos = []; + + public function run(int $index): string + { + if (!array_key_exists($index, $this->todos)) { + return 'Todo not found'; + } + + if (!array_key_exists($this->todos[$index]['unique_key'], $this->selectedTodos)) { + $this->selectedTodos[$this->todos[$index]['unique_key']] = $this->todos[$index]['label']; + return 'Todo selected !'; + } + + return 'Todo already selected !'; + } +} diff --git a/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php b/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php index 9618aa6afed..f2f074fd338 100644 --- a/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php +++ b/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php @@ -4,6 +4,8 @@ namespace Rector\Php85\Rector\FuncCall; +use PHPStan\Type\UnionType; +use PHPStan\Type\TypeCombinator; use PhpParser\Node; use PhpParser\Node\Expr\FuncCall; use PHPStan\Analyser\Scope; @@ -88,12 +90,21 @@ public function refactor(Node $node): ?Node return null; } - $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($functionReflection, $node, $scope); + $argPosition = $this->argsAnalyzer->resolveArgPosition($args, 'key', 0); + $originalType = $this->getType($args[$argPosition]->value); + + if ($originalType instanceof UnionType) { + $withoutNullParameterType = TypeCombinator::removeNull($originalType); + if ($withoutNullParameterType->equals($originalType)) { + return null; + } + } + $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($functionReflection, $node, $scope); $result = $this->nullToStrictStringIntConverter->convertIfNull( $node, $args, - $this->argsAnalyzer->resolveArgPosition($args, 'key', 0), + $argPosition, $isTrait, $scope, $parametersAcceptor