Completed
Push — master ( f32ba6...d43b85 )
by Yannick
30:30
created

Common::convertDecLatLong()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 22
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 18
nc 6
nop 1
dl 0
loc 22
rs 8.6737
c 0
b 0
f 0
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, $async = 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
		} elseif ($type != 'get' && $type != '') curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $type);
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
		if ($async) {
76
			curl_setopt($ch, CURLOPT_NOSIGNAL, 1); //to timeout immediately if the value is < 1000 ms
77
			curl_setopt($ch, CURLOPT_TIMEOUT_MS, 50);
78
		}
79
		$result = curl_exec($ch);
80
		$info = curl_getinfo($ch);
81
		curl_close($ch);
82
		if ($info['http_code'] == '503' && strstr($result,'DDoS protection by CloudFlare')) {
83
			echo "Cloudflare Detected\n";
84
			require_once(dirname(__FILE__).'/libs/cloudflare-bypass/libraries/cloudflareClass.php');
85
			$useragent = UAgent::random();
86
			cloudflare::useUserAgent($useragent);
87
			if ($clearanceCookie = cloudflare::bypass($url)) {
88
				return $this->getData($url,'get',$data,$headers,$clearanceCookie,$referer,$timeout,$useragent);
89
			}
90
		} else {
91
			return $result;
92
		}
93
	}
94
	
95
	private function curlResponseHeaderCallback($ch, $headerLine) {
96
		//global $cookies;
97
		$cookies = array();
98
		if (preg_match('/^Set-Cookie:\s*([^;]*)/mi', $headerLine, $cookie) == 1)
99
			$cookies[] = $cookie;
100
		return strlen($headerLine); // Needed by curl
101
	}
102
103
	public static function download($url, $file, $referer = '') {
104
		global $globalDebug, $globalProxy, $globalForceIPv4;
105
		$fp = fopen($file, 'w');
106
		$ch = curl_init();
107
		curl_setopt($ch, CURLOPT_URL, $url);
108
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
109
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
110
		if ($referer != '') curl_setopt($ch, CURLOPT_REFERER, $referer);
111
		if (isset($globalForceIPv4) && $globalForceIPv4) {
112
			if (defined('CURLOPT_IPRESOLVE') && defined('CURL_IPRESOLVE_V4')){
113
				curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
114
			}
115
		}
116
		if (isset($globalProxy) && $globalProxy != '') {
117
			curl_setopt($ch, CURLOPT_PROXY, $globalProxy);
118
		}
119
		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');
120
		curl_setopt($ch, CURLOPT_FILE, $fp);
121
		curl_exec($ch);
122
		if (curl_errno($ch) && $globalDebug) echo 'Download error: '.curl_error($ch);
123
		curl_close($ch);
124
		fclose($fp);
125
	}
126
127
	public static function gunzip($in_file,$out_file_name = '') {
128
		//echo $in_file.' -> '.$out_file_name."\n";
129
		$buffer_size = 4096; // read 4kb at a time
130
		if ($out_file_name == '') $out_file_name = str_replace('.gz', '', $in_file); 
131
		if ($in_file != '' && file_exists($in_file)) {
132
			// PHP version of Ubuntu use gzopen64 instead of gzopen
133
			if (function_exists('gzopen')) $file = gzopen($in_file,'rb');
134
			elseif (function_exists('gzopen64')) $file = gzopen64($in_file,'rb');
135
			else {
136
				echo 'gzopen not available';
137
				die;
138
			}
139
			$out_file = fopen($out_file_name, 'wb'); 
140
			while(!gzeof($file)) {
141
				fwrite($out_file, gzread($file, $buffer_size));
142
			}  
143
			fclose($out_file);
144
			gzclose($file);
145
		}
146
	}
147
148
	public static function bunzip2($in_file,$out_file_name = '') {
149
		//echo $in_file.' -> '.$out_file_name."\n";
150
		$buffer_size = 4096; // read 4kb at a time
151
		if ($out_file_name == '') $out_file_name = str_replace('.bz2', '', $in_file); 
152
		if ($in_file != '' && file_exists($in_file)) {
153
			// PHP version of Ubuntu use gzopen64 instead of gzopen
154
			if (function_exists('bzopen')) $file = bzopen($in_file,'rb');
155
			else {
156
				echo 'bzopen not available';
157
				die;
158
			}
159
			$out_file = fopen($out_file_name, 'wb'); 
160
			while(!feof($file)) {
161
				fwrite($out_file, bzread($file, $buffer_size));
162
			}  
163
			fclose($out_file);
164
			bzclose($file);
165
		}
166
	}
167
168
	/**
169
	* Convert a HTML table to an array
170
	* @param String $data HTML page
171
	* @return Array array of the tables in HTML page
172
	*/
173
	public function table2array($data) {
174
		if (!is_string($data)) return array();
175
		if ($data == '') return array();
176
		$html = str_get_html($data);
177
		if ($html === false) return array();
178
		$tabledata=array();
179
		foreach($html->find('tr') as $element)
180
		{
181
			$td = array();
182
			foreach( $element->find('th') as $row)
183
			{
184
				$td [] = trim($row->plaintext);
185
			}
186
			$td=array_filter($td);
187
			$tabledata[] = $td;
188
189
			$td = array();
190
			$tdi = array();
191
			foreach( $element->find('td') as $row)
192
			{
193
				$td [] = trim($row->plaintext);
194
				$tdi [] = trim($row->innertext);
195
			}
196
			$td=array_filter($td);
197
			$tdi=array_filter($tdi);
198
			$tabledata[]=array_merge($td,$tdi);
199
		}
200
		$html->clear();
201
		unset($html);
202
		return(array_filter($tabledata));
203
	}
204
	
205
	/**
206
	* Convert <p> part of a HTML page to an array
207
	* @param String $data HTML page
208
	* @return Array array of the <p> in HTML page
209
	*/
210
	public function text2array($data) {
211
		$html = str_get_html($data);
212
		if ($html === false) return array();
213
		$tabledata=array();
214
		foreach($html->find('p') as $element)
215
		{
216
			$tabledata [] = trim($element->plaintext);
217
		}
218
		$html->clear();
219
		unset($html);
220
		return(array_filter($tabledata));
221
	}
222
223
	/**
224
	* Give distance between 2 coordonnates
225
	* @param Float $lat latitude of first point
226
	* @param Float $lon longitude of first point
227
	* @param Float $latc latitude of second point
228
	* @param Float $lonc longitude of second point
229
	* @param String $unit km else no unit used
230
	* @return Float Distance in $unit
231
	*/
232
	public function distance($lat, $lon, $latc, $lonc, $unit = 'km') {
233
		if ($lat == $latc && $lon == $lonc) return 0;
234
		$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;
235
		if ($unit == "km") {
236
			return round($dist * 1.609344);
237
		} elseif ($unit == "m") {
238
			return round($dist * 1.609344 * 1000);
239
		} elseif ($unit == "mile" || $unit == "mi") {
240
			return round($dist);
241
		} elseif ($unit == "nm") {
242
			return round($dist*0.868976);
243
		} else {
244
			return round($dist);
245
		}
246
	}
247
248
	/**
249
	* Give plunge between 2 altitudes and distance
250
	* @param Float $initial_altitude altitude of first point in m
251
	* @param Float $final_altitude altitude of second point in m
252
	* @param String $distance distance between two points in m
253
	* @return Float plunge
254
	*/
255
	public function plunge($initial_altitude,$final_altitude,$distance) {
256
		$plunge = rad2deg(asin(($final_altitude-$initial_altitude)/$distance));
257
		/*
258
		$siter = 6378137.0 + $initial_altitude;
259
		$planer = 6378137.0 + $final_altitude;
260
		$airdist = sqrt($siter-$siter + $planer*$planer - 2*$siter*$planer*cos($distance/6378137.0));
261
		echo 'airdist:'.$airdist;
262
		$plunge = rad2deg(asin(($planer*$planer - $siter*$siter - $airdist*$airdist)/(2*$siter+$distance)));
263
		*/
264
		return $plunge;
265
	}
266
267
	/**
268
	* Give azimuth between 2 coordonnates
269
	* @param Float $lat latitude of first point
270
	* @param Float $lon longitude of first point
271
	* @param Float $latc latitude of second point
272
	* @param Float $lonc longitude of second point
273
	* @return Float Azimuth
274
	*/
275
	public function azimuth($lat, $lon, $latc, $lonc) {
276
		$dX = $latc - $lat;
277
		$dY = $lonc - $lon;
278
		$azimuth = rad2deg(atan2($dY,$dX));
279
		if ($azimuth < 0) return $azimuth+360;
280
		return $azimuth;
281
	}
282
	
283
	
284
	/**
285
	* Check is distance realistic
286
	* @param int $timeDifference the time between the reception of both messages
287
	* @param float $distance distance covered
288
	* @return whether distance is realistic
289
	*/
290
	public function withinThreshold ($timeDifference, $distance) {
291
		$x = abs($timeDifference);
292
		$d = abs($distance);
293
		if ($x == 0 || $d == 0) return true;
294
		// may be due to Internet jitter; distance is realistic
295
		if ($x < 0.7 && $d < 2000) return true;
296
		else return $d/$x < 1500*0.27778; // 1500 km/h max
297
	}
298
299
300
	// Check if an array is assoc
301
	public function isAssoc($array)
302
	{
303
		return ($array !== array_values($array));
304
	}
305
306
	public function isInteger($input){
307
		//return(ctype_digit(strval($input)));
308
		return preg_match('/^-?[0-9]+$/', (string)$input) ? true : false;
309
	}
310
311
312
	public function convertDec($dms,$latlong) {
313
		if ($latlong == 'latitude') {
314
			$deg = substr($dms, 0, 2);
315
			$min = substr($dms, 2, 4);
316
		} else {
317
			$deg = substr($dms, 0, 3);
318
			$min = substr($dms, 3, 5);
319
		}
320
		return $deg+(($min*60)/3600);
321
	}
322
	
323
	public function convertDecLatLong($coord) {
324
		//N43°36.763' W5°46.845'
325
		$coords = explode(' ',$coord);
326
		$latitude = '';
327
		$longitude = '';
328
		foreach ($coords as $latlong) {
329
			$type = substr($latlong,0,1);
330
			$degmin = explode('°',substr($latlong,1,-1));
331
			$deg = $degmin[0];
332
			$min = $degmin[1];
333
			if ($type == 'N') {
334
				$latitude = $deg+(($min*60)/3600);
335
			} elseif ($type == 'S') {
336
				$latitude = -($deg+(($min*60)/3600));
337
			} elseif ($type == 'E') {
338
				$longitude = ($deg+(($min*60)/3600));
339
			} elseif ($type == 'W') {
340
				$longitude = -($deg+(($min*60)/3600));
341
			}
342
		}
343
		return array('latitude' => round($latitude,5),'longitude' => round($longitude,5));
344
	}
345
	
346
	public function convertDM($coord,$latlong) {
347
		if ($latlong == 'latitude') {
348
			if ($coord < 0) $NSEW = 'S';
349
			else $NSEW = 'N';
350
		} else {
351
			if ($coord < 0) $NSEW = 'W';
352
			else $NSEW = 'E';
353
		}
354
		$coord = abs($coord);
355
		$deg = floor($coord);
356
		$coord = ($coord-$deg)*60;
357
		$min = $coord;
358
		return array('deg' => $deg,'min' => $min,'NSEW' => $NSEW);
359
	}
360
	
361
	/**
362
	* Copy folder contents
363
	* @param       string   $source    Source path
364
	* @param       string   $dest      Destination path
365
	* @return      bool     Returns true on success, false on failure
366
	*/
367
	public function xcopy($source, $dest)
368
	{
369
		$files = glob($source.'*.*');
370
		foreach($files as $file){
371
			$file_to_go = str_replace($source,$dest,$file);
372
			copy($file, $file_to_go);
373
		}
374
		return true;
375
	}
376
	
377
	/**
378
	* Check if an url exist
379
	* @param	String $url url to check
380
	* @return	bool Return true on succes false on failure
381
	*/
382
	public function urlexist($url){
383
		$headers=get_headers($url);
384
		return stripos($headers[0],"200 OK")?true:false;
385
	}
386
	
387
	/**
388
	* Convert hexa to string
389
	* @param	String $hex data in hexa
390
	* @return	String Return result
391
	*/
392
	public function hex2str($hex) {
393
		$str = '';
394
		$hexln = strlen($hex);
395
		for($i=0;$i<$hexln;$i+=2) $str .= chr(hexdec(substr($hex,$i,2)));
396
		return $str;
397
	}
398
	
399
	/**
400
	* Convert hexa color to rgb
401
	* @param	String $hex data in hexa
402
	* @return	String Return result
403
	*/
404
	public function hex2rgb($hex) {
405
		$hex = str_replace('#','',$hex);
406
		return sscanf($hex, "%02x%02x%02x"); 
407
	}
408
	
409
	public function getHeading($lat1, $lon1, $lat2, $lon2) {
410
		//difference in longitudinal coordinates
411
		$dLon = deg2rad($lon2) - deg2rad($lon1);
412
		//difference in the phi of latitudinal coordinates
413
		$dPhi = log(tan(deg2rad($lat2) / 2 + M_PI / 4) / tan(deg2rad($lat1) / 2 + M_PI / 4));
414
		//we need to recalculate $dLon if it is greater than pi
415
		if(abs($dLon) > M_PI) {
416
			if($dLon > 0) {
417
				$dLon = (2 * M_PI - $dLon) * -1;
418
			} else {
419
				$dLon = 2 * M_PI + $dLon;
420
			}
421
		}
422
		//return the angle, normalized
423
		return (rad2deg(atan2($dLon, $dPhi)) + 360) % 360;
424
	}
425
426
	public function checkLine($lat1,$lon1,$lat2,$lon2,$lat3,$lon3,$approx = 0.15) {
427
		//$a = ($lon2-$lon1)*$lat3+($lat2-$lat1)*$lon3+($lat1*$lon2+$lat2*$lon1);
428
		$a = -($lon2-$lon1);
429
		$b = $lat2 - $lat1;
430
		$c = -($a*$lat1+$b*$lon1);
431
		$d = $a*$lat3+$b*$lon3+$c;
432
		if ($d > -$approx && $d < $approx) return true;
433
		else return false;
434
	}
435
	
436
	public function array_merge_noappend() {
437
		$output = array();
438
		foreach(func_get_args() as $array) {
439
			foreach($array as $key => $value) {
440
				$output[$key] = isset($output[$key]) ?
441
				array_merge($output[$key], $value) : $value;
442
			}
443
		}
444
		return $output;
445
	}
446
	
447
448
	public function arr_diff($arraya, $arrayb) {
449
		foreach ($arraya as $keya => $valuea) {
450
			if (in_array($valuea, $arrayb)) {
451
				unset($arraya[$keya]);
452
			}
453
		}
454
		return $arraya;
455
	}
456
457
	/*
458
	* Check if a key exist in an array
459
	* Come from http://stackoverflow.com/a/19420866
460
	* @param Array array to check
461
	* @param String key to check
462
	* @return Bool true if exist, else false
463
	*/
464
	public function multiKeyExists(array $arr, $key) {
465
		// is in base array?
466
		if (array_key_exists($key, $arr)) {
467
			return true;
468
		}
469
		// check arrays contained in this array
470
		foreach ($arr as $element) {
471
			if (is_array($element)) {
472
				if ($this->multiKeyExists($element, $key)) {
473
					return true;
474
				}
475
			}
476
		}
477
		return false;
478
	}
479
	
480
	/**
481
	* Returns list of available locales
482
	*
483
	* @return array
484
	 */
485
	public function listLocaleDir()
486
	{
487
		$result = array('en');
488
		if (!is_dir('./locale')) {
489
			return $result;
490
		}
491
		$handle = @opendir('./locale');
492
		if ($handle === false) return $result;
493
		while (false !== ($file = readdir($handle))) {
494
			$path = './locale'.'/'.$file.'/LC_MESSAGES/fam.mo';
495
			if ($file != "." && $file != ".." && @file_exists($path)) {
496
				$result[] = $file;
497
			}
498
		}
499
		closedir($handle);
500
		return $result;
501
	}
502
503
	public function nextcoord($latitude, $longitude, $speed, $heading, $archivespeed = 1, $seconds = ''){
504
		global $globalMapRefresh;
505
		if ($seconds == '') {
506
			$distance = ($speed*0.514444*$globalMapRefresh*$archivespeed)/1000;
507
		} else {
508
			$distance = ($speed*0.514444*$seconds*$archivespeed)/1000;
509
		}
510
		$r = 6378;
511
		$latitude = deg2rad($latitude);
512
		$longitude = deg2rad($longitude);
513
		$bearing = deg2rad($heading); 
514
		$latitude2 =  asin( (sin($latitude) * cos($distance/$r)) + (cos($latitude) * sin($distance/$r) * cos($bearing)) );
515
		$longitude2 = $longitude + atan2( sin($bearing)*sin($distance/$r)*cos($latitude), cos($distance/$r)-(sin($latitude)*sin($latitude2)) );
516
		return array('latitude' => number_format(rad2deg($latitude2),5,'.',''),'longitude' => number_format(rad2deg($longitude2),5,'.',''));
517
	}
518
	
519
	public function getCoordfromDistanceBearing($latitude,$longitude,$bearing,$distance) {
520
		// distance in meter
521
		$R = 6378.14;
522
		$latitude1 = $latitude * (M_PI/180);
523
		$longitude1 = $longitude * (M_PI/180);
524
		$brng = $bearing * (M_PI/180);
525
		$d = $distance;
526
527
		$latitude2 = asin(sin($latitude1)*cos($d/$R) + cos($latitude1)*sin($d/$R)*cos($brng));
528
		$longitude2 = $longitude1 + atan2(sin($brng)*sin($d/$R)*cos($latitude1),cos($d/$R)-sin($latitude1)*sin($latitude2));
529
530
		$latitude2 = $latitude2 * (180/M_PI);
531
		$longitude2 = $longitude2 * (180/M_PI);
532
533
		$flat = round ($latitude2,6);
534
		$flong = round ($longitude2,6);
535
/*
536
		$dx = $distance*cos($bearing);
537
		$dy = $distance*sin($bearing);
538
		$dlong = $dx/(111320*cos($latitude));
539
		$dlat = $dy/110540;
540
		$flong = $longitude + $dlong;
541
		$flat = $latitude + $dlat;
542
*/
543
		return array('latitude' => $flat,'longitude' => $flong);
544
	}
545
546
	/**
547
	 * GZIPs a file on disk (appending .gz to the name)
548
	 *
549
	 * From http://stackoverflow.com/questions/6073397/how-do-you-create-a-gz-file-using-php
550
	 * Based on function by Kioob at:
551
	 * http://www.php.net/manual/en/function.gzwrite.php#34955
552
	 * 
553
	 * @param string $source Path to file that should be compressed
554
	 * @param integer $level GZIP compression level (default: 9)
555
	 * @return string New filename (with .gz appended) if success, or false if operation fails
556
	 */
557
	public function gzCompressFile($source, $level = 9){ 
558
		$dest = $source . '.gz'; 
559
		$mode = 'wb' . $level; 
560
		$error = false; 
561
		if ($fp_out = gzopen($dest, $mode)) { 
562
			if ($fp_in = fopen($source,'rb')) { 
563
				while (!feof($fp_in)) 
564
					gzwrite($fp_out, fread($fp_in, 1024 * 512)); 
565
				fclose($fp_in); 
566
			} else {
567
				$error = true; 
568
			}
569
			gzclose($fp_out); 
570
		} else {
571
			$error = true; 
572
		}
573
		if ($error)
574
			return false; 
575
		else
576
			return $dest; 
577
	} 
578
	
579
	public function remove_accents($string) {
580
		if ( !preg_match('/[\x80-\xff]/', $string) ) return $string;
581
		$chars = array(
582
		    // Decompositions for Latin-1 Supplement
583
		    chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
584
		    chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
585
		    chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
586
		    chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
587
		    chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
588
		    chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
589
		    chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
590
		    chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
591
		    chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
592
		    chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
593
		    chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
594
		    chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
595
		    chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
596
		    chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
597
		    chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
598
		    chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
599
		    chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
600
		    chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
601
		    chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
602
		    chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
603
		    chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
604
		    chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
605
		    chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
606
		    chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
607
		    chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
608
		    chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
609
		    chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
610
		    chr(195).chr(191) => 'y',
611
		    // Decompositions for Latin Extended-A
612
		    chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
613
		    chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
614
		    chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
615
		    chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
616
		    chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
617
		    chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
618
		    chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
619
		    chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
620
		    chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
621
		    chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
622
		    chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
623
		    chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
624
		    chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
625
		    chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
626
		    chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
627
		    chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
628
		    chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
629
		    chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
630
		    chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
631
		    chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
632
		    chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
633
		    chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
634
		    chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
635
		    chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
636
		    chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
637
		    chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
638
		    chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
639
		    chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
640
		    chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
641
		    chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
642
		    chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
643
		    chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
644
		    chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
645
		    chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
646
		    chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
647
		    chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
648
		    chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
649
		    chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
650
		    chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
651
		    chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
652
		    chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
653
		    chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
654
		    chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
655
		    chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
656
		    chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
657
		    chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
658
		    chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
659
		    chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
660
		    chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
661
		    chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
662
		    chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
663
		    chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
664
		    chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
665
		    chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
666
		    chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
667
		    chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
668
		    chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
669
		    chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
670
		    chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
671
		    chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
672
		    chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
673
		    chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
674
		    chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
675
		    chr(197).chr(190) => 'z', chr(197).chr(191) => 's'
676
		);
677
		$string = strtr($string, $chars);
678
		return $string;
679
	}
680
	
681
	/*
682
	* Extract int from a string
683
	* Come from http://php.net/manual/fr/function.intval.php comment by michiel ed thalent nl
684
	*
685
	* @param String Input string
686
	* @return Integer integer from the string
687
	*/
688
	public function str2int($string, $concat = false) {
689
		$length = strlen($string);    
690
		for ($i = 0, $int = '', $concat_flag = true; $i < $length; $i++) {
691
			if (is_numeric($string[$i]) && $concat_flag) {
692
				$int .= $string[$i];
693
			} elseif(!$concat && $concat_flag && strlen($int) > 0) {
694
				$concat_flag = false;
695
			}
696
		}
697
		return (int) $int;
698
	}
699
	
700
	public function create_socket($host, $port, &$errno, &$errstr) {
701
		$ip = gethostbyname($host);
702
		$s = socket_create(AF_INET, SOCK_STREAM, 0);
703
		$r = @socket_connect($s, $ip, $port);
704
		if (!socket_set_nonblock($s)) echo "Unable to set nonblock on socket\n";
705
		if ($r || socket_last_error() == 114 || socket_last_error() == 115) {
706
			return $s;
707
		}
708
		$errno = socket_last_error($s);
709
		$errstr = socket_strerror($errno);
710
		socket_close($s);
711
		return false;
712
	}
713
714
	public function create_socket_udp($host, $port, &$errno, &$errstr) {
715
		$ip = gethostbyname($host);
716
		$s = socket_create(AF_INET, SOCK_DGRAM, 0);
717
		$r = @socket_bind($s, $ip, $port);
718
		if ($r || socket_last_error() == 114 || socket_last_error() == 115) {
719
			return $s;
720
		}
721
		$errno = socket_last_error($s);
722
		$errstr = socket_strerror($errno);
723
		socket_close($s);
724
		return false;
725
	}
726
727
	public function getUserIP() { 
728
		$client = @$_SERVER['HTTP_CLIENT_IP'];
729
		$forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
730
		return filter_var($client, FILTER_VALIDATE_IP) ? $client : filter_var($forward, FILTER_VALIDATE_IP) ? $forward : $_SERVER['REMOTE_ADDR']; 
731
	}
732
	public function replace_mb_substr($string, $offset, $length)
733
	{
734
		if (!function_exists('mb_substr')) {
735
			$arr = preg_split("//u", $string);
736
			$slice = array_slice($arr, $offset + 1, $length);
737
			return implode("", $slice);
738
		} else {
739
			return mb_substr($string,$offset,$length,'UTF-8');
740
		}
741
	}
742
743
	// Come from comment : http://php.net/manual/fr/function.is-writable.php#73596
744
	public function is__writable($path) {
745
		//will work in despite of Windows ACLs bug
746
		//NOTE: use a trailing slash for folders!!!
747
		//see http://bugs.php.net/bug.php?id=27609
748
		//see http://bugs.php.net/bug.php?id=30931
749
		if ($path{strlen($path)-1}=='/') // recursively return a temporary file path
750
			return $this->is__writable($path.uniqid(mt_rand()).'.tmp');
751
		else if (is_dir($path))
752
			return $this->is__writable($path.'/'.uniqid(mt_rand()).'.tmp');
753
		// check tmp file for read/write capabilities
754
		$rm = file_exists($path);
755
		$f = @fopen($path, 'a');
756
		if ($f===false)
757
			return false;
758
		fclose($f);
759
		if (!$rm)
760
			unlink($path);
761
		return true;
762
	}
763
	
764
	/*
765
	 * Great circle route
766
	 * Translated to PHP from javascript version of https://github.com/springmeyer/arc.js
767
	 * @param Float $begin_lat Latitude of origin point
768
	 * @param Float $begin_lon Longitude of origin point
769
	 * @param Float $end_lat Latitude of final point
770
	 * @param Float $end_lon Longitude of final point
771
	 * @param Integer $nbpts Number of intermediate vertices desired
772
	 * @param Integer $offset Controls the likelyhood that lines will be split which cross the dateline
773
	 * @return Array Coordinate of the route
774
	*/
775
	public function greatcircle($begin_lat,$begin_lon,$end_lat,$end_lon,$nbpts = 20, $offset = 10) {
776
		if ($nbpts <= 2) return array(array($begin_lon,$begin_lat),array($end_lon,$end_lat));
777
		$sx = deg2rad($begin_lon);
778
		$sy = deg2rad($begin_lat);
779
		$ex = deg2rad($end_lon);
780
		$ey = deg2rad($end_lat);
781
		$w = $sx - $ex;
782
		$h = $sy - $ey;
783
		$z = pow(sin($h/2.0),2) + cos($sy)*cos($ey)*pow(sin($w/2.0),2);
784
		$g = 2.0*asin(sqrt($z));
785
		if ($g == M_PI || is_nan($g)) return array(array($begin_lon,$begin_lat),array($end_lon,$end_lat));
786
		$first_pass = array();
787
		$delta = 1.0/($nbpts-1);
788
		for ($i =0; $i < $nbpts; ++$i) {
789
			$step = $delta*$i;
790
			$A = sin((1 - $step) * $g) / sin($g);
791
			$B = sin($step * $g) / sin($g);
792
			$x = $A * cos($sy) * cos($sx) + $B * cos($ey) * cos($ex);
793
			$y = $A * cos($sy) * sin($sx) + $B * cos($ey) * sin($ex);
794
			$z = $A * sin($sy) + $B * sin($ey);
795
			$lat = rad2deg(atan2($z, sqrt(pow($x, 2) + pow($y, 2))));
796
			$lon = rad2deg(atan2($y, $x));
797
			$first_pass[] = array($lon,$lat);
798
		}
799
		$bHasBigDiff = false;
800
		$dfMaxSmallDiffLong = 0;
801
		// from http://www.gdal.org/ogr2ogr.html
802
		// -datelineoffset:
803
		// (starting with GDAL 1.10) offset from dateline in degrees (default long. = +/- 10deg, geometries within 170deg to -170deg will be splited)
804
		$dfDateLineOffset = $offset;
805
		$dfLeftBorderX = 180 - $dfDateLineOffset;
806
		$dfRightBorderX = -180 + $dfDateLineOffset;
807
		$dfDiffSpace = 360 - $dfDateLineOffset;
808
		
809
		// https://github.com/OSGeo/gdal/blob/7bfb9c452a59aac958bff0c8386b891edf8154ca/gdal/ogr/ogrgeometryfactory.cpp#L2342
810
		$first_pass_ln = count($first_pass);
811
		for ($j = 1; $j < $first_pass_ln; ++$j) {
812
			$dfPrevX = $first_pass[$j-1][0];
813
			$dfX = $first_pass[$j][0];
814
			$dfDiffLong = abs($dfX - $dfPrevX);
815
			if ($dfDiffLong > $dfDiffSpace &&
816
			    (($dfX > $dfLeftBorderX && $dfPrevX < $dfRightBorderX) || ($dfPrevX > $dfLeftBorderX && $dfX < $dfRightBorderX))) 
817
			{
818
				$bHasBigDiff = true;
819
			} else if ($dfDiffLong > $dfMaxSmallDiffLong) {
820
				$dfMaxSmallDiffLong = $dfDiffLong;
821
			}
822
		}
823
		$poMulti = array();
824
		$first_pass_ln = count($first_pass);
825
		if ($bHasBigDiff && $dfMaxSmallDiffLong < $dfDateLineOffset) {
826
			$poNewLS = array();
827
			//$poMulti[] = $poNewLS;
828
			for ($k = 0; $k < $first_pass_ln; ++$k) {
829
				$dfX0 = floatval($first_pass[$k][0]);
830
				if ($k > 0 &&  abs($dfX0 - $first_pass[$k-1][0]) > $dfDiffSpace) {
831
					$dfX1 = floatval($first_pass[$k-1][0]);
832
					$dfY1 = floatval($first_pass[$k-1][1]);
833
					$dfX2 = floatval($first_pass[$k][0]);
834
					$dfY2 = floatval($first_pass[$k][1]);
835
					if ($dfX1 > -180 && $dfX1 < $dfRightBorderX && $dfX2 == 180 &&
836
					    $k+1 < count($first_pass) &&
837
					    $first_pass[$k-1][0] > -180 && $first_pass[$k-1][0] < $dfRightBorderX)
838
					{
839
						$poNewLS[] = array(-180, $first_pass[$k][1]);
840
						$k++;
841
						//echo 'here';
842
						$poNewLS[] = array($first_pass[$k][0], $first_pass[$k][1]);
843
						continue;
844
					} else if ($dfX1 > $dfLeftBorderX && $dfX1 < 180 && $dfX2 == -180 &&
845
					    $k+1 < $first_pass_ln &&
846
					    $first_pass[$k-1][0] > $dfLeftBorderX && $first_pass[$k-1][0] < 180)
847
					{
848
						$poNewLS[] = array(180, $first_pass[$k][1]);
849
						$k++;
850
						$poNewLS[] = array($first_pass[$k][0], $first_pass[$k][1]);
851
						continue;
852
					}
853
					if ($dfX1 < $dfRightBorderX && $dfX2 > $dfLeftBorderX)
854
					{
855
						// swap dfX1, dfX2
856
						$tmpX = $dfX1;
857
						$dfX1 = $dfX2;
858
						$dfX2 = $tmpX;
859
						// swap dfY1, dfY2
860
						$tmpY = $dfY1;
861
						$dfY1 = $dfY2;
862
						$dfY2 = $tmpY;
863
					}
864
					if ($dfX1 > $dfLeftBorderX && $dfX2 < $dfRightBorderX) {
865
						$dfX2 += 360;
866
					}
867
					if ($dfX1 <= 180 && $dfX2 >= 180 && $dfX1 < $dfX2)
868
					{
869
						$dfRatio = (180 - $dfX1) / ($dfX2 - $dfX1);
870
						$dfY = $dfRatio * $dfY2 + (1 - $dfRatio) * $dfY1;
871
						$poNewLS[] = array($first_pass[$k-1][0] > $dfLeftBorderX ? 180 : -180, $dfY);
872
						$poMulti[] = $poNewLS;
873
						$poNewLS = array();
874
						$poNewLS[] = array($first_pass[$k-1][0] > $dfLeftBorderX ? -180 : 180, $dfY);
875
						//$poMulti[] = $poNewLS;
876
					} else {
877
						//$poNewLS[] = array();
878
						$poMulti[] = $poNewLS;
879
						$poNewLS = array();
880
					}
881
					$poNewLS[] = array($dfX0, $first_pass[$k][1]);
882
				} else {
883
					$poNewLS[] = array($first_pass[$k][0], $first_pass[$k][1]);
884
				}
885
			}
886
			$poMulti[] = $poNewLS;
887
		} else {
888
			// add normally
889
			$poNewLS0 = array();
890
			//$poMulti[] = $poNewLS0;
891
			for ($l = 0; $l < $first_pass_ln; ++$l) {
892
				$poNewLS0[] = array($first_pass[$l][0],$first_pass[$l][1]);
893
			}
894
			$poMulti[] = $poNewLS0;
895
		}
896
		return $poMulti;
897
	}
898
}
899
?>