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

Common::getData()   F

Complexity

Conditions 24
Paths 13824

Size

Total Lines 77
Code Lines 60

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 24
eloc 60
nc 13824
nop 10
dl 0
loc 77
rs 2.3626
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 = '', $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
?>