mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-10-31 10:39:59 +08:00 
			
		
		
		
	Fix #20032: Added mask method for string masking with multibyte support
				
					
				
			This commit is contained in:
		| @ -11,6 +11,8 @@ Yii Framework 2 Change Log | |||||||
| - Bug #20002: Fixed superfluous query on HEAD request in serializer (xicond) | - Bug #20002: Fixed superfluous query on HEAD request in serializer (xicond) | ||||||
| - Enh #12743: Added new methods `BaseActiveRecord::loadRelations()` and `BaseActiveRecord::loadRelationsFor()` to eager load related models for existing primary model instances (PowerGamer1) | - Enh #12743: Added new methods `BaseActiveRecord::loadRelations()` and `BaseActiveRecord::loadRelationsFor()` to eager load related models for existing primary model instances (PowerGamer1) | ||||||
| - Enh #20030: Improve performance of handling `ErrorHandler::$memoryReserveSize` (antonshevelev, rob006) | - Enh #20030: Improve performance of handling `ErrorHandler::$memoryReserveSize` (antonshevelev, rob006) | ||||||
|  | - Enh #20032: Added `mask` method for string masking with multibyte support (salehhashemi1992) | ||||||
|  |  | ||||||
|  |  | ||||||
| 2.0.49.2 October 12, 2023 | 2.0.49.2 October 12, 2023 | ||||||
| ------------------------- | ------------------------- | ||||||
|  | |||||||
| @ -497,4 +497,34 @@ class BaseStringHelper | |||||||
|  |  | ||||||
|         return implode('', $parts); |         return implode('', $parts); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Masks a portion of a string with a repeated character. | ||||||
|  |      * This method is multibyte-safe. | ||||||
|  |      * | ||||||
|  |      * @param string $string The input string. | ||||||
|  |      * @param int $start The starting position from where to begin masking. | ||||||
|  |      *                   This can be a positive or negative integer. | ||||||
|  |      *                   Positive values count from the beginning, | ||||||
|  |      *                   negative values count from the end of the string. | ||||||
|  |      * @param int $length The length of the section to be masked. | ||||||
|  |      *                    The masking will start from the $start position | ||||||
|  |      *                    and continue for $length characters. | ||||||
|  |      * @param string $mask The character to use for masking. The default is '*'. | ||||||
|  |      * @return string The masked string. | ||||||
|  |      */ | ||||||
|  |     public static function mask($string, $start, $length, $mask = '*') { | ||||||
|  |         $strLength = mb_strlen($string, 'UTF-8'); | ||||||
|  |  | ||||||
|  |         // Return original string if start position is out of bounds | ||||||
|  |         if ($start >= $strLength || $start < -$strLength) { | ||||||
|  |             return $string; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $masked = mb_substr($string, 0, $start, 'UTF-8'); | ||||||
|  |         $masked .= str_repeat($mask, abs($length)); | ||||||
|  |         $masked .= mb_substr($string, $start + abs($length), null, 'UTF-8'); | ||||||
|  |  | ||||||
|  |         return $masked; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -474,4 +474,36 @@ class StringHelperTest extends TestCase | |||||||
|             ['', ''], |             ['', ''], | ||||||
|         ]; |         ]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public function testMask() | ||||||
|  |     { | ||||||
|  |         // Standard masking | ||||||
|  |         $this->assertSame('12******90', StringHelper::mask('1234567890', 2, 6)); | ||||||
|  |         $this->assertSame('a********j', StringHelper::mask('abcdefghij', 1, 8)); | ||||||
|  |         $this->assertSame('*************', StringHelper::mask('Hello, World!', 0, 13)); | ||||||
|  |         $this->assertSame('************!', StringHelper::mask('Hello, World!', 0, 12)); | ||||||
|  |         $this->assertSame('Hello, *orld!', StringHelper::mask('Hello, World!', 7, 1)); | ||||||
|  |         $this->assertSame('Saleh Hashemi', StringHelper::mask('Saleh Hashemi', 0, 0)); | ||||||
|  |  | ||||||
|  |         // Different Mask Character | ||||||
|  |         $this->assertSame('12######90', StringHelper::mask('1234567890', 2, 6, '#')); | ||||||
|  |  | ||||||
|  |         // Positions outside the string | ||||||
|  |         $this->assertSame('1234567890', StringHelper::mask('1234567890', 20, 6)); | ||||||
|  |         $this->assertSame('1234567890', StringHelper::mask('1234567890', -20, 6)); | ||||||
|  |  | ||||||
|  |         // Negative values for start | ||||||
|  |         $this->assertSame('1234****90', StringHelper::mask('1234567890', -6, 4)); | ||||||
|  |  | ||||||
|  |         // type-related edge case | ||||||
|  |         $this->assertSame('1234****90', StringHelper::mask(1234567890, -6, 4)); | ||||||
|  |  | ||||||
|  |         // Multibyte characters | ||||||
|  |         $this->assertSame('你**', StringHelper::mask('你好吗', 1, 2)); | ||||||
|  |         $this->assertSame('你好吗', StringHelper::mask('你好吗', 4, 2)); | ||||||
|  |  | ||||||
|  |         // Special characters | ||||||
|  |         $this->assertSame('em**l@email.com', StringHelper::mask('email@email.com', 2, 2)); | ||||||
|  |         $this->assertSame('******email.com', StringHelper::mask('email@email.com', 0, 6)); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Saleh Hashemi
					Saleh Hashemi