Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
100.00% |
1 / 1 |
|
100.00% |
2 / 2 |
CRAP | |
100.00% |
58 / 58 |
| convertNegativeTo | |
100.00% |
1 / 1 |
0 | |
100.00% |
8 / 8 |
|||
| from | |
100.00% |
1 / 1 |
0 | |
100.00% |
3 / 3 |
|||
| convertFromPositive | |
100.00% |
1 / 1 |
0 | |
100.00% |
21 / 21 |
|||
| convertFromNegative | |
100.00% |
1 / 1 |
0 | |
100.00% |
8 / 8 |
|||
| RFC2550 | |
100.00% |
1 / 1 |
|
100.00% |
2 / 2 |
7 | |
100.00% |
58 / 58 |
| to | |
100.00% |
1 / 1 |
3 | |
100.00% |
4 / 4 |
|||
| convertPositiveTo | |
100.00% |
1 / 1 |
4 | |
100.00% |
14 / 14 |
|||
| <?php | |
| namespace Popy\Calendar\Formatter\NumberConverter; | |
| use Popy\Calendar\Formatter\NumberConverterInterface; | |
| /** | |
| * Converts years for RFC2550 Implementation. | |
| * | |
| * @link https://tools.ietf.org/html/rfc2550 | |
| */ | |
| class RFC2550 implements NumberConverterInterface | |
| { | |
| const ORD_START = 65; | |
| const POSITIVE_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^'; | |
| const NEGATIVE_CHARS = '9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA!'; | |
| /** | |
| * @inheritDoc | |
| */ | |
| public function to($input) | |
| { | |
| $input = (string)$input; | |
| if ($input[0] === '-' || preg_match('/^0+$/', $input)) { | |
| return $this->convertNegativeTo($input); | |
| } | |
| return $this->convertPositiveTo($input); | |
| } | |
| /** | |
| * Convert a positive value into its RFC2550 representation. | |
| * | |
| * @param string $input Value (as a string) | |
| * | |
| * @return string | |
| */ | |
| protected function convertPositiveTo($input) | |
| { | |
| $extraLen = strlen($input) - 5; | |
| if ($extraLen < 0) { | |
| return str_pad($input, 4, '0', STR_PAD_LEFT); | |
| } | |
| if ($extraLen < 26) { | |
| return chr(static::ORD_START + $extraLen) . $input; | |
| } | |
| $extraLen -= 25; | |
| $prefix = ''; | |
| $carets = ''; | |
| do { | |
| $carets .= '^'; | |
| $extraLen--; | |
| $prefix = chr(static::ORD_START + $extraLen % 26) . $prefix; | |
| $extraLen = intval($extraLen / 26); | |
| } while ($extraLen); | |
| return "${carets}${prefix}${input}"; | |
| } | |
| /** | |
| * Converts a negative value into its RFC2550 representation. | |
| * | |
| * @param string $input Value (as a string) | |
| * | |
| * @return string | |
| */ | |
| protected function convertNegativeTo($input) | |
| { | |
| $res = $this->convertPositiveTo(substr($input, 1)); | |
| $res = strtr($res, static::POSITIVE_CHARS, static::NEGATIVE_CHARS); | |
| if (strlen($res) < 5) { | |
| $res = '/' . $res; | |
| } elseif ($res[0] !== '!') { | |
| $res = '*' . $res; | |
| } | |
| return $res; | |
| } | |
| /** | |
| * @inheritDoc | |
| */ | |
| public function from($input) | |
| { | |
| if (strpos('!/*', $input[0]) !== false) { | |
| return $this->convertFromNegative($input); | |
| } | |
| return $this->convertFromPositive($input); | |
| } | |
| /** | |
| * Convert a positive representation. | |
| * | |
| * @param string $input | |
| * | |
| * @return string | |
| */ | |
| public function convertFromPositive($input) | |
| { | |
| $matches = []; | |
| if ( | |
| !preg_match( | |
| ' | |
| /^0*(?<carets>\\^*)(?<alpha>[A-Z]*)(?<year>\d+)$/', | |
| $input, | |
| $matches | |
| ) | |
| ) { | |
| return; | |
| } | |
| if ($matches['alpha'] === '') { | |
| return $matches['year']; | |
| } | |
| if ($matches['carets'] === '') { | |
| $expectedLength = ord($matches['alpha']) - static::ORD_START + 5; | |
| } else { | |
| $len = strlen($matches['carets']); | |
| $expectedLength = 0; | |
| for ($i=0; $i < $len; $i++) { | |
| $expectedLength = $expectedLength * 26; | |
| $expectedLength += ord($matches['alpha'][$i]) - static::ORD_START; | |
| $expectedLength++; | |
| } | |
| $expectedLength += 30; | |
| } | |
| return str_pad($matches['year'], $expectedLength, '0', STR_PAD_RIGHT); | |
| } | |
| /** | |
| * Convert a negative representation. | |
| * | |
| * @param string $input | |
| * | |
| * @return string | |
| */ | |
| public function convertFromNegative($input) | |
| { | |
| if (strpos('/*', $input[0]) !== false) { | |
| $input = substr($input, 1); | |
| } | |
| $input = strtr($input, static::NEGATIVE_CHARS, static::POSITIVE_CHARS); | |
| $res = $this->convertFromPositive($input); | |
| if (preg_match('/^0+$/', $res)) { | |
| return $res; | |
| } | |
| return '-' . $res; | |
| } | |
| } |