Skip to content

Commit 29d524e

Browse files
Merge pull request #135 from VincentLanglet/mbstring
✨ Add mb string sniff
2 parents 5596f47 + 88be321 commit 29d524e

15 files changed

+134
-38
lines changed

SymfonyCustom/Sniffs/Namespaces/AlphabeticallySortedUseSniff.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ private function getUseStatements(File $phpcsFile, int $scopePtr): array
107107

108108
$type = 'class';
109109
if (T_STRING === $tokens[$startOfName]['code']) {
110-
$lowerContent = strtolower($tokens[$startOfName]['content']);
110+
$lowerContent = mb_strtolower($tokens[$startOfName]['content']);
111111
if ('function' === $lowerContent || 'const' === $lowerContent) {
112112
$type = $lowerContent;
113113

SymfonyCustom/Sniffs/Namespaces/UnusedUseSniff.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public function process(File $phpcsFile, $stackPtr): void
162162
$from = $phpcsFile->findNext(Tokens::$emptyTokens, $prev + 1, null, true);
163163
if (
164164
T_STRING === $tokens[$from]['code']
165-
&& in_array(strtolower($tokens[$from]['content']), ['const', 'function'], true)
165+
&& in_array(mb_strtolower($tokens[$from]['content']), ['const', 'function'], true)
166166
) {
167167
$from = $phpcsFile->findNext(Tokens::$emptyTokens, $from + 1, null, true);
168168
}
@@ -248,12 +248,12 @@ private function isClassUsed(File $phpcsFile, int $usePtr, int $classPtr): bool
248248
$next = $phpcsFile->findNext(Tokens::$emptyTokens, $usePtr + 1, null, true);
249249
if (
250250
T_STRING === $tokens[$next]['code']
251-
&& in_array(strtolower($tokens[$next]['content']), ['const', 'function'], true)
251+
&& in_array(mb_strtolower($tokens[$next]['content']), ['const', 'function'], true)
252252
) {
253-
$type = strtolower($tokens[$next]['content']);
253+
$type = mb_strtolower($tokens[$next]['content']);
254254
}
255255

256-
$searchName = 'const' === $type ? $className : strtolower($className);
256+
$searchName = 'const' === $type ? $className : mb_strtolower($className);
257257

258258
$prev = $phpcsFile->findPrevious(
259259
Tokens::$emptyTokens + [
@@ -292,7 +292,7 @@ private function isClassUsed(File $phpcsFile, int $usePtr, int $classPtr): bool
292292
);
293293
}
294294

295-
$useNamespace = substr($useNamespace, 0, strrpos($useNamespace, '\\') ?: 0);
295+
$useNamespace = mb_substr($useNamespace, 0, mb_strrpos($useNamespace, '\\') ?: 0);
296296

297297
if (false !== $namespacePtr) {
298298
$namespace = $this->getNamespace($phpcsFile, $namespacePtr + 1, [T_CURLY_OPEN, T_SEMICOLON]);
@@ -315,7 +315,7 @@ private function isClassUsed(File $phpcsFile, int $usePtr, int $classPtr): bool
315315

316316
if (
317317
($isStringToken
318-
&& (('const' !== $type && strtolower($tokens[$classUsed]['content']) === $searchName)
318+
&& (('const' !== $type && mb_strtolower($tokens[$classUsed]['content']) === $searchName)
319319
|| ('const' === $type && $tokens[$classUsed]['content'] === $searchName)))
320320
|| ('class' === $type
321321
&& ((T_DOC_COMMENT_STRING === $tokens[$classUsed]['code']

SymfonyCustom/Sniffs/NamingConventions/ValidClassNameSniff.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public function process(File $phpcsFile, $stackPtr): void
5757
if (T_EXTENDS === $tokens[$stackPtr]['code']) {
5858
$extend = $phpcsFile->findNext(T_STRING, $stackPtr);
5959

60-
if ($extend && substr($tokens[$extend]['content'], -9) === 'Exception') {
60+
if ($extend && mb_substr($tokens[$extend]['content'], -9) === 'Exception') {
6161
$class = $phpcsFile->findPrevious(T_CLASS, $stackPtr);
6262
$name = $phpcsFile->findNext(T_STRING, $class);
6363

@@ -93,7 +93,7 @@ private function checkPrefix(File $phpcsFile, int $stackPtr, $name, string $pref
9393
{
9494
$tokens = $phpcsFile->getTokens();
9595

96-
if (false !== $name && substr($tokens[$name]['content'], 0, strlen($prefix)) !== $prefix) {
96+
if (false !== $name && mb_substr($tokens[$name]['content'], 0, mb_strlen($prefix)) !== $prefix) {
9797
$phpcsFile->addError(
9898
"$prefix name is not prefixed with '$prefix'",
9999
$stackPtr,
@@ -114,7 +114,7 @@ private function checkSuffix(File $phpcsFile, int $stackPtr, $name, string $suff
114114
{
115115
$tokens = $phpcsFile->getTokens();
116116

117-
if (false !== $name && substr($tokens[$name]['content'], -strlen($suffix)) !== $suffix) {
117+
if (false !== $name && mb_substr($tokens[$name]['content'], -mb_strlen($suffix)) !== $suffix) {
118118
$phpcsFile->addError(
119119
"$suffix name is not suffixed with '$suffix'",
120120
$stackPtr,

SymfonyCustom/Sniffs/NamingConventions/ValidFileNameSniff.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public function process(File $phpcsFile, $stackPtr): void
3737
$filenamePhp = basename($filename, '.php');
3838
$filenameInc = basename($filename, '.inc');
3939

40-
if (strlen($filenameInc) < strlen($filenamePhp)) {
40+
if (mb_strlen($filenameInc) < mb_strlen($filenamePhp)) {
4141
$filename = $filenameInc;
4242
} else {
4343
$filename = $filenamePhp;

SymfonyCustom/Sniffs/NamingConventions/ValidTypeHintSniff.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ private function getValidTypes(string $content): string
113113
preg_match('{^'.SniffHelper::REGEX_TYPES.'$}ix', $content, $matches);
114114

115115
if (isset($matches['array']) && '' !== $matches['array']) {
116-
$validType = $this->getValidTypes(substr($matches['array'], 0, -2)).'[]';
116+
$validType = $this->getValidTypes(mb_substr($matches['array'], 0, -2)).'[]';
117117
} elseif (isset($matches['multiple']) && '' !== $matches['multiple']) {
118118
$validType = '('.$this->getValidTypes($matches['mutipleContent']).')';
119119
} elseif (isset($matches['generic']) && '' !== $matches['generic']) {
@@ -126,8 +126,8 @@ private function getValidTypes(string $content): string
126126

127127
$types[] = $validType;
128128

129-
$separators[] = substr($content, strlen($matches['type']), 1);
130-
$content = substr($content, strlen($matches['type']) + 1);
129+
$separators[] = mb_substr($content, mb_strlen($matches['type']), 1);
130+
$content = mb_substr($content, mb_strlen($matches['type']) + 1);
131131
}
132132

133133
// Remove last separator since it's an empty string
@@ -185,7 +185,7 @@ private function getValidGenericType(string $genericName, string $genericContent
185185
preg_match('{^'.SniffHelper::REGEX_TYPES.',?}ix', $genericContent, $matches);
186186

187187
$validType .= $this->getValidTypes($matches['types']).', ';
188-
$genericContent = substr($genericContent, strlen($matches['types']) + 1);
188+
$genericContent = mb_substr($genericContent, mb_strlen($matches['types']) + 1);
189189
}
190190

191191
return preg_replace('/,\s$/', '>', $validType);
@@ -213,7 +213,7 @@ private function getValidObjectType(string $objectContent): string
213213
preg_match('{^'.SniffHelper::REGEX_TYPES.',?}ix', $objectContent, $matches);
214214

215215
$validType .= $this->getValidTypes($matches['types']).', ';
216-
$objectContent = substr($objectContent, strlen($matches['types']) + 1);
216+
$objectContent = mb_substr($objectContent, mb_strlen($matches['types']) + 1);
217217
}
218218

219219
return preg_replace('/,\s$/', '}', $validType);
@@ -226,7 +226,7 @@ private function getValidObjectType(string $objectContent): string
226226
*/
227227
private function getValidType(string $typeName): string
228228
{
229-
$lowerType = strtolower($typeName);
229+
$lowerType = mb_strtolower($typeName);
230230
if (isset(self::TYPES[$lowerType])) {
231231
return self::TYPES[$lowerType] ? $lowerType : $typeName;
232232
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SymfonyCustom\Sniffs\PHP;
6+
7+
use PHP_CodeSniffer\Standards\Generic\Sniffs\PHP\ForbiddenFunctionsSniff;
8+
9+
/**
10+
* Class EncourageMultiBytesSniff
11+
*/
12+
class EncourageMultiBytesSniff extends ForbiddenFunctionsSniff
13+
{
14+
/**
15+
* @var array
16+
*/
17+
public $forbiddenFunctions = [
18+
'str_split' => 'mb_str_split',
19+
'stripos' => 'mb_stripos',
20+
'stristr' => 'mb_stristr',
21+
'strlen' => 'mb_strlen',
22+
'strpos' => 'mb_strpos',
23+
'strrchr' => 'mb_strrchr',
24+
'strripos' => 'mb_strripos',
25+
'strrpos' => 'mb_strrpos',
26+
'strstr' => 'mb_strstr',
27+
'strtolower' => 'mb_strtolower',
28+
'strtoupper' => 'mb_strtoupper',
29+
'substr_count' => 'mb_substr_count',
30+
'substr' => 'mb_substr',
31+
];
32+
33+
/**
34+
* @var bool
35+
*/
36+
public $error = false;
37+
}

SymfonyCustom/Sniffs/WhiteSpace/OpenBracketSpacingSniff.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function process(File $phpcsFile, $stackPtr): void
3434
if (
3535
isset($tokens[$stackPtr + 1])
3636
&& T_WHITESPACE === $tokens[$stackPtr + 1]['code']
37-
&& false === strpos($tokens[$stackPtr + 1]['content'], $phpcsFile->eolChar)
37+
&& false === mb_strpos($tokens[$stackPtr + 1]['content'], $phpcsFile->eolChar)
3838
) {
3939
$error = 'There should be no space after an opening "%s"';
4040
$fix = $phpcsFile->addFixableError(
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
str_split('e');
4+
stripos('eee', 'e');
5+
stristr('eee', 'e');
6+
strlen('eee');
7+
strpos('eee', 'e');
8+
strrchr('eee', 'e');
9+
strripos('eee', 'e');
10+
strrpos('eee', 'e');
11+
strstr('eee', 'e');
12+
strtolower('eee');
13+
strtoupper('eee');
14+
substr_count('eee', 'e');
15+
substr('eee', 1);
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SymfonyCustom\Tests\PHP;
6+
7+
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
8+
9+
/**
10+
* Unit test class for the EncourageMultiBytes sniff.
11+
*/
12+
class EncourageMultiBytesUnitTest extends AbstractSniffUnitTest
13+
{
14+
/**
15+
* @return array
16+
*/
17+
protected function getErrorList(): array
18+
{
19+
return [];
20+
}
21+
22+
/**
23+
* @return array
24+
*/
25+
protected function getWarningList(): array
26+
{
27+
return [
28+
3 => 1,
29+
4 => 1,
30+
5 => 1,
31+
6 => 1,
32+
7 => 1,
33+
8 => 1,
34+
9 => 1,
35+
10 => 1,
36+
11 => 1,
37+
12 => 1,
38+
13 => 1,
39+
14 => 1,
40+
15 => 1,
41+
];
42+
}
43+
}

TwigCS/src/Report/SniffViolation.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public function getLevelAsString(): string
9797
*/
9898
public static function getLevelAsInt(string $level): int
9999
{
100-
switch (strtoupper($level)) {
100+
switch (mb_strtoupper($level)) {
101101
case self::LEVEL_NOTICE:
102102
return Report::MESSAGE_TYPE_NOTICE;
103103
case self::LEVEL_WARNING:

0 commit comments

Comments
 (0)