Completed
Push — master ( b40ad5...583e49 )
by Yannick
29:34
created

Common   F

Complexity

Total Complexity 190

Size/Duplication

Total Lines 860
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 860
rs 1.263
c 0
b 0
f 0
wmc 190
lcom 0
cbo 2

36 Methods

Rating   Name   Duplication   Size   Complexity  
A curlResponseHeaderCallback() 0 7 2
C download() 0 23 10
B gunzip() 0 20 7
B bunzip2() 0 19 6
C table2array() 0 31 7
A text2array() 0 12 3
B distance() 0 15 8
A plunge() 0 4 1
A azimuth() 0 7 2
B withinThreshold() 0 8 5
A isAssoc() 0 4 1
A isInteger() 0 3 1
A convertDec() 0 10 2
A convertDM() 0 14 4
A xcopy() 0 9 2
A urlexist() 0 4 2
A hex2str() 0 6 2
A hex2rgb() 0 4 1
A getHeading() 0 16 3
A checkLine() 0 9 3
A array_merge_noappend() 0 10 4
A arr_diff() 0 8 3
B multiKeyExists() 0 15 5
B listLocaleDir() 0 17 7
A nextcoord() 0 15 2
B getCoordfromDistanceBearing() 0 26 1
B gzCompressFile() 0 21 5
B remove_accents() 0 101 2
B str2int() 0 11 7
B create_socket() 0 13 5
A create_socket_udp() 0 12 4
A getUserIP() 0 5 3
A replace_mb_substr() 0 10 2
B is__writable() 0 19 5
F getData() 0 77 24
F greatcircle() 0 121 39

How to fix   Complexity   

Complex Class

Complex classes like Common often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Common, and based on these observations, apply Extract Interface, too.

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
		return $plunge;
258
	}
259
260
	/**
261
	* Give azimuth between 2 coordonnates
262
	* @param Float $lat latitude of first point
263
	* @param Float $lon longitude of first point
264
	* @param Float $latc latitude of second point
265
	* @param Float $lonc longitude of second point
266
	* @return Float Azimuth
267
	*/
268
	public function azimuth($lat, $lon, $latc, $lonc) {
269
		$dX = $latc - $lat;
270
		$dY = $lonc - $lon;
271
		$azimuth = rad2deg(atan2($dY,$dX));
272
		if ($azimuth < 0) return $azimuth+360;
273
		return $azimuth;
274
	}
275
	
276
	
277
	/**
278
	* Check is distance realistic
279
	* @param int $timeDifference the time between the reception of both messages
280
	* @param float $distance distance covered
281
	* @return whether distance is realistic
282
	*/
283
	public function withinThreshold ($timeDifference, $distance) {
284
		$x = abs($timeDifference);
285
		$d = abs($distance);
286
		if ($x == 0 || $d == 0) return true;
287
		// may be due to Internet jitter; distance is realistic
288
		if ($x < 0.7 && $d < 2000) return true;
289
		else return $d/$x < 1500*0.27778; // 1500 km/h max
290
	}
291
292
293
	// Check if an array is assoc
294
	public function isAssoc($array)
295
	{
296
		return ($array !== array_values($array));
297
	}
298
299
	public function isInteger($input){
300
	    return(ctype_digit(strval($input)));
301
	}
302
303
304
	public function convertDec($dms,$latlong) {
305
		if ($latlong == 'latitude') {
306
			$deg = substr($dms, 0, 2);
307
			$min = substr($dms, 2, 4);
308
		} else {
309
			$deg = substr($dms, 0, 3);
310
			$min = substr($dms, 3, 5);
311
		}
312
		return $deg+(($min*60)/3600);
313
	}
314
	
315
	public function convertDM($coord,$latlong) {
316
		if ($latlong == 'latitude') {
317
			if ($coord < 0) $NSEW = 'S';
318
			else $NSEW = 'N';
319
		} else {
320
			if ($coord < 0) $NSEW = 'W';
321
			else $NSEW = 'E';
322
		}
323
		$coord = abs($coord);
324
		$deg = floor($coord);
325
		$coord = ($coord-$deg)*60;
326
		$min = $coord;
327
		return array('deg' => $deg,'min' => $min,'NSEW' => $NSEW);
328
	}
329
	
330
	/**
331
	* Copy folder contents
332
	* @param       string   $source    Source path
333
	* @param       string   $dest      Destination path
334
	* @return      bool     Returns true on success, false on failure
335
	*/
336
	public function xcopy($source, $dest)
337
	{
338
		$files = glob($source.'*.*');
339
		foreach($files as $file){
340
			$file_to_go = str_replace($source,$dest,$file);
341
			copy($file, $file_to_go);
342
		}
343
		return true;
344
	}
345
	
346
	/**
347
	* Check if an url exist
348
	* @param	String $url url to check
349
	* @return	bool Return true on succes false on failure
350
	*/
351
	public function urlexist($url){
352
		$headers=get_headers($url);
353
		return stripos($headers[0],"200 OK")?true:false;
354
	}
355
	
356
	/**
357
	* Convert hexa to string
358
	* @param	String $hex data in hexa
359
	* @return	String Return result
360
	*/
361
	public function hex2str($hex) {
362
		$str = '';
363
		$hexln = strlen($hex);
364
		for($i=0;$i<$hexln;$i+=2) $str .= chr(hexdec(substr($hex,$i,2)));
365
		return $str;
366
	}
367
	
368
	/**
369
	* Convert hexa color to rgb
370
	* @param	String $hex data in hexa
371
	* @return	String Return result
372
	*/
373
	public function hex2rgb($hex) {
374
		$hex = str_replace('#','',$hex);
375
		return sscanf($hex, "%02x%02x%02x"); 
376
	}
377
	
378
	public function getHeading($lat1, $lon1, $lat2, $lon2) {
379
		//difference in longitudinal coordinates
380
		$dLon = deg2rad($lon2) - deg2rad($lon1);
381
		//difference in the phi of latitudinal coordinates
382
		$dPhi = log(tan(deg2rad($lat2) / 2 + pi() / 4) / tan(deg2rad($lat1) / 2 + pi() / 4));
383
		//we need to recalculate $dLon if it is greater than pi
384
		if(abs($dLon) > pi()) {
385
			if($dLon > 0) {
386
				$dLon = (2 * pi() - $dLon) * -1;
387
			} else {
388
				$dLon = 2 * pi() + $dLon;
389
			}
390
		}
391
		//return the angle, normalized
392
		return (rad2deg(atan2($dLon, $dPhi)) + 360) % 360;
393
	}
394
395
	public function checkLine($lat1,$lon1,$lat2,$lon2,$lat3,$lon3,$approx = 0.15) {
396
		//$a = ($lon2-$lon1)*$lat3+($lat2-$lat1)*$lon3+($lat1*$lon2+$lat2*$lon1);
397
		$a = -($lon2-$lon1);
398
		$b = $lat2 - $lat1;
399
		$c = -($a*$lat1+$b*$lon1);
400
		$d = $a*$lat3+$b*$lon3+$c;
401
		if ($d > -$approx && $d < $approx) return true;
402
		else return false;
403
	}
404
	
405
	public function array_merge_noappend() {
406
		$output = array();
407
		foreach(func_get_args() as $array) {
408
			foreach($array as $key => $value) {
409
				$output[$key] = isset($output[$key]) ?
410
				array_merge($output[$key], $value) : $value;
411
			}
412
		}
413
		return $output;
414
	}
415
	
416
417
	public function arr_diff($arraya, $arrayb) {
418
		foreach ($arraya as $keya => $valuea) {
419
			if (in_array($valuea, $arrayb)) {
420
				unset($arraya[$keya]);
421
			}
422
		}
423
		return $arraya;
424
	}
425
426
	/*
427
	* Check if a key exist in an array
428
	* Come from http://stackoverflow.com/a/19420866
429
	* @param Array array to check
430
	* @param String key to check
431
	* @return Bool true if exist, else false
432
	*/
433
	public function multiKeyExists(array $arr, $key) {
434
		// is in base array?
435
		if (array_key_exists($key, $arr)) {
436
			return true;
437
		}
438
		// check arrays contained in this array
439
		foreach ($arr as $element) {
440
			if (is_array($element)) {
441
				if ($this->multiKeyExists($element, $key)) {
442
					return true;
443
				}
444
			}
445
		}
446
		return false;
447
	}
448
	
449
	/**
450
	* Returns list of available locales
451
	*
452
	* @return array
453
	 */
454
	public function listLocaleDir()
455
	{
456
		$result = array('en');
457
		if (!is_dir('./locale')) {
458
			return $result;
459
		}
460
		$handle = @opendir('./locale');
461
		if ($handle === false) return $result;
462
		while (false !== ($file = readdir($handle))) {
463
			$path = './locale'.'/'.$file.'/LC_MESSAGES/fam.mo';
464
			if ($file != "." && $file != ".." && @file_exists($path)) {
465
				$result[] = $file;
466
			}
467
		}
468
		closedir($handle);
469
		return $result;
470
	}
471
472
	public function nextcoord($latitude, $longitude, $speed, $heading, $archivespeed = 1, $seconds = ''){
473
		global $globalMapRefresh;
474
		if ($seconds == '') {
475
			$distance = ($speed*0.514444*$globalMapRefresh*$archivespeed)/1000;
476
		} else {
477
			$distance = ($speed*0.514444*$seconds*$archivespeed)/1000;
478
		}
479
		$r = 6378;
480
		$latitude = deg2rad($latitude);
481
		$longitude = deg2rad($longitude);
482
		$bearing = deg2rad($heading); 
483
		$latitude2 =  asin( (sin($latitude) * cos($distance/$r)) + (cos($latitude) * sin($distance/$r) * cos($bearing)) );
484
		$longitude2 = $longitude + atan2( sin($bearing)*sin($distance/$r)*cos($latitude), cos($distance/$r)-(sin($latitude)*sin($latitude2)) );
485
		return array('latitude' => number_format(rad2deg($latitude2),5,'.',''),'longitude' => number_format(rad2deg($longitude2),5,'.',''));
486
	}
487
	
488
	public function getCoordfromDistanceBearing($latitude,$longitude,$bearing,$distance) {
489
		// distance in meter
490
		$R = 6378.14;
491
		$latitude1 = $latitude * (M_PI/180);
492
		$longitude1 = $longitude * (M_PI/180);
493
		$brng = $bearing * (M_PI/180);
494
		$d = $distance;
495
496
		$latitude2 = asin(sin($latitude1)*cos($d/$R) + cos($latitude1)*sin($d/$R)*cos($brng));
497
		$longitude2 = $longitude1 + atan2(sin($brng)*sin($d/$R)*cos($latitude1),cos($d/$R)-sin($latitude1)*sin($latitude2));
498
499
		$latitude2 = $latitude2 * (180/M_PI);
500
		$longitude2 = $longitude2 * (180/M_PI);
501
502
		$flat = round ($latitude2,6);
503
		$flong = round ($longitude2,6);
504
/*
505
		$dx = $distance*cos($bearing);
506
		$dy = $distance*sin($bearing);
507
		$dlong = $dx/(111320*cos($latitude));
508
		$dlat = $dy/110540;
509
		$flong = $longitude + $dlong;
510
		$flat = $latitude + $dlat;
511
*/
512
		return array('latitude' => $flat,'longitude' => $flong);
513
	}
514
515
	/**
516
	 * GZIPs a file on disk (appending .gz to the name)
517
	 *
518
	 * From http://stackoverflow.com/questions/6073397/how-do-you-create-a-gz-file-using-php
519
	 * Based on function by Kioob at:
520
	 * http://www.php.net/manual/en/function.gzwrite.php#34955
521
	 * 
522
	 * @param string $source Path to file that should be compressed
523
	 * @param integer $level GZIP compression level (default: 9)
524
	 * @return string New filename (with .gz appended) if success, or false if operation fails
525
	 */
526
	public function gzCompressFile($source, $level = 9){ 
527
		$dest = $source . '.gz'; 
528
		$mode = 'wb' . $level; 
529
		$error = false; 
530
		if ($fp_out = gzopen($dest, $mode)) { 
531
			if ($fp_in = fopen($source,'rb')) { 
532
				while (!feof($fp_in)) 
533
					gzwrite($fp_out, fread($fp_in, 1024 * 512)); 
534
				fclose($fp_in); 
535
			} else {
536
				$error = true; 
537
			}
538
			gzclose($fp_out); 
539
		} else {
540
			$error = true; 
541
		}
542
		if ($error)
543
			return false; 
544
		else
545
			return $dest; 
546
	} 
547
	
548
	public function remove_accents($string) {
549
		if ( !preg_match('/[\x80-\xff]/', $string) ) return $string;
550
		$chars = array(
551
		    // Decompositions for Latin-1 Supplement
552
		    chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
553
		    chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
554
		    chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
555
		    chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
556
		    chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
557
		    chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
558
		    chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
559
		    chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
560
		    chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
561
		    chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
562
		    chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
563
		    chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
564
		    chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
565
		    chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
566
		    chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
567
		    chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
568
		    chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
569
		    chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
570
		    chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
571
		    chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
572
		    chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
573
		    chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
574
		    chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
575
		    chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
576
		    chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
577
		    chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
578
		    chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
579
		    chr(195).chr(191) => 'y',
580
		    // Decompositions for Latin Extended-A
581
		    chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
582
		    chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
583
		    chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
584
		    chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
585
		    chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
586
		    chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
587
		    chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
588
		    chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
589
		    chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
590
		    chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
591
		    chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
592
		    chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
593
		    chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
594
		    chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
595
		    chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
596
		    chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
597
		    chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
598
		    chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
599
		    chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
600
		    chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
601
		    chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
602
		    chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
603
		    chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
604
		    chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
605
		    chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
606
		    chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
607
		    chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
608
		    chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
609
		    chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
610
		    chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
611
		    chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
612
		    chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
613
		    chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
614
		    chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
615
		    chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
616
		    chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
617
		    chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
618
		    chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
619
		    chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
620
		    chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
621
		    chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
622
		    chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
623
		    chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
624
		    chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
625
		    chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
626
		    chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
627
		    chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
628
		    chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
629
		    chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
630
		    chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
631
		    chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
632
		    chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
633
		    chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
634
		    chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
635
		    chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
636
		    chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
637
		    chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
638
		    chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
639
		    chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
640
		    chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
641
		    chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
642
		    chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
643
		    chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
644
		    chr(197).chr(190) => 'z', chr(197).chr(191) => 's'
645
		);
646
		$string = strtr($string, $chars);
647
		return $string;
648
	}
649
	
650
	/*
651
	* Extract int from a string
652
	* Come from http://php.net/manual/fr/function.intval.php comment by michiel ed thalent nl
653
	*
654
	* @param String Input string
655
	* @return Integer integer from the string
656
	*/
657
	public function str2int($string, $concat = false) {
658
		$length = strlen($string);    
659
		for ($i = 0, $int = '', $concat_flag = true; $i < $length; $i++) {
660
			if (is_numeric($string[$i]) && $concat_flag) {
661
				$int .= $string[$i];
662
			} elseif(!$concat && $concat_flag && strlen($int) > 0) {
663
				$concat_flag = false;
664
			}
665
		}
666
		return (int) $int;
667
	}
668
	
669
	public function create_socket($host, $port, &$errno, &$errstr) {
670
		$ip = gethostbyname($host);
671
		$s = socket_create(AF_INET, SOCK_STREAM, 0);
672
		$r = @socket_connect($s, $ip, $port);
673
		if (!socket_set_nonblock($s)) echo "Unable to set nonblock on socket\n";
674
		if ($r || socket_last_error() == 114 || socket_last_error() == 115) {
675
			return $s;
676
		}
677
		$errno = socket_last_error($s);
678
		$errstr = socket_strerror($errno);
679
		socket_close($s);
680
		return false;
681
	}
682
683
	public function create_socket_udp($host, $port, &$errno, &$errstr) {
684
		$ip = gethostbyname($host);
685
		$s = socket_create(AF_INET, SOCK_DGRAM, 0);
686
		$r = @socket_bind($s, $ip, $port);
687
		if ($r || socket_last_error() == 114 || socket_last_error() == 115) {
688
			return $s;
689
		}
690
		$errno = socket_last_error($s);
691
		$errstr = socket_strerror($errno);
692
		socket_close($s);
693
		return false;
694
	}
695
696
	public function getUserIP() { 
697
		$client = @$_SERVER['HTTP_CLIENT_IP'];
698
		$forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
699
		return filter_var($client, FILTER_VALIDATE_IP) ? $client : filter_var($forward, FILTER_VALIDATE_IP) ? $forward : $_SERVER['REMOTE_ADDR']; 
700
	}
701
	public function replace_mb_substr($string, $offset, $length)
702
	{
703
		if (!function_exists('mb_substr')) {
704
			$arr = preg_split("//u", $string);
705
			$slice = array_slice($arr, $offset + 1, $length);
706
			return implode("", $slice);
707
		} else {
708
			return mb_substr($string,$offset,$length,'UTF-8');
709
		}
710
	}
711
712
	// Come from comment : http://php.net/manual/fr/function.is-writable.php#73596
713
	public function is__writable($path) {
714
		//will work in despite of Windows ACLs bug
715
		//NOTE: use a trailing slash for folders!!!
716
		//see http://bugs.php.net/bug.php?id=27609
717
		//see http://bugs.php.net/bug.php?id=30931
718
		if ($path{strlen($path)-1}=='/') // recursively return a temporary file path
719
			return $this->is__writable($path.uniqid(mt_rand()).'.tmp');
720
		else if (is_dir($path))
721
			return $this->is__writable($path.'/'.uniqid(mt_rand()).'.tmp');
722
		// check tmp file for read/write capabilities
723
		$rm = file_exists($path);
724
		$f = @fopen($path, 'a');
725
		if ($f===false)
726
			return false;
727
		fclose($f);
728
		if (!$rm)
729
			unlink($path);
730
		return true;
731
	}
732
	
733
	/*
734
	 * Great circle route
735
	 * Translated to PHP from javascript version of https://github.com/springmeyer/arc.js
736
	 * @param Float $begin_lat Latitude of origin point
737
	 * @param Float $begin_lon Longitude of origin point
738
	 * @param Float $end_lat Latitude of final point
739
	 * @param Float $end_lon Longitude of final point
740
	 * @param Integer $nbpts Number of intermediate vertices desired
741
	 * @param Integer $offset Controls the likelyhood that lines will be split which cross the dateline
742
	 * @return Array Coordinate of the route
743
	*/
744
	public function greatcircle($begin_lat,$begin_lon,$end_lat,$end_lon,$nbpts = 20, $offset = 10) {
745
		if ($nbpts <= 2) return array(array($begin_lon,$begin_lat),array($end_lon,$end_lat));
746
		$sx = deg2rad($begin_lon);
747
		$sy = deg2rad($begin_lat);
748
		$ex = deg2rad($end_lon);
749
		$ey = deg2rad($end_lat);
750
		$w = $sx - $ex;
751
		$h = $sy - $ey;
752
		$z = pow(sin($h/2.0),2) + cos($sy)*cos($ey)*pow(sin($w/2.0),2);
753
		$g = 2.0*asin(sqrt($z));
754
		if ($g == pi() || is_nan($g)) return array(array($begin_lon,$begin_lat),array($end_lon,$end_lat));
755
		$first_pass = array();
756
		$delta = 1.0/($nbpts-1);
757
		for ($i =0; $i < $nbpts; ++$i) {
758
			$step = $delta*$i;
759
			$A = sin((1 - $step) * $g) / sin($g);
760
			$B = sin($step * $g) / sin($g);
761
			$x = $A * cos($sy) * cos($sx) + $B * cos($ey) * cos($ex);
762
			$y = $A * cos($sy) * sin($sx) + $B * cos($ey) * sin($ex);
763
			$z = $A * sin($sy) + $B * sin($ey);
764
			$lat = rad2deg(atan2($z, sqrt(pow($x, 2) + pow($y, 2))));
765
			$lon = rad2deg(atan2($y, $x));
766
			$first_pass[] = array($lon,$lat);
767
		}
768
		$bHasBigDiff = false;
769
		$dfMaxSmallDiffLong = 0;
770
		// from http://www.gdal.org/ogr2ogr.html
771
		// -datelineoffset:
772
		// (starting with GDAL 1.10) offset from dateline in degrees (default long. = +/- 10deg, geometries within 170deg to -170deg will be splited)
773
		$dfDateLineOffset = $offset;
774
		$dfLeftBorderX = 180 - $dfDateLineOffset;
775
		$dfRightBorderX = -180 + $dfDateLineOffset;
776
		$dfDiffSpace = 360 - $dfDateLineOffset;
777
		
778
		// https://github.com/OSGeo/gdal/blob/7bfb9c452a59aac958bff0c8386b891edf8154ca/gdal/ogr/ogrgeometryfactory.cpp#L2342
779
		for ($j = 1; $j < count($first_pass); ++$j) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
780
			$dfPrevX = $first_pass[$j-1][0];
781
			$dfX = $first_pass[$j][0];
782
			$dfDiffLong = abs($dfX - $dfPrevX);
783
			if ($dfDiffLong > $dfDiffSpace &&
784
			    (($dfX > $dfLeftBorderX && $dfPrevX < $dfRightBorderX) || ($dfPrevX > $dfLeftBorderX && $dfX < $dfRightBorderX))) 
785
			{
786
				$bHasBigDiff = true;
787
			} else if ($dfDiffLong > $dfMaxSmallDiffLong) {
788
				$dfMaxSmallDiffLong = $dfDiffLong;
789
			}
790
		}
791
		$poMulti = array();
792
		if ($bHasBigDiff && $dfMaxSmallDiffLong < $dfDateLineOffset) {
793
			$poNewLS = array();
794
			//$poMulti[] = $poNewLS;
795
			for ($k = 0; $k < count($first_pass); ++$k) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
796
				$dfX0 = floatval($first_pass[$k][0]);
797
				if ($k > 0 &&  abs($dfX0 - $first_pass[$k-1][0]) > $dfDiffSpace) {
798
					$dfX1 = floatval($first_pass[$k-1][0]);
799
					$dfY1 = floatval($first_pass[$k-1][1]);
800
					$dfX2 = floatval($first_pass[$k][0]);
801
					$dfY2 = floatval($first_pass[$k][1]);
802
					if ($dfX1 > -180 && $dfX1 < $dfRightBorderX && $dfX2 == 180 &&
803
					    $k+1 < count($first_pass) &&
804
					    $first_pass[$k-1][0] > -180 && $first_pass[$k-1][0] < $dfRightBorderX)
805
					{
806
						$poNewLS[] = array(-180, $first_pass[$k][1]);
807
						$k++;
808
						//echo 'here';
809
						$poNewLS[] = array($first_pass[$k][0], $first_pass[$k][1]);
810
						continue;
811
					} else if ($dfX1 > $dfLeftBorderX && $dfX1 < 180 && $dfX2 == -180 &&
812
					    $k+1 < count($first_pass) &&
813
					    $first_pass[$k-1][0] > $dfLeftBorderX && $first_pass[$k-1][0] < 180)
814
					{
815
						$poNewLS[] = array(180, $first_pass[$k][1]);
816
						$k++;
817
						$poNewLS[] = array($first_pass[$k][0], $first_pass[$k][1]);
818
						continue;
819
					}
820
					if ($dfX1 < $dfRightBorderX && $dfX2 > $dfLeftBorderX)
821
					{
822
						// swap dfX1, dfX2
823
						$tmpX = $dfX1;
824
						$dfX1 = $dfX2;
825
						$dfX2 = $tmpX;
826
						// swap dfY1, dfY2
827
						$tmpY = $dfY1;
828
						$dfY1 = $dfY2;
829
						$dfY2 = $tmpY;
830
					}
831
					if ($dfX1 > $dfLeftBorderX && $dfX2 < $dfRightBorderX) {
832
						$dfX2 += 360;
833
					}
834
					if ($dfX1 <= 180 && $dfX2 >= 180 && $dfX1 < $dfX2)
835
					{
836
						$dfRatio = (180 - $dfX1) / ($dfX2 - $dfX1);
837
						$dfY = $dfRatio * $dfY2 + (1 - $dfRatio) * $dfY1;
838
						$poNewLS[] = array($first_pass[$k-1][0] > $dfLeftBorderX ? 180 : -180, $dfY);
839
						$poMulti[] = $poNewLS;
840
						$poNewLS = array();
841
						$poNewLS[] = array($first_pass[$k-1][0] > $dfLeftBorderX ? -180 : 180, $dfY);
842
						//$poMulti[] = $poNewLS;
843
					} else {
844
						//$poNewLS[] = array();
845
						$poMulti[] = $poNewLS;
846
						$poNewLS = array();
847
					}
848
					$poNewLS[] = array($dfX0, $first_pass[$k][1]);
849
				} else {
850
					$poNewLS[] = array($first_pass[$k][0], $first_pass[$k][1]);
851
				}
852
			}
853
			$poMulti[] = $poNewLS;
854
		} else {
855
			// add normally
856
			$poNewLS0 = array();
857
			//$poMulti[] = $poNewLS0;
858
			for ($l = 0; $l < count($first_pass); ++$l) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
859
				$poNewLS0[] = array($first_pass[$l][0],$first_pass[$l][1]);
860
			}
861
			$poMulti[] = $poNewLS0;
862
		}
863
		return $poMulti;
864
	}
865
}
866
?>