diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/DowngradeStrContainsWithMultibyteNeedleRectorTest.php b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/DowngradeStrContainsWithMultibyteNeedleRectorTest.php new file mode 100644 index 00000000..de0c2219 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/DowngradeStrContainsWithMultibyteNeedleRectorTest.php @@ -0,0 +1,28 @@ +doTestFile($filePath); + } + + public static function provideData(): Iterator + { + return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/fixture_equal.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/fixture_equal.php.inc new file mode 100644 index 00000000..c120cd9a --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/fixture_equal.php.inc @@ -0,0 +1,27 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/identical_mb_strpos.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/identical_mb_strpos.php.inc new file mode 100644 index 00000000..f3b8cab8 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/identical_mb_strpos.php.inc @@ -0,0 +1,27 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/not_equal_mb_strstr.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/not_equal_mb_strstr.php.inc new file mode 100644 index 00000000..db9bece0 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/not_equal_mb_strstr.php.inc @@ -0,0 +1,27 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/not_str_contains.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/not_str_contains.php.inc new file mode 100644 index 00000000..896d32f5 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/not_str_contains.php.inc @@ -0,0 +1,27 @@ + +----- + diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/not_strstr.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/not_strstr.php.inc new file mode 100644 index 00000000..db9bece0 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/not_strstr.php.inc @@ -0,0 +1,27 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_equal_strpos.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_equal_strpos.php.inc new file mode 100644 index 00000000..27ae5638 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_equal_strpos.php.inc @@ -0,0 +1,25 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_expression_equal_strpos.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_expression_equal_strpos.php.inc new file mode 100644 index 00000000..6b07e619 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_expression_equal_strpos.php.inc @@ -0,0 +1,27 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_expression_mb_strpos.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_expression_mb_strpos.php.inc new file mode 100644 index 00000000..6b07e619 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_expression_mb_strpos.php.inc @@ -0,0 +1,27 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_negative_equal_strpos.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_negative_equal_strpos.php.inc new file mode 100644 index 00000000..a80c166c --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_negative_equal_strpos.php.inc @@ -0,0 +1,25 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_negative_strpos.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_negative_strpos.php.inc new file mode 100644 index 00000000..a80c166c --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_negative_strpos.php.inc @@ -0,0 +1,25 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_strpos.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_strpos.php.inc new file mode 100644 index 00000000..27ae5638 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_strpos.php.inc @@ -0,0 +1,25 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_variable_equal_strpos.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_variable_equal_strpos.php.inc new file mode 100644 index 00000000..03d1a5b3 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_variable_equal_strpos.php.inc @@ -0,0 +1,27 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_variable_strpos.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_variable_strpos.php.inc new file mode 100644 index 00000000..0e4ff70a --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_variable_strpos.php.inc @@ -0,0 +1,27 @@ + +----- + diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_variable_zero_equal_strpos.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_variable_zero_equal_strpos.php.inc new file mode 100644 index 00000000..38c8d610 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_variable_zero_equal_strpos.php.inc @@ -0,0 +1,27 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_variable_zero_strpos.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_variable_zero_strpos.php.inc new file mode 100644 index 00000000..38c8d610 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/offset_variable_zero_strpos.php.inc @@ -0,0 +1,27 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/skip_fixture_equal.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/skip_fixture_equal.php.inc new file mode 100644 index 00000000..27b23e07 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/skip_fixture_equal.php.inc @@ -0,0 +1,13 @@ + \ No newline at end of file diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/skip_str_contains.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/skip_str_contains.php.inc new file mode 100644 index 00000000..492c4926 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/skip_str_contains.php.inc @@ -0,0 +1,13 @@ + diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/skip_str_contains.php_with_mixed.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/skip_str_contains.php_with_mixed.php.inc new file mode 100644 index 00000000..d5bd6f0d --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/skip_str_contains.php_with_mixed.php.inc @@ -0,0 +1,14 @@ + diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/strstr.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/strstr.php.inc new file mode 100644 index 00000000..dab93a74 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/strstr.php.inc @@ -0,0 +1,27 @@ + +----- + diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/the_other_way.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/the_other_way.php.inc new file mode 100644 index 00000000..1fb94d54 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/the_other_way.php.inc @@ -0,0 +1,27 @@ + +----- + \ No newline at end of file diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/the_other_way_equal.php.inc b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/the_other_way_equal.php.inc new file mode 100644 index 00000000..969483ec --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/Fixture/the_other_way_equal.php.inc @@ -0,0 +1,27 @@ + +----- + diff --git a/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/config/configured_rule.php b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/config/configured_rule.php new file mode 100644 index 00000000..b46f20b2 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(DowngradeStrContainsWithMultibyteNeedleRector::class); +}; diff --git a/rules/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector.php b/rules/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector.php new file mode 100644 index 00000000..00d16022 --- /dev/null +++ b/rules/DowngradePhp80/Rector/FuncCall/DowngradeStrContainsWithMultibyteNeedleRector.php @@ -0,0 +1,147 @@ +> + */ + public function getNodeTypes(): array + { + return [FuncCall::class, BooleanNot::class]; + } + + /** + * @param FuncCall|BooleanNot $node + * @return Identical|NotIdentical|null The refactored node. + */ + public function refactor(Node $node): Identical | NotIdentical | null + { + $funcCall = $this->matchStrContainsOrNotStrContains($node); + + if (! $funcCall instanceof FuncCall) { + return null; + } + + if ($funcCall->isFirstClassCallable()) { + return null; + } + + $args = $funcCall->getArgs(); + if (count($args) < 2) { + return null; + } + + $haystack = $args[0]->value; + $needle = $args[1]->value; + $offset = null; + + if ($haystack instanceof FuncCall) { + + if (! $this->isName($haystack->name, 'mb_substr')) { + return null; + } + + if ($haystack->isFirstClassCallable()) { + return null; + } + + $substrArg = $haystack->getArgs(); + if (isset($substrArg[0]) && ! $substrArg[0] instanceof Arg) { + return null; + } + + if (isset($substrArg[1]) && ! $substrArg[1] instanceof Arg) { + return null; + } + + $haystack = $substrArg[0]; + $offset = $substrArg[1]; + } + + if (!$needle instanceof String_) { + return null; + } + + if(strlen($needle->value) === mb_strlen($needle->value)){ + return null; + } + + if ($offset instanceof Arg) { + $funcCall = $this->nodeFactory->createFuncCall('mb_strpos', [$haystack, $needle, $offset]); + } + + if (! $offset instanceof Arg) { + $funcCall = $this->nodeFactory->createFuncCall('mb_strpos', [$haystack, $needle]); + } + + if ($node instanceof BooleanNot) { + return new Identical($funcCall, $this->nodeFactory->createFalse()); + } + + return new NotIdentical($funcCall, $this->nodeFactory->createFalse()); + } + + private function matchStrContainsOrNotStrContains(FuncCall | BooleanNot $expr): ?FuncCall + { + $expr = ($expr instanceof BooleanNot) ? $expr->expr : $expr; + if (! $expr instanceof FuncCall) { + return null; + } + + if (! $this->isName($expr, 'str_contains')) { + return null; + } + + return $expr; + } +}