Merge pull request #8471 from MrPetovan/bug/8470-twitter-expand-entities
Add new Strings::substringReplace method
This commit is contained in:
commit
9f25327189
2 changed files with 98 additions and 0 deletions
|
@ -420,4 +420,42 @@ class Strings
|
||||||
|
|
||||||
return $pathItem;
|
return $pathItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multi-byte safe implementation of substr_replace where $start and $length are character offset and count rather
|
||||||
|
* than byte offset and counts.
|
||||||
|
*
|
||||||
|
* Depends on mbstring, use default encoding.
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
* @param string $replacement
|
||||||
|
* @param int $start
|
||||||
|
* @param int|null $length
|
||||||
|
* @return string
|
||||||
|
* @see substr_replace()
|
||||||
|
*/
|
||||||
|
public static function substringReplace(string $string, string $replacement, int $start, int $length = null)
|
||||||
|
{
|
||||||
|
$string_length = mb_strlen($string);
|
||||||
|
|
||||||
|
$length = $length ?? $string_length;
|
||||||
|
|
||||||
|
if ($start < 0) {
|
||||||
|
$start = max(0, $string_length + $start);
|
||||||
|
} else if ($start > $string_length) {
|
||||||
|
$start = $string_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($length < 0) {
|
||||||
|
$length = max(0, $string_length - $start + $length);
|
||||||
|
} else if ($length > $string_length) {
|
||||||
|
$length = $string_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($start + $length) > $string_length) {
|
||||||
|
$length = $string_length - $start;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mb_substr($string, 0, $start) . $replacement . mb_substr($string, $start + $length, $string_length - $start - $length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,4 +134,64 @@ class StringsTest extends TestCase
|
||||||
{
|
{
|
||||||
$this->assertEquals($valid, Strings::isHex($input));
|
$this->assertEquals($valid, Strings::isHex($input));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that Strings::substringReplace behaves the same as substr_replace with ASCII strings in all the possible
|
||||||
|
* numerical parameter configurations (positive, negative, zero, out of bounds either side, null)
|
||||||
|
*/
|
||||||
|
public function testSubstringReplaceASCII()
|
||||||
|
{
|
||||||
|
for ($start = -10; $start <= 10; $start += 5) {
|
||||||
|
$this->assertEquals(
|
||||||
|
substr_replace('string', 'replacement', $start),
|
||||||
|
Strings::substringReplace('string', 'replacement', $start)
|
||||||
|
);
|
||||||
|
|
||||||
|
for ($length = -10; $length <= 10; $length += 5) {
|
||||||
|
$this->assertEquals(
|
||||||
|
substr_replace('string', 'replacement', $start, $length),
|
||||||
|
Strings::substringReplace('string', 'replacement', $start, $length)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function dataSubstringReplaceMultiByte()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'issue-8470' => [
|
||||||
|
'expected' => 'Je n’y pense que maintenant (pask ma sonnette ne fonctionne pas) : mettre un gentil mot avec mes coordonnées sur ma porte est le moyen le plus simple de rester en contact si besoin avec mon voisinage direct ! [url=https://www.instagram.com/p/B-UdH2loee1/?igshid=x4aglyju9kva]instagram.com/p/B-UdH2loee1/…[/url] [rest of the post]',
|
||||||
|
'string' => 'Je n’y pense que maintenant (pask ma sonnette ne fonctionne pas) : mettre un gentil mot avec mes coordonnées sur ma porte est le moyen le plus simple de rester en contact si besoin avec mon voisinage direct ! https://t.co/YoBWTHsAAk [rest of the post]',
|
||||||
|
'replacement' => '[url=https://www.instagram.com/p/B-UdH2loee1/?igshid=x4aglyju9kva]instagram.com/p/B-UdH2loee1/…[/url]',
|
||||||
|
'start' => 209,
|
||||||
|
'length' => 23,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests cases where Strings::substringReplace is needed over substr_replace with multi-byte strings and character
|
||||||
|
* offsets
|
||||||
|
*
|
||||||
|
* @param string $expected
|
||||||
|
* @param string $string
|
||||||
|
* @param string $replacement
|
||||||
|
* @param int $start
|
||||||
|
* @param int|null $length
|
||||||
|
*
|
||||||
|
* @dataProvider dataSubstringReplaceMultiByte
|
||||||
|
*/
|
||||||
|
public function testSubstringReplaceMultiByte(string $expected, string $string, string $replacement, int $start, int $length = null)
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
Strings::substringReplace(
|
||||||
|
$string,
|
||||||
|
$replacement,
|
||||||
|
$start,
|
||||||
|
$length
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue