[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 namespace Algo26\IdnaConvert\Punycode; 4 5 use Algo26\IdnaConvert\Exception\AlreadyPunycodeException; 6 use Algo26\IdnaConvert\Exception\InvalidCharacterException; 7 use Algo26\IdnaConvert\Exception\InvalidIdnVersionException; 8 use Algo26\IdnaConvert\NamePrep\NamePrep; 9 10 class ToPunycode extends AbstractPunycode implements PunycodeInterface 11 { 12 /** @var NamePrep */ 13 private $namePrep; 14 15 /** 16 * @throws InvalidIdnVersionException 17 */ 18 public function __construct(?string $idnVersion = null) 19 { 20 $this->namePrep = new NamePrep($idnVersion); 21 parent::__construct(); 22 } 23 24 /** 25 * @param array $decoded 26 * 27 * @return string 28 * @throws AlreadyPunycodeException 29 * @throws InvalidCharacterException 30 */ 31 public function convert(array $decoded): string 32 { 33 // We cannot encode a domain name containing the Punycode prefix 34 $checkForPrefix = array_slice($decoded, 0, self::$prefixLength); 35 if (self::$prefixAsArray === $checkForPrefix) { 36 throw new AlreadyPunycodeException('This is already a Punycode string', 100); 37 } 38 // We will not try to encode strings consisting of basic code points only 39 $canEncode = false; 40 foreach ($decoded as $k => $v) { 41 if ($v > 0x7a) { 42 $canEncode = true; 43 break; 44 } 45 } 46 if (!$canEncode) { 47 return false; 48 } 49 50 // Do NAMEPREP 51 $decoded = $this->namePrep->do($decoded); 52 if (!$decoded || !is_array($decoded)) { 53 return false; // NAMEPREP failed 54 } 55 56 $decodedLength = count($decoded); 57 if (!$decodedLength) { 58 return false; // Empty array 59 } 60 61 $codeCount = 0; // How many chars have been consumed 62 $encoded = ''; 63 // Copy all basic code points to output 64 for ($i = 0; $i < $decodedLength; ++$i) { 65 $test = $decoded[$i]; 66 // Will match [-0-9a-zA-Z] 67 if ((0x2F < $test && $test < 0x40) 68 || (0x40 < $test && $test < 0x5B) 69 || (0x60 < $test && $test <= 0x7B) 70 || (0x2D == $test) 71 ) { 72 $encoded .= chr($decoded[$i]); 73 $codeCount++; 74 } 75 } 76 if ($codeCount === $decodedLength) { 77 return $encoded; // All codepoints were basic ones 78 } 79 80 // Start with the prefix; copy it to output 81 $encoded = self::punycodePrefix . $encoded; 82 // If we have basic code points in output, add an hyphen to the end 83 if ($codeCount) { 84 $encoded .= '-'; 85 } 86 // Now find and encode all non-basic code points 87 $isFirst = true; 88 $currentCode = self::initialN; 89 $bias = self::initialBias; 90 $delta = 0; 91 while ($codeCount < $decodedLength) { 92 // Find the smallest code point >= the current code point and 93 // remember the last occurrence of it in the input 94 for ($i = 0, $nextCode = self::maxUcs; $i < $decodedLength; $i++) { 95 if ($decoded[$i] >= $currentCode && $decoded[$i] <= $nextCode) { 96 $nextCode = $decoded[$i]; 97 } 98 } 99 $delta += ($nextCode - $currentCode) * ($codeCount + 1); 100 $currentCode = $nextCode; 101 102 // Scan input again and encode all characters whose code point is $currentCode 103 for ($i = 0; $i < $decodedLength; $i++) { 104 if ($decoded[$i] < $currentCode) { 105 $delta++; 106 } elseif ($decoded[$i] == $currentCode) { 107 for ($q = $delta, $k = self::base; 1; $k += self::base) { 108 $t = ($k <= $bias) 109 ? self::tMin 110 : (($k >= $bias + self::tMax) 111 ? self::tMax 112 : $k - $bias 113 ); 114 if ($q < $t) { 115 break; 116 } 117 118 $encoded .= $this->encodeDigit(intval($t + (($q - $t) % (self::base - $t)))); 119 $q = (int) (($q - $t) / (self::base - $t)); 120 } 121 $encoded .= $this->encodeDigit($q); 122 $bias = $this->adapt($delta, $codeCount + 1, $isFirst); 123 $codeCount++; 124 $delta = 0; 125 $isFirst = false; 126 } 127 } 128 $delta++; 129 $currentCode++; 130 } 131 132 return $encoded; 133 } 134 135 /** 136 * Encoding a certain digit 137 * @param int $d 138 * @return string 139 */ 140 private function encodeDigit($d): string 141 { 142 return chr($d + 22 + 75 * ($d < 26)); 143 } 144 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |