Completed
Push — master ( 9adbe5...64358c )
by Yannick
33:16
created

Common::download()   C

Complexity

Conditions 10
Paths 24

Size

Total Lines 23
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 19
nc 24
nop 3
dl 0
loc 23
rs 5.6534
c 0
b 0
f 0

How to fix   Complexity   

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:

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 = '', $sizelimit = false) {
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
		if ($sizelimit === true) {
69
			curl_setopt($ch, CURLOPT_BUFFERSIZE, 128);
70
			curl_setopt($ch, CURLOPT_NOPROGRESS, false);
71
			curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, function($curlr,$downloadsize, $downloaded, $uploadsize, $uploaded){
0 ignored issues
show
Unused Code introduced by
The parameter $uploadsize is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $uploaded is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

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