PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.10.8
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.10.8
4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 3.10.4 All 148 releases
visualizer / vendor / neitanod / forceutf8 / src / ForceUTF8 / Encoding.php

Encoding.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.10.8, at vendor/neitanod/forceutf8/src/ForceUTF8/Encoding.php

353 lines 11.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Copyright (c) 2008 Sebastián Grignoli
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 2. Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 3. Neither the name of copyright holders nor the names of its
15 contributors may be used to endorse or promote products derived
16 from this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS
22 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 /**
32 * @author "Sebastián Grignoli" <grignoli@gmail.com>
33 * @package Encoding
34 * @version 2.0
35 * @link https://github.com/neitanod/forceutf8
36 * @example https://github.com/neitanod/forceutf8
37 * @license Revised BSD
38 */
39
40 namespace ForceUTF8;
41
42 class Encoding {
43
44 const ICONV_TRANSLIT = "TRANSLIT";
45 const ICONV_IGNORE = "IGNORE";
46 const WITHOUT_ICONV = "";
47
48 protected static $win1252ToUtf8 = array(
49 128 => "\xe2\x82\xac",
50
51 130 => "\xe2\x80\x9a",
52 131 => "\xc6\x92",
53 132 => "\xe2\x80\x9e",
54 133 => "\xe2\x80\xa6",
55 134 => "\xe2\x80\xa0",
56 135 => "\xe2\x80\xa1",
57 136 => "\xcb\x86",
58 137 => "\xe2\x80\xb0",
59 138 => "\xc5\xa0",
60 139 => "\xe2\x80\xb9",
61 140 => "\xc5\x92",
62
63 142 => "\xc5\xbd",
64
65
66 145 => "\xe2\x80\x98",
67 146 => "\xe2\x80\x99",
68 147 => "\xe2\x80\x9c",
69 148 => "\xe2\x80\x9d",
70 149 => "\xe2\x80\xa2",
71 150 => "\xe2\x80\x93",
72 151 => "\xe2\x80\x94",
73 152 => "\xcb\x9c",
74 153 => "\xe2\x84\xa2",
75 154 => "\xc5\xa1",
76 155 => "\xe2\x80\xba",
77 156 => "\xc5\x93",
78
79 158 => "\xc5\xbe",
80 159 => "\xc5\xb8"
81 );
82
83 protected static $brokenUtf8ToUtf8 = array(
84 "\xc2\x80" => "\xe2\x82\xac",
85
86 "\xc2\x82" => "\xe2\x80\x9a",
87 "\xc2\x83" => "\xc6\x92",
88 "\xc2\x84" => "\xe2\x80\x9e",
89 "\xc2\x85" => "\xe2\x80\xa6",
90 "\xc2\x86" => "\xe2\x80\xa0",
91 "\xc2\x87" => "\xe2\x80\xa1",
92 "\xc2\x88" => "\xcb\x86",
93 "\xc2\x89" => "\xe2\x80\xb0",
94 "\xc2\x8a" => "\xc5\xa0",
95 "\xc2\x8b" => "\xe2\x80\xb9",
96 "\xc2\x8c" => "\xc5\x92",
97
98 "\xc2\x8e" => "\xc5\xbd",
99
100
101 "\xc2\x91" => "\xe2\x80\x98",
102 "\xc2\x92" => "\xe2\x80\x99",
103 "\xc2\x93" => "\xe2\x80\x9c",
104 "\xc2\x94" => "\xe2\x80\x9d",
105 "\xc2\x95" => "\xe2\x80\xa2",
106 "\xc2\x96" => "\xe2\x80\x93",
107 "\xc2\x97" => "\xe2\x80\x94",
108 "\xc2\x98" => "\xcb\x9c",
109 "\xc2\x99" => "\xe2\x84\xa2",
110 "\xc2\x9a" => "\xc5\xa1",
111 "\xc2\x9b" => "\xe2\x80\xba",
112 "\xc2\x9c" => "\xc5\x93",
113
114 "\xc2\x9e" => "\xc5\xbe",
115 "\xc2\x9f" => "\xc5\xb8"
116 );
117
118 protected static $utf8ToWin1252 = array(
119 "\xe2\x82\xac" => "\x80",
120
121 "\xe2\x80\x9a" => "\x82",
122 "\xc6\x92" => "\x83",
123 "\xe2\x80\x9e" => "\x84",
124 "\xe2\x80\xa6" => "\x85",
125 "\xe2\x80\xa0" => "\x86",
126 "\xe2\x80\xa1" => "\x87",
127 "\xcb\x86" => "\x88",
128 "\xe2\x80\xb0" => "\x89",
129 "\xc5\xa0" => "\x8a",
130 "\xe2\x80\xb9" => "\x8b",
131 "\xc5\x92" => "\x8c",
132
133 "\xc5\xbd" => "\x8e",
134
135
136 "\xe2\x80\x98" => "\x91",
137 "\xe2\x80\x99" => "\x92",
138 "\xe2\x80\x9c" => "\x93",
139 "\xe2\x80\x9d" => "\x94",
140 "\xe2\x80\xa2" => "\x95",
141 "\xe2\x80\x93" => "\x96",
142 "\xe2\x80\x94" => "\x97",
143 "\xcb\x9c" => "\x98",
144 "\xe2\x84\xa2" => "\x99",
145 "\xc5\xa1" => "\x9a",
146 "\xe2\x80\xba" => "\x9b",
147 "\xc5\x93" => "\x9c",
148
149 "\xc5\xbe" => "\x9e",
150 "\xc5\xb8" => "\x9f"
151 );
152
153 static function toUTF8($text){
154 /**
155 * Function \ForceUTF8\Encoding::toUTF8
156 *
157 * This function leaves UTF8 characters alone, while converting almost all non-UTF8 to UTF8.
158 *
159 * It assumes that the encoding of the original string is either Windows-1252 or ISO 8859-1.
160 *
161 * It may fail to convert characters to UTF-8 if they fall into one of these scenarios:
162 *
163 * 1) when any of these characters: ÀÁÂÃÄ�
164 ÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞß
165 * are followed by any of these: ("group B")
166 * ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶•¸¹º»¼½¾¿
167 * For example: %ABREPRESENT%C9%BB. «REPRESENTÉ»
168 * The "«" (%AB) character will be converted, but the "É" followed by "»" (%C9%BB)
169 * is also a valid unicode character, and will be left unchanged.
170 *
171 * 2) when any of these: àáâãäåæçèéêëìíîï are followed by TWO chars from group B,
172 * 3) when any of these: ðñòó are followed by THREE chars from group B.
173 *
174 * @name toUTF8
175 * @param string $text Any string.
176 * @return string The same string, UTF8 encoded
177 *
178 */
179
180 if(is_array($text))
181 {
182 foreach($text as $k => $v)
183 {
184 $text[$k] = self::toUTF8($v);
185 }
186 return $text;
187 }
188
189 if(!is_string($text)) {
190 return $text;
191 }
192
193 $max = self::strlen($text);
194
195 $buf = "";
196 for($i = 0; $i < $max; $i++){
197 $c1 = $text[$i];
198 if($c1>="\xc0"){ //Should be converted to UTF8, if it's not UTF8 already
199 $c2 = $i+1 >= $max? "\x00" : $text[$i+1];
200 $c3 = $i+2 >= $max? "\x00" : $text[$i+2];
201 $c4 = $i+3 >= $max? "\x00" : $text[$i+3];
202 if($c1 >= "\xc0" & $c1 <= "\xdf"){ //looks like 2 bytes UTF8
203 if($c2 >= "\x80" && $c2 <= "\xbf"){ //yeah, almost sure it's UTF8 already
204 $buf .= $c1 . $c2;
205 $i++;
206 } else { //not valid UTF8. Convert it.
207 $cc1 = (chr(ord($c1) / 64) | "\xc0");
208 $cc2 = ($c1 & "\x3f") | "\x80";
209 $buf .= $cc1 . $cc2;
210 }
211 } elseif($c1 >= "\xe0" & $c1 <= "\xef"){ //looks like 3 bytes UTF8
212 if($c2 >= "\x80" && $c2 <= "\xbf" && $c3 >= "\x80" && $c3 <= "\xbf"){ //yeah, almost sure it's UTF8 already
213 $buf .= $c1 . $c2 . $c3;
214 $i = $i + 2;
215 } else { //not valid UTF8. Convert it.
216 $cc1 = (chr(ord($c1) / 64) | "\xc0");
217 $cc2 = ($c1 & "\x3f") | "\x80";
218 $buf .= $cc1 . $cc2;
219 }
220 } elseif($c1 >= "\xf0" & $c1 <= "\xf7"){ //looks like 4 bytes UTF8
221 if($c2 >= "\x80" && $c2 <= "\xbf" && $c3 >= "\x80" && $c3 <= "\xbf" && $c4 >= "\x80" && $c4 <= "\xbf"){ //yeah, almost sure it's UTF8 already
222 $buf .= $c1 . $c2 . $c3 . $c4;
223 $i = $i + 3;
224 } else { //not valid UTF8. Convert it.
225 $cc1 = (chr(ord($c1) / 64) | "\xc0");
226 $cc2 = ($c1 & "\x3f") | "\x80";
227 $buf .= $cc1 . $cc2;
228 }
229 } else { //doesn't look like UTF8, but should be converted
230 $cc1 = (chr(ord($c1) / 64) | "\xc0");
231 $cc2 = (($c1 & "\x3f") | "\x80");
232 $buf .= $cc1 . $cc2;
233 }
234 } elseif(($c1 & "\xc0") === "\x80"){ // needs conversion
235 if(isset(self::$win1252ToUtf8[ord($c1)])) { //found in Windows-1252 special cases
236 $buf .= self::$win1252ToUtf8[ord($c1)];
237 } else {
238 $cc1 = (chr(ord($c1) / 64) | "\xc0");
239 $cc2 = (($c1 & "\x3f") | "\x80");
240 $buf .= $cc1 . $cc2;
241 }
242 } else { // it doesn't need conversion
243 $buf .= $c1;
244 }
245 }
246 return $buf;
247 }
248
249 static function toWin1252($text, $option = self::WITHOUT_ICONV) {
250 if(is_array($text)) {
251 foreach($text as $k => $v) {
252 $text[$k] = self::toWin1252($v, $option);
253 }
254 return $text;
255 } elseif(is_string($text)) {
256 return static::utf8_decode($text, $option);
257 } else {
258 return $text;
259 }
260 }
261
262 static function toISO8859($text, $option = self::WITHOUT_ICONV) {
263 return self::toWin1252($text, $option);
264 }
265
266 static function toLatin1($text, $option = self::WITHOUT_ICONV) {
267 return self::toWin1252($text, $option);
268 }
269
270 static function fixUTF8($text, $option = self::WITHOUT_ICONV){
271 if(is_array($text)) {
272 foreach($text as $k => $v) {
273 $text[$k] = self::fixUTF8($v, $option);
274 }
275 return $text;
276 }
277
278 if(!is_string($text)) {
279 return $text;
280 }
281
282 $last = "";
283 while($last <> $text){
284 $last = $text;
285 $text = self::toUTF8(static::utf8_decode($text, $option));
286 }
287 $text = self::toUTF8(static::utf8_decode($text, $option));
288 return $text;
289 }
290
291 static function UTF8FixWin1252Chars($text){
292 // If you received an UTF-8 string that was converted from Windows-1252 as it was ISO8859-1
293 // (ignoring Windows-1252 chars from 80 to 9F) use this function to fix it.
294 // See: http://en.wikipedia.org/wiki/Windows-1252
295
296 return str_replace(array_keys(self::$brokenUtf8ToUtf8), array_values(self::$brokenUtf8ToUtf8), $text);
297 }
298
299 static function removeBOM($str=""){
300 if(substr($str, 0,3) === pack("CCC",0xef,0xbb,0xbf)) {
301 $str=substr($str, 3);
302 }
303 return $str;
304 }
305
306 protected static function strlen($text){
307 return (function_exists('mb_strlen') && ((int) ini_get('mbstring.func_overload')) & 2) ?
308 mb_strlen($text,'8bit') : strlen($text);
309 }
310
311 public static function normalizeEncoding($encodingLabel)
312 {
313 $encoding = strtoupper($encodingLabel);
314 $encoding = preg_replace('/[^a-zA-Z0-9\s]/', '', $encoding);
315 $equivalences = array(
316 'ISO88591' => 'ISO-8859-1',
317 'ISO8859' => 'ISO-8859-1',
318 'ISO' => 'ISO-8859-1',
319 'LATIN1' => 'ISO-8859-1',
320 'LATIN' => 'ISO-8859-1',
321 'UTF8' => 'UTF-8',
322 'UTF' => 'UTF-8',
323 'WIN1252' => 'ISO-8859-1',
324 'WINDOWS1252' => 'ISO-8859-1'
325 );
326
327 if(empty($equivalences[$encoding])){
328 return 'UTF-8';
329 }
330
331 return $equivalences[$encoding];
332 }
333
334 public static function encode($encodingLabel, $text)
335 {
336 $encodingLabel = self::normalizeEncoding($encodingLabel);
337 if($encodingLabel === 'ISO-8859-1') return self::toLatin1($text);
338 return self::toUTF8($text);
339 }
340
341 protected static function utf8_decode($text, $option = self::WITHOUT_ICONV)
342 {
343 if ($option == self::WITHOUT_ICONV || !function_exists('iconv')) {
344 $o = utf8_decode(
345 str_replace(array_keys(self::$utf8ToWin1252), array_values(self::$utf8ToWin1252), self::toUTF8($text))
346 );
347 } else {
348 $o = iconv("UTF-8", "Windows-1252" . ($option === self::ICONV_TRANSLIT ? '//TRANSLIT' : ($option === self::ICONV_IGNORE ? '//IGNORE' : '')), $text);
349 }
350 return $o;
351 }
352 }
353