WC_Geo_IP::_setup_segments()   D
last analyzed

Complexity

Conditions 72
Paths 48

Size

Total Lines 149
Code Lines 108

Duplication

Lines 14
Ratio 9.4 %

Importance

Changes 0
Metric Value
cc 72
eloc 108
nc 48
nop 0
dl 14
loc 149
rs 4.1818
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Geo IP class
4
 *
5
 * This class is a fork of GeoIP class from MaxMind LLC.
6
 *
7
 * @author 	 WooThemes
8
 * @category Admin
9
 * @package  WooCommerce/Classes
10
 * @version  2.4.0
11
 */
12
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * WC_Geo_IP Class.
19
 */
20
class WC_Geo_IP {
21
22
	const GEOIP_COUNTRY_BEGIN            = 16776960;
23
	const GEOIP_STATE_BEGIN_REV0         = 16700000;
24
	const GEOIP_STATE_BEGIN_REV1         = 16000000;
25
	const GEOIP_MEMORY_CACHE             = 1;
26
	const GEOIP_SHARED_MEMORY            = 2;
27
	const STRUCTURE_INFO_MAX_SIZE        = 20;
28
	const GEOIP_COUNTRY_EDITION          = 1;
29
	const GEOIP_PROXY_EDITION            = 8;
30
	const GEOIP_ASNUM_EDITION            = 9;
31
	const GEOIP_NETSPEED_EDITION         = 10;
32
	const GEOIP_REGION_EDITION_REV0      = 7;
33
	const GEOIP_REGION_EDITION_REV1      = 3;
34
	const GEOIP_CITY_EDITION_REV0        = 6;
35
	const GEOIP_CITY_EDITION_REV1        = 2;
36
	const GEOIP_ORG_EDITION              = 5;
37
	const GEOIP_ISP_EDITION              = 4;
38
	const SEGMENT_RECORD_LENGTH          = 3;
39
	const STANDARD_RECORD_LENGTH         = 3;
40
	const ORG_RECORD_LENGTH              = 4;
41
	const GEOIP_SHM_KEY                  = 0x4f415401;
42
	const GEOIP_DOMAIN_EDITION           = 11;
43
	const GEOIP_COUNTRY_EDITION_V6       = 12;
44
	const GEOIP_LOCATIONA_EDITION        = 13;
45
	const GEOIP_ACCURACYRADIUS_EDITION   = 14;
46
	const GEOIP_CITY_EDITION_REV1_V6     = 30;
47
	const GEOIP_CITY_EDITION_REV0_V6     = 31;
48
	const GEOIP_NETSPEED_EDITION_REV1    = 32;
49
	const GEOIP_NETSPEED_EDITION_REV1_V6 = 33;
50
	const GEOIP_USERTYPE_EDITION         = 28;
51
	const GEOIP_USERTYPE_EDITION_V6      = 29;
52
	const GEOIP_ASNUM_EDITION_V6         = 21;
53
	const GEOIP_ISP_EDITION_V6           = 22;
54
	const GEOIP_ORG_EDITION_V6           = 23;
55
	const GEOIP_DOMAIN_EDITION_V6        = 24;
56
57
	/**
58
	 * Flags.
59
	 *
60
	 * @var int
61
	 */
62
	public $flags;
63
64
	/**
65
	 * File handler.
66
	 *
67
	 * @var resource
68
	 */
69
	public $filehandle;
70
71
	/**
72
	 * Memory buffer.
73
	 *
74
	 * @var string
75
	 */
76
	public $memory_buffer;
77
78
	/**
79
	 * Database type.
80
	 *
81
	 * @var string
82
	 */
83
	public $databaseType;
84
85
	/**
86
	 * Database segments.
87
	 *
88
	 * @var int
89
	 */
90
	public $databaseSegments;
91
92
	/**
93
	 * Record length.
94
	 *
95
	 * @var int
96
	 */
97
	public $record_length;
98
99
	/**
100
	 * Shmid.
101
	 *
102
	 * @var string
103
	 */
104
	public $shmid;
105
106
	/**
107
	 * Two letters country codes.
108
	 *
109
	 * @var array
110
	 */
111
	public $GEOIP_COUNTRY_CODES = array(
112
		'',
113
		'AP',
114
		'EU',
115
		'AD',
116
		'AE',
117
		'AF',
118
		'AG',
119
		'AI',
120
		'AL',
121
		'AM',
122
		'CW',
123
		'AO',
124
		'AQ',
125
		'AR',
126
		'AS',
127
		'AT',
128
		'AU',
129
		'AW',
130
		'AZ',
131
		'BA',
132
		'BB',
133
		'BD',
134
		'BE',
135
		'BF',
136
		'BG',
137
		'BH',
138
		'BI',
139
		'BJ',
140
		'BM',
141
		'BN',
142
		'BO',
143
		'BR',
144
		'BS',
145
		'BT',
146
		'BV',
147
		'BW',
148
		'BY',
149
		'BZ',
150
		'CA',
151
		'CC',
152
		'CD',
153
		'CF',
154
		'CG',
155
		'CH',
156
		'CI',
157
		'CK',
158
		'CL',
159
		'CM',
160
		'CN',
161
		'CO',
162
		'CR',
163
		'CU',
164
		'CV',
165
		'CX',
166
		'CY',
167
		'CZ',
168
		'DE',
169
		'DJ',
170
		'DK',
171
		'DM',
172
		'DO',
173
		'DZ',
174
		'EC',
175
		'EE',
176
		'EG',
177
		'EH',
178
		'ER',
179
		'ES',
180
		'ET',
181
		'FI',
182
		'FJ',
183
		'FK',
184
		'FM',
185
		'FO',
186
		'FR',
187
		'SX',
188
		'GA',
189
		'GB',
190
		'GD',
191
		'GE',
192
		'GF',
193
		'GH',
194
		'GI',
195
		'GL',
196
		'GM',
197
		'GN',
198
		'GP',
199
		'GQ',
200
		'GR',
201
		'GS',
202
		'GT',
203
		'GU',
204
		'GW',
205
		'GY',
206
		'HK',
207
		'HM',
208
		'HN',
209
		'HR',
210
		'HT',
211
		'HU',
212
		'ID',
213
		'IE',
214
		'IL',
215
		'IN',
216
		'IO',
217
		'IQ',
218
		'IR',
219
		'IS',
220
		'IT',
221
		'JM',
222
		'JO',
223
		'JP',
224
		'KE',
225
		'KG',
226
		'KH',
227
		'KI',
228
		'KM',
229
		'KN',
230
		'KP',
231
		'KR',
232
		'KW',
233
		'KY',
234
		'KZ',
235
		'LA',
236
		'LB',
237
		'LC',
238
		'LI',
239
		'LK',
240
		'LR',
241
		'LS',
242
		'LT',
243
		'LU',
244
		'LV',
245
		'LY',
246
		'MA',
247
		'MC',
248
		'MD',
249
		'MG',
250
		'MH',
251
		'MK',
252
		'ML',
253
		'MM',
254
		'MN',
255
		'MO',
256
		'MP',
257
		'MQ',
258
		'MR',
259
		'MS',
260
		'MT',
261
		'MU',
262
		'MV',
263
		'MW',
264
		'MX',
265
		'MY',
266
		'MZ',
267
		'NA',
268
		'NC',
269
		'NE',
270
		'NF',
271
		'NG',
272
		'NI',
273
		'NL',
274
		'NO',
275
		'NP',
276
		'NR',
277
		'NU',
278
		'NZ',
279
		'OM',
280
		'PA',
281
		'PE',
282
		'PF',
283
		'PG',
284
		'PH',
285
		'PK',
286
		'PL',
287
		'PM',
288
		'PN',
289
		'PR',
290
		'PS',
291
		'PT',
292
		'PW',
293
		'PY',
294
		'QA',
295
		'RE',
296
		'RO',
297
		'RU',
298
		'RW',
299
		'SA',
300
		'SB',
301
		'SC',
302
		'SD',
303
		'SE',
304
		'SG',
305
		'SH',
306
		'SI',
307
		'SJ',
308
		'SK',
309
		'SL',
310
		'SM',
311
		'SN',
312
		'SO',
313
		'SR',
314
		'ST',
315
		'SV',
316
		'SY',
317
		'SZ',
318
		'TC',
319
		'TD',
320
		'TF',
321
		'TG',
322
		'TH',
323
		'TJ',
324
		'TK',
325
		'TM',
326
		'TN',
327
		'TO',
328
		'TL',
329
		'TR',
330
		'TT',
331
		'TV',
332
		'TW',
333
		'TZ',
334
		'UA',
335
		'UG',
336
		'UM',
337
		'US',
338
		'UY',
339
		'UZ',
340
		'VA',
341
		'VC',
342
		'VE',
343
		'VG',
344
		'VI',
345
		'VN',
346
		'VU',
347
		'WF',
348
		'WS',
349
		'YE',
350
		'YT',
351
		'RS',
352
		'ZA',
353
		'ZM',
354
		'ME',
355
		'ZW',
356
		'A1',
357
		'A2',
358
		'O1',
359
		'AX',
360
		'GG',
361
		'IM',
362
		'JE',
363
		'BL',
364
		'MF',
365
		'BQ',
366
		'SS',
367
		'O1'
368
	);
369
370
	/**
371
	 * 3 letters country codes.
372
	 *
373
	 * @var array
374
	 */
375
	public $GEOIP_COUNTRY_CODES3 = array(
376
		'',
377
		'AP',
378
		'EU',
379
		'AND',
380
		'ARE',
381
		'AFG',
382
		'ATG',
383
		'AIA',
384
		'ALB',
385
		'ARM',
386
		'CUW',
387
		'AGO',
388
		'ATA',
389
		'ARG',
390
		'ASM',
391
		'AUT',
392
		'AUS',
393
		'ABW',
394
		'AZE',
395
		'BIH',
396
		'BRB',
397
		'BGD',
398
		'BEL',
399
		'BFA',
400
		'BGR',
401
		'BHR',
402
		'BDI',
403
		'BEN',
404
		'BMU',
405
		'BRN',
406
		'BOL',
407
		'BRA',
408
		'BHS',
409
		'BTN',
410
		'BVT',
411
		'BWA',
412
		'BLR',
413
		'BLZ',
414
		'CAN',
415
		'CCK',
416
		'COD',
417
		'CAF',
418
		'COG',
419
		'CHE',
420
		'CIV',
421
		'COK',
422
		'CHL',
423
		'CMR',
424
		'CHN',
425
		'COL',
426
		'CRI',
427
		'CUB',
428
		'CPV',
429
		'CXR',
430
		'CYP',
431
		'CZE',
432
		'DEU',
433
		'DJI',
434
		'DNK',
435
		'DMA',
436
		'DOM',
437
		'DZA',
438
		'ECU',
439
		'EST',
440
		'EGY',
441
		'ESH',
442
		'ERI',
443
		'ESP',
444
		'ETH',
445
		'FIN',
446
		'FJI',
447
		'FLK',
448
		'FSM',
449
		'FRO',
450
		'FRA',
451
		'SXM',
452
		'GAB',
453
		'GBR',
454
		'GRD',
455
		'GEO',
456
		'GUF',
457
		'GHA',
458
		'GIB',
459
		'GRL',
460
		'GMB',
461
		'GIN',
462
		'GLP',
463
		'GNQ',
464
		'GRC',
465
		'SGS',
466
		'GTM',
467
		'GUM',
468
		'GNB',
469
		'GUY',
470
		'HKG',
471
		'HMD',
472
		'HND',
473
		'HRV',
474
		'HTI',
475
		'HUN',
476
		'IDN',
477
		'IRL',
478
		'ISR',
479
		'IND',
480
		'IOT',
481
		'IRQ',
482
		'IRN',
483
		'ISL',
484
		'ITA',
485
		'JAM',
486
		'JOR',
487
		'JPN',
488
		'KEN',
489
		'KGZ',
490
		'KHM',
491
		'KIR',
492
		'COM',
493
		'KNA',
494
		'PRK',
495
		'KOR',
496
		'KWT',
497
		'CYM',
498
		'KAZ',
499
		'LAO',
500
		'LBN',
501
		'LCA',
502
		'LIE',
503
		'LKA',
504
		'LBR',
505
		'LSO',
506
		'LTU',
507
		'LUX',
508
		'LVA',
509
		'LBY',
510
		'MAR',
511
		'MCO',
512
		'MDA',
513
		'MDG',
514
		'MHL',
515
		'MKD',
516
		'MLI',
517
		'MMR',
518
		'MNG',
519
		'MAC',
520
		'MNP',
521
		'MTQ',
522
		'MRT',
523
		'MSR',
524
		'MLT',
525
		'MUS',
526
		'MDV',
527
		'MWI',
528
		'MEX',
529
		'MYS',
530
		'MOZ',
531
		'NAM',
532
		'NCL',
533
		'NER',
534
		'NFK',
535
		'NGA',
536
		'NIC',
537
		'NLD',
538
		'NOR',
539
		'NPL',
540
		'NRU',
541
		'NIU',
542
		'NZL',
543
		'OMN',
544
		'PAN',
545
		'PER',
546
		'PYF',
547
		'PNG',
548
		'PHL',
549
		'PAK',
550
		'POL',
551
		'SPM',
552
		'PCN',
553
		'PRI',
554
		'PSE',
555
		'PRT',
556
		'PLW',
557
		'PRY',
558
		'QAT',
559
		'REU',
560
		'ROU',
561
		'RUS',
562
		'RWA',
563
		'SAU',
564
		'SLB',
565
		'SYC',
566
		'SDN',
567
		'SWE',
568
		'SGP',
569
		'SHN',
570
		'SVN',
571
		'SJM',
572
		'SVK',
573
		'SLE',
574
		'SMR',
575
		'SEN',
576
		'SOM',
577
		'SUR',
578
		'STP',
579
		'SLV',
580
		'SYR',
581
		'SWZ',
582
		'TCA',
583
		'TCD',
584
		'ATF',
585
		'TGO',
586
		'THA',
587
		'TJK',
588
		'TKL',
589
		'TKM',
590
		'TUN',
591
		'TON',
592
		'TLS',
593
		'TUR',
594
		'TTO',
595
		'TUV',
596
		'TWN',
597
		'TZA',
598
		'UKR',
599
		'UGA',
600
		'UMI',
601
		'USA',
602
		'URY',
603
		'UZB',
604
		'VAT',
605
		'VCT',
606
		'VEN',
607
		'VGB',
608
		'VIR',
609
		'VNM',
610
		'VUT',
611
		'WLF',
612
		'WSM',
613
		'YEM',
614
		'MYT',
615
		'SRB',
616
		'ZAF',
617
		'ZMB',
618
		'MNE',
619
		'ZWE',
620
		'A1',
621
		'A2',
622
		'O1',
623
		'ALA',
624
		'GGY',
625
		'IMN',
626
		'JEY',
627
		'BLM',
628
		'MAF',
629
		'BES',
630
		'SSD',
631
		'O1'
632
	);
633
634
	/**
635
	 * Contry names.
636
	 *
637
	 * @var array
638
	 */
639
	public $GEOIP_COUNTRY_NAMES = array(
640
		'',
641
		'Asia/Pacific Region',
642
		'Europe',
643
		'Andorra',
644
		'United Arab Emirates',
645
		'Afghanistan',
646
		'Antigua and Barbuda',
647
		'Anguilla',
648
		'Albania',
649
		'Armenia',
650
		'Curacao',
651
		'Angola',
652
		'Antarctica',
653
		'Argentina',
654
		'American Samoa',
655
		'Austria',
656
		'Australia',
657
		'Aruba',
658
		'Azerbaijan',
659
		'Bosnia and Herzegovina',
660
		'Barbados',
661
		'Bangladesh',
662
		'Belgium',
663
		'Burkina Faso',
664
		'Bulgaria',
665
		'Bahrain',
666
		'Burundi',
667
		'Benin',
668
		'Bermuda',
669
		'Brunei Darussalam',
670
		'Bolivia',
671
		'Brazil',
672
		'Bahamas',
673
		'Bhutan',
674
		'Bouvet Island',
675
		'Botswana',
676
		'Belarus',
677
		'Belize',
678
		'Canada',
679
		'Cocos (Keeling) Islands',
680
		'Congo, The Democratic Republic of the',
681
		'Central African Republic',
682
		'Congo',
683
		'Switzerland',
684
		"Cote D'Ivoire",
685
		'Cook Islands',
686
		'Chile',
687
		'Cameroon',
688
		'China',
689
		'Colombia',
690
		'Costa Rica',
691
		'Cuba',
692
		'Cape Verde',
693
		'Christmas Island',
694
		'Cyprus',
695
		'Czech Republic',
696
		'Germany',
697
		'Djibouti',
698
		'Denmark',
699
		'Dominica',
700
		'Dominican Republic',
701
		'Algeria',
702
		'Ecuador',
703
		'Estonia',
704
		'Egypt',
705
		'Western Sahara',
706
		'Eritrea',
707
		'Spain',
708
		'Ethiopia',
709
		'Finland',
710
		'Fiji',
711
		'Falkland Islands (Malvinas)',
712
		'Micronesia, Federated States of',
713
		'Faroe Islands',
714
		'France',
715
		'Sint Maarten (Dutch part)',
716
		'Gabon',
717
		'United Kingdom',
718
		'Grenada',
719
		'Georgia',
720
		'French Guiana',
721
		'Ghana',
722
		'Gibraltar',
723
		'Greenland',
724
		'Gambia',
725
		'Guinea',
726
		'Guadeloupe',
727
		'Equatorial Guinea',
728
		'Greece',
729
		'South Georgia and the South Sandwich Islands',
730
		'Guatemala',
731
		'Guam',
732
		'Guinea-Bissau',
733
		'Guyana',
734
		'Hong Kong',
735
		'Heard Island and McDonald Islands',
736
		'Honduras',
737
		'Croatia',
738
		'Haiti',
739
		'Hungary',
740
		'Indonesia',
741
		'Ireland',
742
		'Israel',
743
		'India',
744
		'British Indian Ocean Territory',
745
		'Iraq',
746
		'Iran, Islamic Republic of',
747
		'Iceland',
748
		'Italy',
749
		'Jamaica',
750
		'Jordan',
751
		'Japan',
752
		'Kenya',
753
		'Kyrgyzstan',
754
		'Cambodia',
755
		'Kiribati',
756
		'Comoros',
757
		'Saint Kitts and Nevis',
758
		"Korea, Democratic People's Republic of",
759
		'Korea, Republic of',
760
		'Kuwait',
761
		'Cayman Islands',
762
		'Kazakhstan',
763
		"Lao People's Democratic Republic",
764
		'Lebanon',
765
		'Saint Lucia',
766
		'Liechtenstein',
767
		'Sri Lanka',
768
		'Liberia',
769
		'Lesotho',
770
		'Lithuania',
771
		'Luxembourg',
772
		'Latvia',
773
		'Libya',
774
		'Morocco',
775
		'Monaco',
776
		'Moldova, Republic of',
777
		'Madagascar',
778
		'Marshall Islands',
779
		'Macedonia',
780
		'Mali',
781
		'Myanmar',
782
		'Mongolia',
783
		'Macau',
784
		'Northern Mariana Islands',
785
		'Martinique',
786
		'Mauritania',
787
		'Montserrat',
788
		'Malta',
789
		'Mauritius',
790
		'Maldives',
791
		'Malawi',
792
		'Mexico',
793
		'Malaysia',
794
		'Mozambique',
795
		'Namibia',
796
		'New Caledonia',
797
		'Niger',
798
		'Norfolk Island',
799
		'Nigeria',
800
		'Nicaragua',
801
		'Netherlands',
802
		'Norway',
803
		'Nepal',
804
		'Nauru',
805
		'Niue',
806
		'New Zealand',
807
		'Oman',
808
		'Panama',
809
		'Peru',
810
		'French Polynesia',
811
		'Papua New Guinea',
812
		'Philippines',
813
		'Pakistan',
814
		'Poland',
815
		'Saint Pierre and Miquelon',
816
		'Pitcairn Islands',
817
		'Puerto Rico',
818
		'Palestinian Territory',
819
		'Portugal',
820
		'Palau',
821
		'Paraguay',
822
		'Qatar',
823
		'Reunion',
824
		'Romania',
825
		'Russian Federation',
826
		'Rwanda',
827
		'Saudi Arabia',
828
		'Solomon Islands',
829
		'Seychelles',
830
		'Sudan',
831
		'Sweden',
832
		'Singapore',
833
		'Saint Helena',
834
		'Slovenia',
835
		'Svalbard and Jan Mayen',
836
		'Slovakia',
837
		'Sierra Leone',
838
		'San Marino',
839
		'Senegal',
840
		'Somalia',
841
		'Suriname',
842
		'Sao Tome and Principe',
843
		'El Salvador',
844
		'Syrian Arab Republic',
845
		'Swaziland',
846
		'Turks and Caicos Islands',
847
		'Chad',
848
		'French Southern Territories',
849
		'Togo',
850
		'Thailand',
851
		'Tajikistan',
852
		'Tokelau',
853
		'Turkmenistan',
854
		'Tunisia',
855
		'Tonga',
856
		'Timor-Leste',
857
		'Turkey',
858
		'Trinidad and Tobago',
859
		'Tuvalu',
860
		'Taiwan',
861
		'Tanzania, United Republic of',
862
		'Ukraine',
863
		'Uganda',
864
		'United States Minor Outlying Islands',
865
		'United States',
866
		'Uruguay',
867
		'Uzbekistan',
868
		'Holy See (Vatican City State)',
869
		'Saint Vincent and the Grenadines',
870
		'Venezuela',
871
		'Virgin Islands, British',
872
		'Virgin Islands, U.S.',
873
		'Vietnam',
874
		'Vanuatu',
875
		'Wallis and Futuna',
876
		'Samoa',
877
		'Yemen',
878
		'Mayotte',
879
		'Serbia',
880
		'South Africa',
881
		'Zambia',
882
		'Montenegro',
883
		'Zimbabwe',
884
		'Anonymous Proxy',
885
		'Satellite Provider',
886
		'Other',
887
		'Aland Islands',
888
		'Guernsey',
889
		'Isle of Man',
890
		'Jersey',
891
		'Saint Barthelemy',
892
		'Saint Martin',
893
		'Bonaire, Saint Eustatius and Saba',
894
		'South Sudan',
895
		'Other'
896
	);
897
898
	/**
899
	 * 2 letters continent codes.
900
	 *
901
	 * @var array
902
	 */
903
	public $GEOIP_CONTINENT_CODES = array(
904
		'--',
905
		'AS',
906
		'EU',
907
		'EU',
908
		'AS',
909
		'AS',
910
		'NA',
911
		'NA',
912
		'EU',
913
		'AS',
914
		'NA',
915
		'AF',
916
		'AN',
917
		'SA',
918
		'OC',
919
		'EU',
920
		'OC',
921
		'NA',
922
		'AS',
923
		'EU',
924
		'NA',
925
		'AS',
926
		'EU',
927
		'AF',
928
		'EU',
929
		'AS',
930
		'AF',
931
		'AF',
932
		'NA',
933
		'AS',
934
		'SA',
935
		'SA',
936
		'NA',
937
		'AS',
938
		'AN',
939
		'AF',
940
		'EU',
941
		'NA',
942
		'NA',
943
		'AS',
944
		'AF',
945
		'AF',
946
		'AF',
947
		'EU',
948
		'AF',
949
		'OC',
950
		'SA',
951
		'AF',
952
		'AS',
953
		'SA',
954
		'NA',
955
		'NA',
956
		'AF',
957
		'AS',
958
		'AS',
959
		'EU',
960
		'EU',
961
		'AF',
962
		'EU',
963
		'NA',
964
		'NA',
965
		'AF',
966
		'SA',
967
		'EU',
968
		'AF',
969
		'AF',
970
		'AF',
971
		'EU',
972
		'AF',
973
		'EU',
974
		'OC',
975
		'SA',
976
		'OC',
977
		'EU',
978
		'EU',
979
		'NA',
980
		'AF',
981
		'EU',
982
		'NA',
983
		'AS',
984
		'SA',
985
		'AF',
986
		'EU',
987
		'NA',
988
		'AF',
989
		'AF',
990
		'NA',
991
		'AF',
992
		'EU',
993
		'AN',
994
		'NA',
995
		'OC',
996
		'AF',
997
		'SA',
998
		'AS',
999
		'AN',
1000
		'NA',
1001
		'EU',
1002
		'NA',
1003
		'EU',
1004
		'AS',
1005
		'EU',
1006
		'AS',
1007
		'AS',
1008
		'AS',
1009
		'AS',
1010
		'AS',
1011
		'EU',
1012
		'EU',
1013
		'NA',
1014
		'AS',
1015
		'AS',
1016
		'AF',
1017
		'AS',
1018
		'AS',
1019
		'OC',
1020
		'AF',
1021
		'NA',
1022
		'AS',
1023
		'AS',
1024
		'AS',
1025
		'NA',
1026
		'AS',
1027
		'AS',
1028
		'AS',
1029
		'NA',
1030
		'EU',
1031
		'AS',
1032
		'AF',
1033
		'AF',
1034
		'EU',
1035
		'EU',
1036
		'EU',
1037
		'AF',
1038
		'AF',
1039
		'EU',
1040
		'EU',
1041
		'AF',
1042
		'OC',
1043
		'EU',
1044
		'AF',
1045
		'AS',
1046
		'AS',
1047
		'AS',
1048
		'OC',
1049
		'NA',
1050
		'AF',
1051
		'NA',
1052
		'EU',
1053
		'AF',
1054
		'AS',
1055
		'AF',
1056
		'NA',
1057
		'AS',
1058
		'AF',
1059
		'AF',
1060
		'OC',
1061
		'AF',
1062
		'OC',
1063
		'AF',
1064
		'NA',
1065
		'EU',
1066
		'EU',
1067
		'AS',
1068
		'OC',
1069
		'OC',
1070
		'OC',
1071
		'AS',
1072
		'NA',
1073
		'SA',
1074
		'OC',
1075
		'OC',
1076
		'AS',
1077
		'AS',
1078
		'EU',
1079
		'NA',
1080
		'OC',
1081
		'NA',
1082
		'AS',
1083
		'EU',
1084
		'OC',
1085
		'SA',
1086
		'AS',
1087
		'AF',
1088
		'EU',
1089
		'EU',
1090
		'AF',
1091
		'AS',
1092
		'OC',
1093
		'AF',
1094
		'AF',
1095
		'EU',
1096
		'AS',
1097
		'AF',
1098
		'EU',
1099
		'EU',
1100
		'EU',
1101
		'AF',
1102
		'EU',
1103
		'AF',
1104
		'AF',
1105
		'SA',
1106
		'AF',
1107
		'NA',
1108
		'AS',
1109
		'AF',
1110
		'NA',
1111
		'AF',
1112
		'AN',
1113
		'AF',
1114
		'AS',
1115
		'AS',
1116
		'OC',
1117
		'AS',
1118
		'AF',
1119
		'OC',
1120
		'AS',
1121
		'EU',
1122
		'NA',
1123
		'OC',
1124
		'AS',
1125
		'AF',
1126
		'EU',
1127
		'AF',
1128
		'OC',
1129
		'NA',
1130
		'SA',
1131
		'AS',
1132
		'EU',
1133
		'NA',
1134
		'SA',
1135
		'NA',
1136
		'NA',
1137
		'AS',
1138
		'OC',
1139
		'OC',
1140
		'OC',
1141
		'AS',
1142
		'AF',
1143
		'EU',
1144
		'AF',
1145
		'AF',
1146
		'EU',
1147
		'AF',
1148
		'--',
1149
		'--',
1150
		'--',
1151
		'EU',
1152
		'EU',
1153
		'EU',
1154
		'EU',
1155
		'NA',
1156
		'NA',
1157
		'NA',
1158
		'AF',
1159
		'--'
1160
	);
1161
1162
	/** @var WC_Logger Logger instance */
1163
	public static $log = false;
1164
1165
	/**
1166
	 * Logging method.
1167
	 *
1168
	 * @param string $message
1169
	 */
1170
	public static function log( $message ) {
1171
		if ( ! class_exists( 'WC_Logger' ) ) {
1172
			include_once( 'class-wc-logger.php' );
1173
		}
1174
1175
		if ( empty( self::$log ) ) {
1176
			self::$log = new WC_Logger();
1177
		}
1178
		self::$log->add( 'geoip', $message );
1179
	}
1180
1181
	/**
1182
	 * Open geoip file.
1183
	 *
1184
	 * @param string $filename
1185
	 * @param int    $flags
1186
	 */
1187
	public function geoip_open( $filename, $flags ) {
1188
		$this->flags = $flags;
1189
		if ( $this->flags & self::GEOIP_SHARED_MEMORY ) {
1190
			$this->shmid = @shmop_open( self::GEOIP_SHM_KEY, 'a', 0, 0 );
1191
		} else {
1192
			if ( $this->filehandle = fopen( $filename, 'rb' ) ) {
1193
				if ( $this->flags & self::GEOIP_MEMORY_CACHE ) {
1194
					$s_array = fstat( $this->filehandle );
1195
					$this->memory_buffer = fread( $this->filehandle, $s_array['size'] );
1196
				}
1197
			} else {
1198
				$this->log( 'GeoIP API: Can not open ' . $filename );
1199
			}
1200
		}
1201
1202
		$this->_setup_segments();
1203
	}
1204
1205
	/**
1206
	 * Setup segments.
1207
	 *
1208
	 * @return WC_Geo_IP instance
1209
	 */
1210
	private function _setup_segments() {
1211
		$this->databaseType  = self::GEOIP_COUNTRY_EDITION;
0 ignored issues
show
Documentation Bug introduced by
The property $databaseType was declared of type string, but self::GEOIP_COUNTRY_EDITION is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
1212
		$this->record_length = self::STANDARD_RECORD_LENGTH;
1213
1214
		if ( $this->flags & self::GEOIP_SHARED_MEMORY ) {
1215
			$offset = @shmop_size( $this->shmid ) - 3;
1216
1217
			for ( $i = 0; $i < self::STRUCTURE_INFO_MAX_SIZE; $i++ ) {
1218
				$delim   = @shmop_read( $this->shmid, $offset, 3 );
1219
				$offset += 3;
1220
1221
				if ( $delim == ( chr( 255 ) . chr( 255 ) . chr( 255 ) ) ) {
1222
					$this->databaseType = ord( @shmop_read( $this->shmid, $offset, 1 ) );
0 ignored issues
show
Documentation Bug introduced by
The property $databaseType was declared of type string, but ord(@shmop_read($this->shmid, $offset, 1)) is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
1223
1224
					if ( $this->databaseType >= 106 ) {
1225
						$this->databaseType -= 105;
1226
					}
1227
1228
					$offset++;
1229
1230
					if ( $this->databaseType == self::GEOIP_REGION_EDITION_REV0 ) {
1231
						$this->databaseSegments = self::GEOIP_STATE_BEGIN_REV0;
1232
					} elseif ( $this->databaseType == self::GEOIP_REGION_EDITION_REV1 ) {
1233
						$this->databaseSegments = self::GEOIP_STATE_BEGIN_REV1;
1234
					} elseif ( ( $this->databaseType == self::GEOIP_CITY_EDITION_REV0 )
1235
						|| ( $this->databaseType == self::GEOIP_CITY_EDITION_REV1 )
1236
						|| ( $this->databaseType == self::GEOIP_ORG_EDITION )
1237
						|| ( $this->databaseType == self::GEOIP_ORG_EDITION_V6 )
1238
						|| ( $this->databaseType == self::GEOIP_DOMAIN_EDITION )
1239
						|| ( $this->databaseType == self::GEOIP_DOMAIN_EDITION_V6 )
1240
						|| ( $this->databaseType == self::GEOIP_ISP_EDITION )
1241
						|| ( $this->databaseType == self::GEOIP_ISP_EDITION_V6 )
1242
						|| ( $this->databaseType == self::GEOIP_USERTYPE_EDITION )
1243
						|| ( $this->databaseType == self::GEOIP_USERTYPE_EDITION_V6 )
1244
						|| ( $this->databaseType == self::GEOIP_LOCATIONA_EDITION )
1245
						|| ( $this->databaseType == self::GEOIP_ACCURACYRADIUS_EDITION )
1246
						|| ( $this->databaseType == self::GEOIP_CITY_EDITION_REV0_V6 )
1247
						|| ( $this->databaseType == self::GEOIP_CITY_EDITION_REV1_V6 )
1248
						|| ( $this->databaseType == self::GEOIP_NETSPEED_EDITION_REV1 )
1249
						|| ( $this->databaseType == self::GEOIP_NETSPEED_EDITION_REV1_V6 )
1250
						|| ( $this->databaseType == self::GEOIP_ASNUM_EDITION )
1251
						|| ( $this->databaseType == self::GEOIP_ASNUM_EDITION_V6 )
1252
					) {
1253
						$this->databaseSegments = 0;
1254
						$buf                    = @shmop_read( $this->shmid, $offset, self::SEGMENT_RECORD_LENGTH );
1255
1256
						for ( $j = 0; $j < self::SEGMENT_RECORD_LENGTH; $j++ ) {
1257
							$this->databaseSegments += ( ord( $buf[ $j ] ) << ( $j * 8 ) );
1258
						}
1259
1260
						if ( ( $this->databaseType == self::GEOIP_ORG_EDITION )
1261
							|| ( $this->databaseType == self::GEOIP_ORG_EDITION_V6 )
1262
							|| ( $this->databaseType == self::GEOIP_DOMAIN_EDITION )
1263
							|| ( $this->databaseType == self::GEOIP_DOMAIN_EDITION_V6 )
1264
							|| ( $this->databaseType == self::GEOIP_ISP_EDITION )
1265
							|| ( $this->databaseType == self::GEOIP_ISP_EDITION_V6 )
1266
						) {
1267
							$this->record_length = self::ORG_RECORD_LENGTH;
1268
						}
1269
					}
1270
1271
					break;
1272
				} else {
1273
					$offset -= 4;
1274
				}
1275
			}
1276 View Code Duplication
			if ( ( $this->databaseType == self::GEOIP_COUNTRY_EDITION )
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1277
				|| ( $this->databaseType == self::GEOIP_COUNTRY_EDITION_V6 )
1278
				|| ( $this->databaseType == self::GEOIP_PROXY_EDITION )
1279
				|| ( $this->databaseType == self::GEOIP_NETSPEED_EDITION )
1280
			) {
1281
				$this->databaseSegments = self::GEOIP_COUNTRY_BEGIN;
1282
			}
1283
		} else {
1284
			$filepos = ftell( $this->filehandle );
1285
			fseek( $this->filehandle, -3, SEEK_END );
1286
1287
			for ( $i = 0; $i < self::STRUCTURE_INFO_MAX_SIZE; $i++ ) {
1288
1289
				$delim = fread( $this->filehandle, 3 );
1290
				if ( $delim == ( chr( 255 ) . chr( 255 ) . chr( 255 ) ) ) {
1291
1292
					$this->databaseType = ord( fread( $this->filehandle, 1 ) );
0 ignored issues
show
Documentation Bug introduced by
The property $databaseType was declared of type string, but ord(fread($this->filehandle, 1)) is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
1293
					if ( $this->databaseType >= 106 ) {
1294
						$this->databaseType -= 105;
1295
					}
1296
1297
					if ( $this->databaseType == self::GEOIP_REGION_EDITION_REV0 ) {
1298
						$this->databaseSegments = self::GEOIP_STATE_BEGIN_REV0;
1299
					} elseif ( $this->databaseType == self::GEOIP_REGION_EDITION_REV1 ) {
1300
						$this->databaseSegments = self::GEOIP_STATE_BEGIN_REV1;
1301
					} elseif ( ( $this->databaseType == self::GEOIP_CITY_EDITION_REV0 )
1302
						|| ( $this->databaseType == self::GEOIP_CITY_EDITION_REV1 )
1303
						|| ( $this->databaseType == self::GEOIP_CITY_EDITION_REV0_V6 )
1304
						|| ( $this->databaseType == self::GEOIP_CITY_EDITION_REV1_V6 )
1305
						|| ( $this->databaseType == self::GEOIP_ORG_EDITION )
1306
						|| ( $this->databaseType == self::GEOIP_DOMAIN_EDITION )
1307
						|| ( $this->databaseType == self::GEOIP_ISP_EDITION )
1308
						|| ( $this->databaseType == self::GEOIP_ORG_EDITION_V6 )
1309
						|| ( $this->databaseType == self::GEOIP_DOMAIN_EDITION_V6 )
1310
						|| ( $this->databaseType == self::GEOIP_ISP_EDITION_V6 )
1311
						|| ( $this->databaseType == self::GEOIP_LOCATIONA_EDITION )
1312
						|| ( $this->databaseType == self::GEOIP_ACCURACYRADIUS_EDITION )
1313
						|| ( $this->databaseType == self::GEOIP_CITY_EDITION_REV0_V6 )
1314
						|| ( $this->databaseType == self::GEOIP_CITY_EDITION_REV1_V6 )
1315
						|| ( $this->databaseType == self::GEOIP_NETSPEED_EDITION_REV1 )
1316
						|| ( $this->databaseType == self::GEOIP_NETSPEED_EDITION_REV1_V6 )
1317
						|| ( $this->databaseType == self::GEOIP_USERTYPE_EDITION )
1318
						|| ( $this->databaseType == self::GEOIP_USERTYPE_EDITION_V6 )
1319
						|| ( $this->databaseType == self::GEOIP_ASNUM_EDITION )
1320
						|| ( $this->databaseType == self::GEOIP_ASNUM_EDITION_V6 )
1321
					) {
1322
						$this->databaseSegments = 0;
1323
						$buf = fread( $this->filehandle, self::SEGMENT_RECORD_LENGTH );
1324
1325
						for ( $j = 0; $j < self::SEGMENT_RECORD_LENGTH; $j++ ) {
1326
							$this->databaseSegments += ( ord( $buf[ $j ] ) << ( $j * 8 ) );
1327
						}
1328
1329
						if ( ( $this->databaseType == self::GEOIP_ORG_EDITION )
1330
							|| ( $this->databaseType == self::GEOIP_DOMAIN_EDITION )
1331
							|| ( $this->databaseType == self::GEOIP_ISP_EDITION )
1332
							|| ( $this->databaseType == self::GEOIP_ORG_EDITION_V6 )
1333
							|| ( $this->databaseType == self::GEOIP_DOMAIN_EDITION_V6 )
1334
							|| ( $this->databaseType == self::GEOIP_ISP_EDITION_V6 )
1335
						) {
1336
							$this->record_length = self::ORG_RECORD_LENGTH;
1337
						}
1338
					}
1339
1340
					break;
1341
				} else {
1342
					fseek( $this->filehandle, -4, SEEK_CUR );
1343
				}
1344
			}
1345
1346 View Code Duplication
			if ( ( $this->databaseType == self::GEOIP_COUNTRY_EDITION )
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1347
				|| ( $this->databaseType == self::GEOIP_COUNTRY_EDITION_V6 )
1348
				|| ( $this->databaseType == self::GEOIP_PROXY_EDITION )
1349
				|| ( $this->databaseType == self::GEOIP_NETSPEED_EDITION )
1350
			) {
1351
				$this->databaseSegments = self::GEOIP_COUNTRY_BEGIN;
1352
			}
1353
1354
			fseek( $this->filehandle, $filepos, SEEK_SET );
1355
		}
1356
1357
		return $this;
1358
	}
1359
1360
	/**
1361
	 * Close geoip file.
1362
	 *
1363
	 * @return bool
1364
	 */
1365
	public function geoip_close() {
1366
		if ( $this->flags & self::GEOIP_SHARED_MEMORY ) {
1367
			return true;
1368
		}
1369
1370
		return fclose( $this->filehandle );
1371
	}
1372
1373
	/**
1374
	 * Common get record.
1375
	 *
1376
	 * @param  string $seek_country
1377
	 * @return WC_Geo_IP_Record instance
1378
	 */
1379
	private function _common_get_record( $seek_country ) {
1380
		// workaround php's broken substr, strpos, etc handling with
1381
		// mbstring.func_overload and mbstring.internal_encoding
1382
		$mbExists = extension_loaded( 'mbstring' );
1383
		if ( $mbExists ) {
1384
			$enc = mb_internal_encoding();
1385
			mb_internal_encoding( 'ISO-8859-1' );
1386
		}
1387
1388
		$record_pointer = $seek_country + ( 2 * $this->record_length - 1 ) * $this->databaseSegments;
1389
1390
		if ( $this->flags & self::GEOIP_MEMORY_CACHE ) {
1391
			$record_buf = substr( $this->memory_buffer, $record_pointer, FULL_RECORD_LENGTH );
1392
		} elseif ( $this->flags & self::GEOIP_SHARED_MEMORY ) {
1393
			$record_buf = @shmop_read( $this->shmid, $record_pointer, FULL_RECORD_LENGTH );
1394
		} else {
1395
			fseek( $this->filehandle, $record_pointer, SEEK_SET );
1396
			$record_buf = fread( $this->filehandle, FULL_RECORD_LENGTH );
1397
		}
1398
1399
		$record                 = new WC_Geo_IP_Record();
1400
		$record_buf_pos         = 0;
1401
		$char                   = ord( substr( $record_buf, $record_buf_pos, 1 ) );
1402
		$record->country_code   = $this->GEOIP_COUNTRY_CODES[ $char ];
1403
		$record->country_code3  = $this->GEOIP_COUNTRY_CODES3[ $char ];
1404
		$record->country_name   = $this->GEOIP_COUNTRY_NAMES[ $char ];
1405
		$record->continent_code = $this->GEOIP_CONTINENT_CODES[ $char ];
1406
		$str_length             = 0;
1407
1408
		$record_buf_pos++;
1409
1410
		// Get region
1411
		$char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) );
1412 View Code Duplication
		while ( $char != 0 ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1413
			$str_length++;
1414
			$char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) );
1415
		}
1416
1417
		if ( $str_length > 0 ) {
1418
			$record->region = substr( $record_buf, $record_buf_pos, $str_length );
1419
		}
1420
1421
		$record_buf_pos += $str_length + 1;
1422
		$str_length      = 0;
1423
1424
		// Get city
1425
		$char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) );
1426 View Code Duplication
		while ( $char != 0 ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1427
			$str_length++;
1428
			$char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) );
1429
		}
1430
1431
		if ( $str_length > 0 ) {
1432
			$record->city = substr( $record_buf, $record_buf_pos, $str_length );
1433
		}
1434
1435
		$record_buf_pos += $str_length + 1;
1436
		$str_length      = 0;
1437
1438
		// Get postal code
1439
		$char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) );
1440 View Code Duplication
		while ( $char != 0 ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1441
			$str_length++;
1442
			$char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) );
1443
		}
1444
1445
		if ( $str_length > 0 ) {
1446
			$record->postal_code = substr( $record_buf, $record_buf_pos, $str_length );
1447
		}
1448
1449
		$record_buf_pos += $str_length + 1;
1450
1451
		// Get latitude and longitude
1452
		$latitude  = 0;
1453
		$longitude = 0;
1454 View Code Duplication
		for ( $j = 0; $j < 3; ++$j ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1455
			$char      = ord( substr( $record_buf, $record_buf_pos++, 1 ) );
1456
			$latitude += ( $char << ( $j * 8 ) );
1457
		}
1458
1459
		$record->latitude = ( $latitude / 10000 ) - 180;
0 ignored issues
show
Documentation Bug introduced by
The property $latitude was declared of type double, but $latitude / 10000 - 180 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
1460
1461 View Code Duplication
		for ( $j = 0; $j < 3; ++$j ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1462
			$char       = ord( substr( $record_buf, $record_buf_pos++, 1 ) );
1463
			$longitude += ( $char << ( $j * 8 ) );
1464
		}
1465
1466
		$record->longitude = ( $longitude / 10000 ) - 180;
0 ignored issues
show
Documentation Bug introduced by
The property $longitude was declared of type double, but $longitude / 10000 - 180 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
1467
1468
		if ( self::GEOIP_CITY_EDITION_REV1 == $this->databaseType ) {
1469
			$metroarea_combo = 0;
1470
			if ( $record->country_code == "US" ) {
1471 View Code Duplication
				for ( $j = 0; $j < 3; ++$j ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1472
					$char             = ord( substr( $record_buf, $record_buf_pos++, 1 ) );
1473
					$metroarea_combo += ( $char << ( $j * 8 ) );
1474
				}
1475
1476
				$record->metro_code = $record->dma_code = floor( $metroarea_combo / 1000 );
0 ignored issues
show
Documentation Bug introduced by
The property $dma_code was declared of type integer, but floor($metroarea_combo / 1000) is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
Documentation Bug introduced by
The property $metro_code was declared of type integer, but $record->dma_code = floo...metroarea_combo / 1000) is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
1477
				$record->area_code  = $metroarea_combo % 1000;
0 ignored issues
show
Documentation Bug introduced by
The property $area_code was declared of type string, but $metroarea_combo % 1000 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
1478
			}
1479
		}
1480
1481
		if ( $mbExists ) {
1482
			mb_internal_encoding( $enc );
1483
		}
1484
1485
		return $record;
1486
	}
1487
1488
	/**
1489
	 * Get record.
1490
	 *
1491
	 * @param  int $ipnum
1492
	 * @return WC_Geo_IP_Record instance
1493
	 */
1494
	private function _get_record( $ipnum ) {
1495
		$seek_country = $this->_geoip_seek_country( $ipnum );
1496
		if ( $seek_country == $this->databaseSegments ) {
1497
			return null;
1498
		}
1499
1500
		return $this->_common_get_record( $seek_country );
0 ignored issues
show
Documentation introduced by
$seek_country is of type integer|false, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1501
	}
1502
1503
	/**
1504
	 * Seek country IPv6.
1505
	 *
1506
	 * @param  int $ipnum
1507
	 * @return string
1508
	 */
1509
	public function _geoip_seek_country_v6( $ipnum ) {
1510
		// arrays from unpack start with offset 1
1511
		// yet another php mystery. array_merge work around
1512
		// this broken behaviour
1513
		$v6vec = array_merge( unpack( 'C16', $ipnum ) );
1514
1515
		$offset = 0;
1516
		for ( $depth = 127; $depth >= 0; --$depth ) {
1517 View Code Duplication
			if ( $this->flags & self::GEOIP_MEMORY_CACHE ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1518
				$buf = $this->_safe_substr(
1519
					$this->memory_buffer,
1520
					2 * $this->record_length * $offset,
1521
					2 * $this->record_length
1522
				);
1523
			} elseif ( $this->flags & self::GEOIP_SHARED_MEMORY ) {
1524
				$buf = @shmop_read(
1525
					$this->shmid,
1526
					2 * $this->record_length * $offset,
1527
					2 * $this->record_length
1528
				);
1529
			} else {
1530
				if ( 0 != fseek( $this->filehandle, 2 * $this->record_length * $offset, SEEK_SET ) ) {
1531
					break;
1532
				}
1533
1534
				$buf = fread( $this->filehandle, 2 * $this->record_length );
1535
			}
1536
			$x = array( 0, 0 );
1537 View Code Duplication
			for ( $i = 0; $i < 2; ++$i ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1538
				for ( $j = 0; $j < $this->record_length; ++$j ) {
1539
					$x[ $i ] += ord( $buf[ $this->record_length * $i + $j ] ) << ( $j * 8 );
1540
				}
1541
			}
1542
1543
			$bnum = 127 - $depth;
1544
			$idx = $bnum >> 3;
1545
			$b_mask = 1 << ( $bnum & 7 ^ 7 );
1546 View Code Duplication
			if ( ( $v6vec[ $idx ] & $b_mask ) > 0 ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1547
				if ( $x[1] >= $this->databaseSegments ) {
1548
					return $x[1];
1549
				}
1550
				$offset = $x[1];
1551
			} else {
1552
				if ( $x[0] >= $this->databaseSegments ) {
1553
					return $x[0];
1554
				}
1555
				$offset = $x[0];
1556
			}
1557
		}
1558
1559
		$this->log( 'GeoIP API: Error traversing database - perhaps it is corrupt?' );
1560
1561
		return false;
1562
	}
1563
1564
	/**
1565
	 * Seek country.
1566
	 *
1567
	 * @param  int $ipnum
1568
	 * @return string
1569
	 */
1570
	private function _geoip_seek_country( $ipnum ) {
1571
		$offset = 0;
1572
		for ( $depth = 31; $depth >= 0; --$depth ) {
1573 View Code Duplication
			if ( $this->flags & self::GEOIP_MEMORY_CACHE ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1574
				$buf = $this->_safe_substr(
1575
					$this->memory_buffer,
1576
					2 * $this->record_length * $offset,
1577
					2 * $this->record_length
1578
				);
1579
			} elseif ( $this->flags & self::GEOIP_SHARED_MEMORY ) {
1580
				$buf = @shmop_read(
1581
					$this->shmid,
1582
					2 * $this->record_length * $offset,
1583
					2 * $this->record_length
1584
				);
1585
			} else {
1586
				if ( 0 != fseek( $this->filehandle, 2 * $this->record_length * $offset, SEEK_SET ) ) {
1587
					break;
1588
				}
1589
1590
				$buf = fread( $this->filehandle, 2 * $this->record_length );
1591
			}
1592
1593
			$x = array( 0, 0 );
1594 View Code Duplication
			for ( $i = 0; $i < 2; ++$i ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1595
				for ( $j = 0; $j < $this->record_length; ++$j ) {
1596
					$x[ $i ] += ord( $buf[ $this->record_length * $i + $j ] ) << ( $j * 8 );
1597
				}
1598
			}
1599 View Code Duplication
			if ( $ipnum & ( 1 << $depth ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1600
				if ( $x[1] >= $this->databaseSegments ) {
1601
					return $x[1];
1602
				}
1603
1604
				$offset = $x[1];
1605
			} else {
1606
				if ( $x[0] >= $this->databaseSegments ) {
1607
					return $x[0];
1608
				}
1609
1610
				$offset = $x[0];
1611
			}
1612
		}
1613
1614
		$this->log( 'GeoIP API: Error traversing database - perhaps it is corrupt?' );
1615
1616
		return false;
1617
	}
1618
1619
	/**
1620
	 * Record by addr.
1621
	 *
1622
	 * @param  string $addr
1623
	 * @return int
1624
	 */
1625
	public function geoip_record_by_addr( $addr ) {
1626
		if ( $addr == null ) {
1627
			return 0;
1628
		}
1629
1630
		$ipnum = ip2long( $addr );
1631
		return $this->_get_record( $ipnum );
1632
	}
1633
1634
	/**
1635
	 * Country ID by addr IPv6.
1636
	 *
1637
	 * @param  string $addr
1638
	 * @return int
1639
	 */
1640
	public function geoip_country_id_by_addr_v6( $addr ) {
1641
		$ipnum = inet_pton( $addr );
1642
		return $this->_geoip_seek_country_v6( $ipnum ) - self::GEOIP_COUNTRY_BEGIN;
1643
	}
1644
1645
	/**
1646
	 * Country ID by addr.
1647
	 *
1648
	 * @param  string $addr
1649
	 * @return int
1650
	 */
1651
	public function geoip_country_id_by_addr( $addr ) {
1652
		$ipnum = ip2long( $addr );
1653
		return $this->_geoip_seek_country( $ipnum ) - self::GEOIP_COUNTRY_BEGIN;
1654
	}
1655
1656
	/**
1657
	 * Country code by addr IPv6.
1658
	 *
1659
	 * @param  string $addr
1660
	 * @return string
1661
	 */
1662
	public function geoip_country_code_by_addr_v6( $addr ) {
1663
		$country_id = $this->geoip_country_id_by_addr_v6( $addr );
1664 View Code Duplication
		if ( $country_id !== false && isset( $this->GEOIP_COUNTRY_CODES[ $country_id ] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1665
			return $this->GEOIP_COUNTRY_CODES[ $country_id ];
1666
		}
1667
1668
		return false;
1669
	}
1670
1671
	/**
1672
	 * Country code by addr.
1673
	 *
1674
	 * @param  string $addr
1675
	 * @return string
1676
	 */
1677
	public function geoip_country_code_by_addr( $addr ) {
1678
		if ( $this->databaseType == self::GEOIP_CITY_EDITION_REV1 ) {
1679
			$record = $this->geoip_record_by_addr( $addr );
1680
			if ( $record !== false ) {
1681
				return $record->country_code;
1682
			}
1683 View Code Duplication
		} else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1684
			$country_id = $this->geoip_country_id_by_addr( $addr );
1685
			if ( $country_id !== false && isset( $this->GEOIP_COUNTRY_CODES[ $country_id ] ) ) {
1686
				return $this->GEOIP_COUNTRY_CODES[ $country_id ];
1687
			}
1688
		}
1689
1690
		return false;
1691
	}
1692
1693
	/**
1694
	 * Encode string.
1695
	 *
1696
	 * @param  string $string
1697
	 * @param  int    $start
1698
	 * @param  int    $length
1699
	 * @return string
1700
	 */
1701
	private function _safe_substr( $string, $start, $length ) {
1702
		// workaround php's broken substr, strpos, etc handling with
1703
		// mbstring.func_overload and mbstring.internal_encoding
1704
		$mb_exists = extension_loaded( 'mbstring' );
1705
1706
		if ( $mb_exists ) {
1707
			$enc = mb_internal_encoding();
1708
			mb_internal_encoding( 'ISO-8859-1' );
1709
		}
1710
1711
		$buf = substr( $string, $start, $length );
1712
1713
		if ( $mb_exists ) {
1714
			mb_internal_encoding( $enc );
1715
		}
1716
1717
		return $buf;
1718
	}
1719
}
1720
1721
/**
1722
 * Geo IP Record class.
1723
 */
1724
class WC_Geo_IP_Record {
1725
1726
	/**
1727
	 * Country code.
1728
	 *
1729
	 * @var string
1730
	 */
1731
	public $country_code;
1732
1733
	/**
1734
	 * 3 letters country code.
1735
	 *
1736
	 * @var string
1737
	 */
1738
	public $country_code3;
1739
1740
	/**
1741
	 * Country name.
1742
	 *
1743
	 * @var string
1744
	 */
1745
	public $country_name;
1746
1747
	/**
1748
	 * Region.
1749
	 *
1750
	 * @var string
1751
	 */
1752
	public $region;
1753
1754
	/**
1755
	 * City.
1756
	 *
1757
	 * @var string
1758
	 */
1759
	public $city;
1760
1761
	/**
1762
	 * Postal code.
1763
	 *
1764
	 * @var string
1765
	 */
1766
	public $postal_code;
1767
1768
	/**
1769
	 * Latitude
1770
	 *
1771
	 * @var float
1772
	 */
1773
	public $latitude;
1774
1775
	/**
1776
	 * Longitude.
1777
	 *
1778
	 * @var float
1779
	 */
1780
	public $longitude;
1781
1782
	/**
1783
	 * Area code.
1784
	 *
1785
	 * @var string
1786
	 */
1787
	public $area_code;
1788
1789
	/**
1790
	 * DMA Code.
1791
	 *
1792
	 * Metro and DMA code are the same.
1793
	 * Use metro code instead.
1794
	 *
1795
	 * @var int
1796
	 */
1797
	public $dma_code;
1798
1799
	/**
1800
	 * Metro code.
1801
	 *
1802
	 * @var int
1803
	 */
1804
	public $metro_code;
1805
1806
	/**
1807
	 * Continent code.
1808
	 *
1809
	 * @var string
1810
	 */
1811
	public $continent_code;
1812
}
1813