From c1bfe35f573e2dde1898dbc222eb45a12f4268dc Mon Sep 17 00:00:00 2001 From: "Daniel St. Jules" Date: Tue, 16 Jul 2013 00:04:32 -0400 Subject: [PATCH] Add pad --- README.md | 14 ++++++++ src/Stringy/Stringy.php | 61 +++++++++++++++++++++++++++++++++++ tests/Stringy/StringyTest.php | 42 ++++++++++++++++++++++++ 3 files changed, 117 insertions(+) diff --git a/README.md b/README.md index 79e049a..acca471 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ A PHP library with a variety of string manipulation functions with multibyte sup * [tidy](#tidy) * [clean](#clean) * [standardize](#standardize) + * [pad](#pad) * [Tests](#tests) * [License](#license) @@ -189,6 +190,19 @@ Converts some non-ASCII characters to their closest ASCII counterparts. S::standardize('fòô bàř'); // 'foo bar' ``` +##### pad + +S::pad(string $str , int $length [, string $padStr [, string $padType [, string $encoding]]]) + +Pads a string to a given length with another string. If length is less +than or equal to the length of $str, then no padding takes places. The +default string used for padding is a space, and the default type (one of +'left', 'right', 'both') is 'right'. + +```php +S::pad('fòô bàř', 10, '¬ø', 'left', 'UTF-8'); // '¬ø¬fòô bàř' +``` + ## TODO **center** diff --git a/src/Stringy/Stringy.php b/src/Stringy/Stringy.php index 37c6c83..01204f0 100644 --- a/src/Stringy/Stringy.php +++ b/src/Stringy/Stringy.php @@ -262,6 +262,67 @@ class Stringy { return $str; } + + /** + * Pads a string to a given length with another string. If length is less + * than or equal to the length of $str, then no padding takes places. The + * default string used for padding is a space, and the default type (one of + * 'left', 'right', 'both') is 'right'. + * + * @param string $str String to pad + * @param int $length Desired string length after padding + * @param string $padStr String used to pad, defaults to space + * @param string $padType One of 'left', 'right', 'both' + * @param string $encoding The character encoding + * @return string The padded string + * @throws InvalidArgumentException If $padType isn't one of 'right', + * 'left' or 'both' + */ + public static function pad($str, $length, $padStr = ' ', $padType = 'right', + $encoding = null) { + $encoding = $encoding ?: mb_internal_encoding(); + + if (!in_array($padType, array('left', 'right', 'both'))) { + throw new InvalidArgumentException('Pad expects the fourth ' . + "argument to be one of 'left', 'right' or 'both'"); + } + + $strLength = mb_strlen($str, $encoding); + $padStrLength = mb_strlen($padStr, $encoding); + + if ($length <= $strLength || $padStrLength <= 0) + return $str; + + // Number of times to repeat the padStr if left or right + $times = ceil(($length - $strLength) / $padStrLength); + $paddedStr = ''; + + if ($padType == 'left') { + // Repeat the pad, cut it, and prepend + $leftPad = str_repeat($padStr, $times); + $leftPad = mb_substr($leftPad, 0, $length - $strLength, $encoding); + $paddedStr = $leftPad . $str; + } elseif ($padType == 'right') { + // Append the repeated pad and get a substring of the given length + $paddedStr = $str . str_repeat($padStr, $times); + $paddedStr = mb_substr($paddedStr, 0, $length, $encoding); + } else { + // Number of times to repeat the padStr on both sides + $paddingSize = ($length - $strLength) / 2; + $times = ceil($paddingSize / $padStrLength); + + // Favour right padding over left, as with str_pad() + $rightPad = str_repeat($padStr, $times); + $rightPad = mb_substr($rightPad, 0, ceil($paddingSize), $encoding); + + $leftPad = str_repeat($padStr, $times); + $leftPad = mb_substr($leftPad, 0, floor($paddingSize), $encoding); + + $paddedStr = $leftPad . $str . $rightPad; + } + + return $paddedStr; + } } ?> diff --git a/tests/Stringy/StringyTest.php b/tests/Stringy/StringyTest.php index a16f373..8816767 100644 --- a/tests/Stringy/StringyTest.php +++ b/tests/Stringy/StringyTest.php @@ -280,6 +280,48 @@ class StringyTestCase extends PHPUnit_Framework_TestCase { return $testData; } + /** + * @dataProvider stringsForPad + */ + public function testPad($string, $expected, $length, $padStr = ' ', + $padType = 'right', $encoding = null) { + $result = S::pad($string, $length, $padStr, $padType, $encoding); + $this->assertEquals($expected, $result); + } + + public function stringsForPad() { + $testData = array( + array('foo bar', 'foo bar', -1), + array('foo bar', 'foo bar', 7), + array('foo bar', 'foo bar ', 9), + array('foo bar', ' foo bar', 9, ' ', 'left'), + array('foo bar', 'foo bar ', 8, ' ', 'both'), + array('foo bar', ' foo bar ', 9, ' ', 'both'), + array('foo bar', '_*foo bar', 9, '_*', 'left'), + array('foo bar', '_*_foo bar', 10, '_*', 'left'), + array('foo bar', 'foo bar_*', 9, '_*', 'right'), + array('foo bar', 'foo bar_*_', 10, '_*', 'right'), + array('fòô bàř', 'fòô bàř', -1, 'UTF-8'), + array('fòô bàř', 'fòô bàř', 7, 'UTF-8'), + array('fòô bàř', 'fòô bàř ', 9, ' ', 'right', 'UTF-8'), + array('fòô bàř', ' fòô bàř', 9, ' ', 'left', 'UTF-8'), + array('fòô bàř', 'fòô bàř ', 8, ' ', 'both', 'UTF-8'), + array('fòô bàř', ' fòô bàř ', 9, ' ', 'both', 'UTF-8'), + array('fòô bàř', '¬øfòô bàř', 9, '¬ø', 'left', 'UTF-8'), + array('fòô bàř', '¬ø¬fòô bàř', 10, '¬ø', 'left', 'UTF-8'), + array('fòô bàř', '¬ø¬øfòô bàř', 11, '¬ø', 'left', 'UTF-8'), + array('fòô bàř', 'fòô bàř¬ø', 9, '¬ø', 'right', 'UTF-8'), + array('fòô bàř', 'fòô bàř¬ø¬', 10, '¬ø', 'right', 'UTF-8'), + array('fòô bàř', 'fòô bàř¬ø¬ø', 11, '¬ø', 'right', 'UTF-8'), + array('fòô bàř', 'fòô bàř¬', 8, '¬ø', 'both', 'UTF-8'), + array('fòô bàř', '¬fòô bàř¬', 9, '¬ø', 'both', 'UTF-8'), + array('fòô bàř', '¬fòô bàř¬ø', 10, '¬ø', 'both', 'UTF-8'), + array('fòô bàř', '¬øfòô bàř¬ø', 11, '¬ø', 'both', 'UTF-8'), + ); + + return $testData; + } + } ?>