Completed
Push — master ( 23805b...5c0366 )
by Yannick
31:36
created

Common::getData()   F

Complexity

Conditions 19
Paths 2592

Size

Total Lines 67
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 19
eloc 51
nc 2592
nop 8
dl 0
loc 67
rs 2.7051
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
require_once(dirname(__FILE__).'/libs/simple_html_dom.php');
3
require_once(dirname(__FILE__).'/libs/uagent/uagent.php');
4
require_once(dirname(__FILE__).'/settings.php');
5
6
class Common {
7
	//protected $cookies = array();
8
	
9
	/**
10
	* Get data from form result
11
	* @param String $url form URL
12
	* @param String $type type of submit form method (get or post)
13
	* @param String|Array $data values form post method
14
	* @param Array $headers header to submit with the form
15
	* @return String the result
16
	*/
17
	public function getData($url, $type = 'get', $data = '', $headers = '',$cookie = '',$referer = '',$timeout = '',$useragent = '') {
18
		global $globalProxy, $globalForceIPv4;
19
		$ch = curl_init();
20
		curl_setopt($ch, CURLOPT_URL, $url);
21
		if (isset($globalForceIPv4) && $globalForceIPv4) {
22
			if (defined('CURLOPT_IPRESOLVE') && defined('CURL_IPRESOLVE_V4')){
23
				curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
24
			}
25
		}
26
		if (isset($globalProxy) && $globalProxy != '') {
27
			curl_setopt($ch, CURLOPT_PROXY, $globalProxy);
28
		}
29
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
30
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
31
		curl_setopt($ch, CURLINFO_HEADER_OUT, true); 
32
		curl_setopt($ch,CURLOPT_ENCODING , "gzip");
33
		//curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 GTB5');
34
//		curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0');
35
		if ($useragent == '') {
36
			curl_setopt($ch, CURLOPT_USERAGENT, UAgent::random());
37
		} else {
38
			curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
39
		}
40
		if ($timeout == '') curl_setopt($ch, CURLOPT_TIMEOUT, 10); 
41
		else curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); 
42
		curl_setopt($ch, CURLOPT_HEADERFUNCTION, array('Common',"curlResponseHeaderCallback"));
43
		if ($type == 'post') {
44
			curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
45
			if (is_array($data)) {
46
				curl_setopt($ch, CURLOPT_POST, count($data));
47
				$data_string = '';
48
				foreach($data as $key=>$value) { $data_string .= $key.'='.$value.'&'; }
49
				rtrim($data_string, '&');
50
				curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
51
			} else {
52
				curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
53
			}
54
		}
55
		if ($headers != '') {
56
			curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
57
		}
58
		if ($cookie != '') {
59
			if (is_array($cookie)) {
60
				curl_setopt($ch, CURLOPT_COOKIE, implode($cookie,';'));
61
			} else {
62
				curl_setopt($ch, CURLOPT_COOKIE, $cookie);
63
			}
64
		}
65
		if ($referer != '') {
66
			curl_setopt($ch, CURLOPT_REFERER, $referer);
67
		}
68
		$result = curl_exec($ch);
69
		$info = curl_getinfo($ch);
70
		//var_dump($info);
71
		curl_close($ch);
72
		if ($info['http_code'] == '503' && strstr($result,'DDoS protection by CloudFlare')) {
73
			echo "Cloudflare Detected\n";
74
			require_once(dirname(__FILE__).'/libs/cloudflare-bypass/libraries/cloudflareClass.php');
75
			$useragent = UAgent::random();
76
			cloudflare::useUserAgent($useragent);
77
			if ($clearanceCookie = cloudflare::bypass($url)) {
78
				return $this->getData($url,'get',$data,$headers,$clearanceCookie,$referer,$timeout,$useragent);
79
			}
80
		} else {
81
			return $result;
82
		}
83
	}
84
	
85
	private function curlResponseHeaderCallback($ch, $headerLine) {
86
		//global $cookies;
87
		$cookies = array();
88
		if (preg_match('/^Set-Cookie:\s*([^;]*)/mi', $headerLine, $cookie) == 1)
89
			$cookies[] = $cookie;
90
		return strlen($headerLine); // Needed by curl
91
	}
92
93
	public static function download($url, $file, $referer = '') {
94
		global $globalDebug;
95
		$fp = fopen($file, 'w');
96
		$ch = curl_init();
97
		curl_setopt($ch, CURLOPT_URL, $url);
98
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
99
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
100
		if ($referer != '') curl_setopt($ch, CURLOPT_REFERER, $referer);
101
		curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 GTB5');
102
		curl_setopt($ch, CURLOPT_FILE, $fp);
103
		curl_exec($ch);
104
		if (curl_errno($ch) && $globalDebug) echo 'Download error: '.curl_error($ch);
105
		curl_close($ch);
106
		fclose($fp);
107
	}
108
109
	public static function gunzip($in_file,$out_file_name = '') {
110
		//echo $in_file.' -> '.$out_file_name."\n";
111
		$buffer_size = 4096; // read 4kb at a time
112
		if ($out_file_name == '') $out_file_name = str_replace('.gz', '', $in_file); 
113
		if ($in_file != '' && file_exists($in_file)) {
114
			// PHP version of Ubuntu use gzopen64 instead of gzopen
115
			if (function_exists('gzopen')) $file = gzopen($in_file,'rb');
116
			elseif (function_exists('gzopen64')) $file = gzopen64($in_file,'rb');
117
			else {
118
				echo 'gzopen not available';
119
				die;
120
			}
121
			$out_file = fopen($out_file_name, 'wb'); 
122
			while(!gzeof($file)) {
123
				fwrite($out_file, gzread($file, $buffer_size));
124
			}  
125
			fclose($out_file);
126
			gzclose($file);
127
		}
128
	}
129
130
	public static function bunzip2($in_file,$out_file_name = '') {
131
		//echo $in_file.' -> '.$out_file_name."\n";
132
		$buffer_size = 4096; // read 4kb at a time
133
		if ($out_file_name == '') $out_file_name = str_replace('.bz2', '', $in_file); 
134
		if ($in_file != '' && file_exists($in_file)) {
135
			// PHP version of Ubuntu use gzopen64 instead of gzopen
136
			if (function_exists('bzopen')) $file = bzopen($in_file,'rb');
137
			else {
138
				echo 'bzopen not available';
139
				die;
140
			}
141
			$out_file = fopen($out_file_name, 'wb'); 
142
			while(!feof($file)) {
143
				fwrite($out_file, bzread($file, $buffer_size));
144
			}  
145
			fclose($out_file);
146
			bzclose($file);
147
		}
148
	}
149
150
	/**
151
	* Convert a HTML table to an array
152
	* @param String $data HTML page
153
	* @return Array array of the tables in HTML page
154
	*/
155
	public function table2array($data) {
156
		if (!is_string($data)) return array();
157
		if ($data == '') return array();
158
		$html = str_get_html($data);
159
		if ($html === false) return array();
160
		$tabledata=array();
161
		foreach($html->find('tr') as $element)
162
		{
163
			$td = array();
164
			foreach( $element->find('th') as $row)
165
			{
166
				$td [] = trim($row->plaintext);
167
			}
168
			$td=array_filter($td);
169
			$tabledata[] = $td;
170
171
			$td = array();
172
			$tdi = array();
173
			foreach( $element->find('td') as $row)
174
			{
175
				$td [] = trim($row->plaintext);
176
				$tdi [] = trim($row->innertext);
177
			}
178
			$td=array_filter($td);
179
			$tdi=array_filter($tdi);
180
			$tabledata[]=array_merge($td,$tdi);
181
		}
182
		$html->clear();
183
		unset($html);
184
		return(array_filter($tabledata));
185
	}
186
	
187
	/**
188
	* Convert <p> part of a HTML page to an array
189
	* @param String $data HTML page
190
	* @return Array array of the <p> in HTML page
191
	*/
192
	public function text2array($data) {
193
		$html = str_get_html($data);
194
		if ($html === false) return array();
195
		$tabledata=array();
196
		foreach($html->find('p') as $element)
197
		{
198
			$tabledata [] = trim($element->plaintext);
199
		}
200
		$html->clear();
201
		unset($html);
202
		return(array_filter($tabledata));
203
	}
204
205
	/**
206
	* Give distance between 2 coordonnates
207
	* @param Float $lat latitude of first point
208
	* @param Float $lon longitude of first point
209
	* @param Float $latc latitude of second point
210
	* @param Float $lonc longitude of second point
211
	* @param String $unit km else no unit used
212
	* @return Float Distance in $unit
213
	*/
214
	public function distance($lat, $lon, $latc, $lonc, $unit = 'km') {
215
		if ($lat == $latc && $lon == $lonc) return 0;
216
		$dist = rad2deg(acos(sin(deg2rad(floatval($lat)))*sin(deg2rad(floatval($latc)))+ cos(deg2rad(floatval($lat)))*cos(deg2rad(floatval($latc)))*cos(deg2rad(floatval($lon)-floatval($lonc)))))*60*1.1515;
217
		if ($unit == "km") {
218
			return round($dist * 1.609344);
219
		} elseif ($unit == "m") {
220
			return round($dist * 1.609344 * 1000);
221
		} elseif ($unit == "mile" || $unit == "mi") {
222
			return round($dist);
223
		} elseif ($unit == "nm") {
224
			return round($dist*0.868976);
225
		} else {
226
			return round($dist);
227
		}
228
	}
229
230
	/**
231
	* Give plunge between 2 altitudes and distance
232
	* @param Float $initial_altitude altitude of first point in m
233
	* @param Float $final_altitude altitude of second point in m
234
	* @param String $distance distance between two points in m
235
	* @return Float plunge
236
	*/
237
	public function plunge($initial_altitude,$final_altitude,$distance) {
238
		$plunge = rad2deg(asin(($final_altitude-$initial_altitude)/$distance));
239
		return $plunge;
240
	}
241
242
	/**
243
	* Give azimuth between 2 coordonnates
244
	* @param Float $lat latitude of first point
245
	* @param Float $lon longitude of first point
246
	* @param Float $latc latitude of second point
247
	* @param Float $lonc longitude of second point
248
	* @return Float Azimuth
249
	*/
250
	public function azimuth($lat, $lon, $latc, $lonc) {
251
		$azimuth = rad2deg(atan(($latc - $lat)/($lonc - $lon)));
252
		return 360+$azimuth;
253
	}
254
	
255
	
256
	/**
257
	* Check is distance realistic
258
	* @param int $timeDifference the time between the reception of both messages
259
	* @param float $distance distance covered
260
	* @return whether distance is realistic
261
	*/
262
	public function withinThreshold ($timeDifference, $distance) {
263
		$x = abs($timeDifference);
264
		$d = abs($distance);
265
		if ($x == 0 || $d == 0) return true;
266
		// may be due to Internet jitter; distance is realistic
267
		if ($x < 0.7 && $d < 2000) return true;
268
		else return $d/$x < 1500*0.27778; // 1500 km/h max
269
	}
270
271
272
	// Check if an array is assoc
273
	public function isAssoc($array)
274
	{
275
		return ($array !== array_values($array));
276
	}
277
278
	public function isInteger($input){
279
	    return(ctype_digit(strval($input)));
280
	}
281
282
283
	public function convertDec($dms,$latlong) {
284
		if ($latlong == 'latitude') {
285
			$deg = substr($dms, 0, 2);
286
			$min = substr($dms, 2, 4);
287
		} else {
288
			$deg = substr($dms, 0, 3);
289
			$min = substr($dms, 3, 5);
290
		}
291
		return $deg+(($min*60)/3600);
292
	}
293
	
294
	public function convertDM($coord,$latlong) {
295
		if ($latlong == 'latitude') {
296
			if ($coord < 0) $NSEW = 'S';
297
			else $NSEW = 'N';
298
		} else {
299
			if ($coord < 0) $NSEW = 'W';
300
			else $NSEW = 'E';
301
		}
302
		$coord = abs($coord);
303
		$deg = floor($coord);
304
		$coord = ($coord-$deg)*60;
305
		$min = $coord;
306
		return array('deg' => $deg,'min' => $min,'NSEW' => $NSEW);
307
	}
308
	
309
	/**
310
	* Copy folder contents
311
	* @param       string   $source    Source path
312
	* @param       string   $dest      Destination path
313
	* @return      bool     Returns true on success, false on failure
314
	*/
315
	public function xcopy($source, $dest)
316
	{
317
		$files = glob($source.'*.*');
318
		foreach($files as $file){
319
			$file_to_go = str_replace($source,$dest,$file);
320
			copy($file, $file_to_go);
321
		}
322
		return true;
323
	}
324
	
325
	/**
326
	* Check if an url exist
327
	* @param	String $url url to check
328
	* @return	bool Return true on succes false on failure
329
	*/
330
	public function urlexist($url){
331
		$headers=get_headers($url);
332
		return stripos($headers[0],"200 OK")?true:false;
333
	}
334
	
335
	/**
336
	* Convert hexa to string
337
	* @param	String $hex data in hexa
338
	* @return	String Return result
339
	*/
340
	public function hex2str($hex) {
341
		$str = '';
342
		$hexln = strlen($hex);
343
		for($i=0;$i<$hexln;$i+=2) $str .= chr(hexdec(substr($hex,$i,2)));
344
		return $str;
345
	}
346
	
347
	/**
348
	* Convert hexa color to rgb
349
	* @param	String $hex data in hexa
350
	* @return	String Return result
351
	*/
352
	public function hex2rgb($hex) {
353
		$hex = str_replace('#','',$hex);
354
		return sscanf($hex, "%02x%02x%02x"); 
355
	}
356
	
357
	public function getHeading($lat1, $lon1, $lat2, $lon2) {
358
		//difference in longitudinal coordinates
359
		$dLon = deg2rad($lon2) - deg2rad($lon1);
360
		//difference in the phi of latitudinal coordinates
361
		$dPhi = log(tan(deg2rad($lat2) / 2 + pi() / 4) / tan(deg2rad($lat1) / 2 + pi() / 4));
362
		//we need to recalculate $dLon if it is greater than pi
363
		if(abs($dLon) > pi()) {
364
			if($dLon > 0) {
365
				$dLon = (2 * pi() - $dLon) * -1;
366
			} else {
367
				$dLon = 2 * pi() + $dLon;
368
			}
369
		}
370
		//return the angle, normalized
371
		return (rad2deg(atan2($dLon, $dPhi)) + 360) % 360;
372
	}
373
	
374
	public function checkLine($lat1,$lon1,$lat2,$lon2,$lat3,$lon3,$approx = 0.15) {
375
		//$a = ($lon2-$lon1)*$lat3+($lat2-$lat1)*$lon3+($lat1*$lon2+$lat2*$lon1);
376
		$a = -($lon2-$lon1);
377
		$b = $lat2 - $lat1;
378
		$c = -($a*$lat1+$b*$lon1);
379
		$d = $a*$lat3+$b*$lon3+$c;
380
		if ($d > -$approx && $d < $approx) return true;
381
		else return false;
382
	}
383
	
384
	public function array_merge_noappend() {
385
		$output = array();
386
		foreach(func_get_args() as $array) {
387
			foreach($array as $key => $value) {
388
				$output[$key] = isset($output[$key]) ?
389
				array_merge($output[$key], $value) : $value;
390
			}
391
		}
392
		return $output;
393
	}
394
	
395
396
	public function arr_diff($arraya, $arrayb) {
397
		foreach ($arraya as $keya => $valuea) {
398
			if (in_array($valuea, $arrayb)) {
399
				unset($arraya[$keya]);
400
			}
401
		}
402
		return $arraya;
403
	}
404
405
	/*
406
	* Check if a key exist in an array
407
	* Come from http://stackoverflow.com/a/19420866
408
	* @param Array array to check
409
	* @param String key to check
410
	* @return Bool true if exist, else false
411
	*/
412
	public function multiKeyExists(array $arr, $key) {
413
		// is in base array?
414
		if (array_key_exists($key, $arr)) {
415
			return true;
416
		}
417
		// check arrays contained in this array
418
		foreach ($arr as $element) {
419
			if (is_array($element)) {
420
				if ($this->multiKeyExists($element, $key)) {
421
					return true;
422
				}
423
			}
424
		}
425
		return false;
426
	}
427
	
428
	/**
429
	* Returns list of available locales
430
	*
431
	* @return array
432
	 */
433
	public function listLocaleDir()
434
	{
435
		$result = array('en');
436
		if (!is_dir('./locale')) {
437
			return $result;
438
		}
439
		$handle = @opendir('./locale');
440
		if ($handle === false) return $result;
441
		while (false !== ($file = readdir($handle))) {
442
			$path = './locale'.'/'.$file.'/LC_MESSAGES/fam.mo';
443
			if ($file != "." && $file != ".." && @file_exists($path)) {
444
				$result[] = $file;
445
			}
446
		}
447
		closedir($handle);
448
		return $result;
449
	}
450
451
	public function nextcoord($latitude, $longitude, $speed, $heading, $archivespeed = 1, $seconds = ''){
452
		global $globalMapRefresh;
453
		if ($seconds == '') {
454
			$distance = ($speed*0.514444*$globalMapRefresh*$archivespeed)/1000;
455
		} else {
456
			$distance = ($speed*0.514444*$seconds*$archivespeed)/1000;
457
		}
458
		$r = 6378;
459
		$latitude = deg2rad($latitude);
460
		$longitude = deg2rad($longitude);
461
		$bearing = deg2rad($heading); 
462
		$latitude2 =  asin( (sin($latitude) * cos($distance/$r)) + (cos($latitude) * sin($distance/$r) * cos($bearing)) );
463
		$longitude2 = $longitude + atan2( sin($bearing)*sin($distance/$r)*cos($latitude), cos($distance/$r)-(sin($latitude)*sin($latitude2)) );
464
		return array('latitude' => number_format(rad2deg($latitude2),5,'.',''),'longitude' => number_format(rad2deg($longitude2),5,'.',''));
465
	}
466
	
467
	public function getCoordfromDistanceBearing($latitude,$longitude,$bearing,$distance) {
468
		// distance in meter
469
		$R = 6378.14;
470
		$latitude1 = $latitude * (M_PI/180);
471
		$longitude1 = $longitude * (M_PI/180);
472
		$brng = $bearing * (M_PI/180);
473
		$d = $distance;
474
475
		$latitude2 = asin(sin($latitude1)*cos($d/$R) + cos($latitude1)*sin($d/$R)*cos($brng));
476
		$longitude2 = $longitude1 + atan2(sin($brng)*sin($d/$R)*cos($latitude1),cos($d/$R)-sin($latitude1)*sin($latitude2));
477
478
		$latitude2 = $latitude2 * (180/M_PI);
479
		$longitude2 = $longitude2 * (180/M_PI);
480
481
		$flat = round ($latitude2,6);
482
		$flong = round ($longitude2,6);
483
/*
484
		$dx = $distance*cos($bearing);
485
		$dy = $distance*sin($bearing);
486
		$dlong = $dx/(111320*cos($latitude));
487
		$dlat = $dy/110540;
488
		$flong = $longitude + $dlong;
489
		$flat = $latitude + $dlat;
490
*/
491
		return array('latitude' => $flat,'longitude' => $flong);
492
	}
493
494
	/**
495
	 * GZIPs a file on disk (appending .gz to the name)
496
	 *
497
	 * From http://stackoverflow.com/questions/6073397/how-do-you-create-a-gz-file-using-php
498
	 * Based on function by Kioob at:
499
	 * http://www.php.net/manual/en/function.gzwrite.php#34955
500
	 * 
501
	 * @param string $source Path to file that should be compressed
502
	 * @param integer $level GZIP compression level (default: 9)
503
	 * @return string New filename (with .gz appended) if success, or false if operation fails
504
	 */
505
	public function gzCompressFile($source, $level = 9){ 
506
		$dest = $source . '.gz'; 
507
		$mode = 'wb' . $level; 
508
		$error = false; 
509
		if ($fp_out = gzopen($dest, $mode)) { 
510
			if ($fp_in = fopen($source,'rb')) { 
511
				while (!feof($fp_in)) 
512
					gzwrite($fp_out, fread($fp_in, 1024 * 512)); 
513
				fclose($fp_in); 
514
			} else {
515
				$error = true; 
516
			}
517
			gzclose($fp_out); 
518
		} else {
519
			$error = true; 
520
		}
521
		if ($error)
522
			return false; 
523
		else
524
			return $dest; 
525
	} 
526
	
527
	public function remove_accents($string) {
528
		if ( !preg_match('/[\x80-\xff]/', $string) ) return $string;
529
		$chars = array(
530
		    // Decompositions for Latin-1 Supplement
531
		    chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
532
		    chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
533
		    chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
534
		    chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
535
		    chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
536
		    chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
537
		    chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
538
		    chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
539
		    chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
540
		    chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
541
		    chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
542
		    chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
543
		    chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
544
		    chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
545
		    chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
546
		    chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
547
		    chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
548
		    chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
549
		    chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
550
		    chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
551
		    chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
552
		    chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
553
		    chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
554
		    chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
555
		    chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
556
		    chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
557
		    chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
558
		    chr(195).chr(191) => 'y',
559
		    // Decompositions for Latin Extended-A
560
		    chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
561
		    chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
562
		    chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
563
		    chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
564
		    chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
565
		    chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
566
		    chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
567
		    chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
568
		    chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
569
		    chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
570
		    chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
571
		    chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
572
		    chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
573
		    chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
574
		    chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
575
		    chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
576
		    chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
577
		    chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
578
		    chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
579
		    chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
580
		    chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
581
		    chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
582
		    chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
583
		    chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
584
		    chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
585
		    chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
586
		    chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
587
		    chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
588
		    chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
589
		    chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
590
		    chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
591
		    chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
592
		    chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
593
		    chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
594
		    chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
595
		    chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
596
		    chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
597
		    chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
598
		    chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
599
		    chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
600
		    chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
601
		    chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
602
		    chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
603
		    chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
604
		    chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
605
		    chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
606
		    chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
607
		    chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
608
		    chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
609
		    chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
610
		    chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
611
		    chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
612
		    chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
613
		    chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
614
		    chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
615
		    chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
616
		    chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
617
		    chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
618
		    chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
619
		    chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
620
		    chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
621
		    chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
622
		    chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
623
		    chr(197).chr(190) => 'z', chr(197).chr(191) => 's'
624
		);
625
		$string = strtr($string, $chars);
626
		return $string;
627
	}
628
	
629
	/*
630
	* Extract int from a string
631
	* Come from http://php.net/manual/fr/function.intval.php comment by michiel ed thalent nl
632
	*
633
	* @param String Input string
634
	* @return Integer integer from the string
635
	*/
636
	public function str2int($string, $concat = false) {
637
		$length = strlen($string);    
638
		for ($i = 0, $int = '', $concat_flag = true; $i < $length; $i++) {
639
			if (is_numeric($string[$i]) && $concat_flag) {
640
				$int .= $string[$i];
641
			} elseif(!$concat && $concat_flag && strlen($int) > 0) {
642
				$concat_flag = false;
643
			}
644
		}
645
		return (int) $int;
646
	}
647
	
648
	public function create_socket($host, $port, &$errno, &$errstr) {
649
		$ip = gethostbyname($host);
650
		$s = socket_create(AF_INET, SOCK_STREAM, 0);
651
		$r = @socket_connect($s, $ip, $port);
652
		if (!socket_set_nonblock($s)) echo "Unable to set nonblock on socket\n";
653
		if ($r || socket_last_error() == 114 || socket_last_error() == 115) {
654
			return $s;
655
		}
656
		$errno = socket_last_error($s);
657
		$errstr = socket_strerror($errno);
658
		socket_close($s);
659
		return false;
660
	}
661
662
	public function create_socket_udp($host, $port, &$errno, &$errstr) {
663
		$ip = gethostbyname($host);
664
		$s = socket_create(AF_INET, SOCK_DGRAM, 0);
665
		$r = @socket_bind($s, $ip, $port);
666
		if ($r || socket_last_error() == 114 || socket_last_error() == 115) {
667
			return $s;
668
		}
669
		$errno = socket_last_error($s);
670
		$errstr = socket_strerror($errno);
671
		socket_close($s);
672
		return false;
673
	}
674
675
	public function getUserIP() { 
676
		$client = @$_SERVER['HTTP_CLIENT_IP'];
677
		$forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
678
		return filter_var($client, FILTER_VALIDATE_IP) ? $client : filter_var($forward, FILTER_VALIDATE_IP) ? $forward : $_SERVER['REMOTE_ADDR']; 
679
	}
680
	public function replace_mb_substr($string, $offset, $length)
681
	{
682
		if (!function_exists('mb_substr')) {
683
			$arr = preg_split("//u", $string);
684
			$slice = array_slice($arr, $offset + 1, $length);
685
			return implode("", $slice);
686
		} else {
687
			return mb_substr($string,$offset,$length,'UTF-8');
688
		}
689
	}
690
691
	// Come from comment : http://php.net/manual/fr/function.is-writable.php#73596
692
	public function is__writable($path) {
693
		//will work in despite of Windows ACLs bug
694
		//NOTE: use a trailing slash for folders!!!
695
		//see http://bugs.php.net/bug.php?id=27609
696
		//see http://bugs.php.net/bug.php?id=30931
697
		if ($path{strlen($path)-1}=='/') // recursively return a temporary file path
698
			return $this->is__writable($path.uniqid(mt_rand()).'.tmp');
699
		else if (is_dir($path))
700
			return $this->is__writable($path.'/'.uniqid(mt_rand()).'.tmp');
701
		// check tmp file for read/write capabilities
702
		$rm = file_exists($path);
703
		$f = @fopen($path, 'a');
704
		if ($f===false)
705
			return false;
706
		fclose($f);
707
		if (!$rm)
708
			unlink($path);
709
		return true;
710
	}
711
}
712
?>