From e33f10513adf51daf01ce5ed3ca4859f1d9a08e9 Mon Sep 17 00:00:00 2001 From: Johan Vlaar Date: Thu, 15 May 2025 09:59:58 +0200 Subject: [PATCH] [StrContainsRector] also replace multibyte functions fro strpos and strstr --- .../Fixture/multibyte_offset_strpos.php.inc | 25 +++++++++++++++++ .../Fixture/multibyte_strpos_function.php.inc | 27 +++++++++++++++++++ .../Fixture/multibyte_strstr_function.php.inc | 27 +++++++++++++++++++ ...et_variable_equal_multibyte_strpos.php.inc | 27 +++++++++++++++++++ ...ultibyte_strpos_with_encoding_null.php.inc | 27 +++++++++++++++++++ ...ultibyte_strstr_with_encoding_null.php.inc | 27 +++++++++++++++++++ ...kip_multibyte_strpos_with_encoding.php.inc | 13 +++++++++ ...ibyte_strstr_with_dynamic_encoding.php.inc | 13 +++++++++ ...kip_multibyte_strstr_with_encoding.php.inc | 13 +++++++++ .../Rector/NotIdentical/StrContainsRector.php | 16 ++++++++--- 10 files changed, 211 insertions(+), 4 deletions(-) create mode 100644 rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/multibyte_offset_strpos.php.inc create mode 100644 rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/multibyte_strpos_function.php.inc create mode 100644 rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/multibyte_strstr_function.php.inc create mode 100644 rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/offset_variable_equal_multibyte_strpos.php.inc create mode 100644 rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/replace_multibyte_strpos_with_encoding_null.php.inc create mode 100644 rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/replace_multibyte_strstr_with_encoding_null.php.inc create mode 100644 rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/skip_multibyte_strpos_with_encoding.php.inc create mode 100644 rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/skip_multibyte_strstr_with_dynamic_encoding.php.inc create mode 100644 rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/skip_multibyte_strstr_with_encoding.php.inc diff --git a/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/multibyte_offset_strpos.php.inc b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/multibyte_offset_strpos.php.inc new file mode 100644 index 00000000000..512f49c6be3 --- /dev/null +++ b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/multibyte_offset_strpos.php.inc @@ -0,0 +1,25 @@ + +----- + diff --git a/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/multibyte_strpos_function.php.inc b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/multibyte_strpos_function.php.inc new file mode 100644 index 00000000000..6be2ada369e --- /dev/null +++ b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/multibyte_strpos_function.php.inc @@ -0,0 +1,27 @@ + +----- + diff --git a/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/multibyte_strstr_function.php.inc b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/multibyte_strstr_function.php.inc new file mode 100644 index 00000000000..4fbe0e69e62 --- /dev/null +++ b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/multibyte_strstr_function.php.inc @@ -0,0 +1,27 @@ + +----- + diff --git a/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/offset_variable_equal_multibyte_strpos.php.inc b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/offset_variable_equal_multibyte_strpos.php.inc new file mode 100644 index 00000000000..deefc9315c9 --- /dev/null +++ b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/offset_variable_equal_multibyte_strpos.php.inc @@ -0,0 +1,27 @@ + +----- + diff --git a/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/replace_multibyte_strpos_with_encoding_null.php.inc b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/replace_multibyte_strpos_with_encoding_null.php.inc new file mode 100644 index 00000000000..f1093ee5308 --- /dev/null +++ b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/replace_multibyte_strpos_with_encoding_null.php.inc @@ -0,0 +1,27 @@ + +----- + diff --git a/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/replace_multibyte_strstr_with_encoding_null.php.inc b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/replace_multibyte_strstr_with_encoding_null.php.inc new file mode 100644 index 00000000000..0f689947e13 --- /dev/null +++ b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/replace_multibyte_strstr_with_encoding_null.php.inc @@ -0,0 +1,27 @@ + +----- + diff --git a/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/skip_multibyte_strpos_with_encoding.php.inc b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/skip_multibyte_strpos_with_encoding.php.inc new file mode 100644 index 00000000000..bc687adc4e7 --- /dev/null +++ b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/skip_multibyte_strpos_with_encoding.php.inc @@ -0,0 +1,13 @@ + diff --git a/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/skip_multibyte_strstr_with_dynamic_encoding.php.inc b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/skip_multibyte_strstr_with_dynamic_encoding.php.inc new file mode 100644 index 00000000000..5fe97330597 --- /dev/null +++ b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/skip_multibyte_strstr_with_dynamic_encoding.php.inc @@ -0,0 +1,13 @@ + diff --git a/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/skip_multibyte_strstr_with_encoding.php.inc b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/skip_multibyte_strstr_with_encoding.php.inc new file mode 100644 index 00000000000..0060403bcbf --- /dev/null +++ b/rules-tests/Php80/Rector/NotIdentical/StrContainsRector/Fixture/skip_multibyte_strstr_with_encoding.php.inc @@ -0,0 +1,13 @@ + diff --git a/rules/Php80/Rector/NotIdentical/StrContainsRector.php b/rules/Php80/Rector/NotIdentical/StrContainsRector.php index 035e2ec6d8e..7daa7d7c11d 100644 --- a/rules/Php80/Rector/NotIdentical/StrContainsRector.php +++ b/rules/Php80/Rector/NotIdentical/StrContainsRector.php @@ -32,7 +32,7 @@ final class StrContainsRector extends AbstractRector implements MinPhpVersionInt /** * @var string[] */ - private const OLD_STR_NAMES = ['strpos', 'strstr']; + private const OLD_STR_NAMES = ['mb_strpos', 'mb_strstr', 'strpos', 'strstr']; public function __construct( private readonly ValueResolver $valueResolver @@ -47,7 +47,7 @@ public function provideMinPhpVersion(): int public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( - 'Replace strpos() !== false and strstr() with str_contains()', + 'Replace strpos|mb_strpos() !== false and strstr()|mb_strstr() with str_contains()', [ new CodeSample( <<<'CODE_SAMPLE' @@ -97,12 +97,20 @@ public function refactor(Node $node): ?Node return null; } + if ($this->isNames($funcCall->name, ['mb_strpos', 'mb_strstr']) && isset($funcCall->getArgs()[3])) { + if (! $this->valueResolver->isNull($funcCall->getArgs()[3]->value)) { + return null; + } + + unset($funcCall->args[3]); + } + if (isset($funcCall->getArgs()[2])) { $secondArg = $funcCall->getArgs()[2]; - if ($this->isName($funcCall->name, 'strpos') && ! $this->isIntegerZero($secondArg->value)) { + if ($this->isNames($funcCall->name, ['strpos', 'mb_strpos']) && ! $this->isIntegerZero($secondArg->value)) { $funcCall->args[0] = new Arg($this->nodeFactory->createFuncCall( - 'substr', + $this->isName($funcCall->name, 'strpos') ? 'substr' : 'mb_substr', [$funcCall->args[0], $secondArg] )); }