Skip to content

Commit e2773e4

Browse files
Fix #20032: Added mask method for string masking with multibyte support
1 parent 778d708 commit e2773e4

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

framework/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ Yii Framework 2 Change Log
1111
- Bug #20002: Fixed superfluous query on HEAD request in serializer (xicond)
1212
- Enh #12743: Added new methods `BaseActiveRecord::loadRelations()` and `BaseActiveRecord::loadRelationsFor()` to eager load related models for existing primary model instances (PowerGamer1)
1313
- Enh #20030: Improve performance of handling `ErrorHandler::$memoryReserveSize` (antonshevelev, rob006)
14+
- Enh #20032: Added `mask` method for string masking with multibyte support (salehhashemi1992)
15+
1416

1517
2.0.49.2 October 12, 2023
1618
-------------------------

framework/helpers/BaseStringHelper.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,4 +497,34 @@ public static function mb_ucwords($string, $encoding = 'UTF-8')
497497

498498
return implode('', $parts);
499499
}
500+
501+
/**
502+
* Masks a portion of a string with a repeated character.
503+
* This method is multibyte-safe.
504+
*
505+
* @param string $string The input string.
506+
* @param int $start The starting position from where to begin masking.
507+
* This can be a positive or negative integer.
508+
* Positive values count from the beginning,
509+
* negative values count from the end of the string.
510+
* @param int $length The length of the section to be masked.
511+
* The masking will start from the $start position
512+
* and continue for $length characters.
513+
* @param string $mask The character to use for masking. The default is '*'.
514+
* @return string The masked string.
515+
*/
516+
public static function mask($string, $start, $length, $mask = '*') {
517+
$strLength = mb_strlen($string, 'UTF-8');
518+
519+
// Return original string if start position is out of bounds
520+
if ($start >= $strLength || $start < -$strLength) {
521+
return $string;
522+
}
523+
524+
$masked = mb_substr($string, 0, $start, 'UTF-8');
525+
$masked .= str_repeat($mask, abs($length));
526+
$masked .= mb_substr($string, $start + abs($length), null, 'UTF-8');
527+
528+
return $masked;
529+
}
500530
}

tests/framework/helpers/StringHelperTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,4 +474,36 @@ public function dataProviderDirname()
474474
['', ''],
475475
];
476476
}
477+
478+
public function testMask()
479+
{
480+
// Standard masking
481+
$this->assertSame('12******90', StringHelper::mask('1234567890', 2, 6));
482+
$this->assertSame('a********j', StringHelper::mask('abcdefghij', 1, 8));
483+
$this->assertSame('*************', StringHelper::mask('Hello, World!', 0, 13));
484+
$this->assertSame('************!', StringHelper::mask('Hello, World!', 0, 12));
485+
$this->assertSame('Hello, *orld!', StringHelper::mask('Hello, World!', 7, 1));
486+
$this->assertSame('Saleh Hashemi', StringHelper::mask('Saleh Hashemi', 0, 0));
487+
488+
// Different Mask Character
489+
$this->assertSame('12######90', StringHelper::mask('1234567890', 2, 6, '#'));
490+
491+
// Positions outside the string
492+
$this->assertSame('1234567890', StringHelper::mask('1234567890', 20, 6));
493+
$this->assertSame('1234567890', StringHelper::mask('1234567890', -20, 6));
494+
495+
// Negative values for start
496+
$this->assertSame('1234****90', StringHelper::mask('1234567890', -6, 4));
497+
498+
// type-related edge case
499+
$this->assertSame('1234****90', StringHelper::mask(1234567890, -6, 4));
500+
501+
// Multibyte characters
502+
$this->assertSame('你**', StringHelper::mask('你好吗', 1, 2));
503+
$this->assertSame('你好吗', StringHelper::mask('你好吗', 4, 2));
504+
505+
// Special characters
506+
$this->assertSame('em**[email protected]', StringHelper::mask('[email protected]', 2, 2));
507+
$this->assertSame('******email.com', StringHelper::mask('[email protected]', 0, 6));
508+
}
477509
}

0 commit comments

Comments
 (0)