WC_Geo_IP

WC_Geo_IP Class.

Defined (1)

The class is defined in the following location(s).

/includes/class-wc-geo-ip.php  
  1. class WC_Geo_IP { 
  2.  
  3. const GEOIP_COUNTRY_BEGIN = 16776960; 
  4. const GEOIP_STATE_BEGIN_REV0 = 16700000; 
  5. const GEOIP_STATE_BEGIN_REV1 = 16000000; 
  6. const GEOIP_MEMORY_CACHE = 1; 
  7. const GEOIP_SHARED_MEMORY = 2; 
  8. const STRUCTURE_INFO_MAX_SIZE = 20; 
  9. const GEOIP_COUNTRY_EDITION = 1; 
  10. const GEOIP_PROXY_EDITION = 8; 
  11. const GEOIP_ASNUM_EDITION = 9; 
  12. const GEOIP_NETSPEED_EDITION = 10; 
  13. const GEOIP_REGION_EDITION_REV0 = 7; 
  14. const GEOIP_REGION_EDITION_REV1 = 3; 
  15. const GEOIP_CITY_EDITION_REV0 = 6; 
  16. const GEOIP_CITY_EDITION_REV1 = 2; 
  17. const GEOIP_ORG_EDITION = 5; 
  18. const GEOIP_ISP_EDITION = 4; 
  19. const SEGMENT_RECORD_LENGTH = 3; 
  20. const STANDARD_RECORD_LENGTH = 3; 
  21. const ORG_RECORD_LENGTH = 4; 
  22. const GEOIP_SHM_KEY = 0x4f415401; 
  23. const GEOIP_DOMAIN_EDITION = 11; 
  24. const GEOIP_COUNTRY_EDITION_V6 = 12; 
  25. const GEOIP_LOCATIONA_EDITION = 13; 
  26. const GEOIP_ACCURACYRADIUS_EDITION = 14; 
  27. const GEOIP_CITY_EDITION_REV1_V6 = 30; 
  28. const GEOIP_CITY_EDITION_REV0_V6 = 31; 
  29. const GEOIP_NETSPEED_EDITION_REV1 = 32; 
  30. const GEOIP_NETSPEED_EDITION_REV1_V6 = 33; 
  31. const GEOIP_USERTYPE_EDITION = 28; 
  32. const GEOIP_USERTYPE_EDITION_V6 = 29; 
  33. const GEOIP_ASNUM_EDITION_V6 = 21; 
  34. const GEOIP_ISP_EDITION_V6 = 22; 
  35. const GEOIP_ORG_EDITION_V6 = 23; 
  36. const GEOIP_DOMAIN_EDITION_V6 = 24; 
  37.  
  38. /** 
  39. * Flags. 
  40. * @var int 
  41. */ 
  42. public $flags; 
  43.  
  44. /** 
  45. * File handler. 
  46. * @var resource 
  47. */ 
  48. public $filehandle; 
  49.  
  50. /** 
  51. * Memory buffer. 
  52. * @var string 
  53. */ 
  54. public $memory_buffer; 
  55.  
  56. /** 
  57. * Database type. 
  58. * @var int 
  59. */ 
  60. public $databaseType; 
  61.  
  62. /** 
  63. * Database segments. 
  64. * @var int 
  65. */ 
  66. public $databaseSegments; 
  67.  
  68. /** 
  69. * Record length. 
  70. * @var int 
  71. */ 
  72. public $record_length; 
  73.  
  74. /** 
  75. * Shmid. 
  76. * @var string 
  77. */ 
  78. public $shmid; 
  79.  
  80. /** 
  81. * Two letters country codes. 
  82. * @var array 
  83. */ 
  84. public $GEOIP_COUNTRY_CODES = array( 
  85. '',  
  86. 'AP',  
  87. 'EU',  
  88. 'AD',  
  89. 'AE',  
  90. 'AF',  
  91. 'AG',  
  92. 'AI',  
  93. 'AL',  
  94. 'AM',  
  95. 'CW',  
  96. 'AO',  
  97. 'AQ',  
  98. 'AR',  
  99. 'AS',  
  100. 'AT',  
  101. 'AU',  
  102. 'AW',  
  103. 'AZ',  
  104. 'BA',  
  105. 'BB',  
  106. 'BD',  
  107. 'BE',  
  108. 'BF',  
  109. 'BG',  
  110. 'BH',  
  111. 'BI',  
  112. 'BJ',  
  113. 'BM',  
  114. 'BN',  
  115. 'BO',  
  116. 'BR',  
  117. 'BS',  
  118. 'BT',  
  119. 'BV',  
  120. 'BW',  
  121. 'BY',  
  122. 'BZ',  
  123. 'CA',  
  124. 'CC',  
  125. 'CD',  
  126. 'CF',  
  127. 'CG',  
  128. 'CH',  
  129. 'CI',  
  130. 'CK',  
  131. 'CL',  
  132. 'CM',  
  133. 'CN',  
  134. 'CO',  
  135. 'CR',  
  136. 'CU',  
  137. 'CV',  
  138. 'CX',  
  139. 'CY',  
  140. 'CZ',  
  141. 'DE',  
  142. 'DJ',  
  143. 'DK',  
  144. 'DM',  
  145. 'DO',  
  146. 'DZ',  
  147. 'EC',  
  148. 'EE',  
  149. 'EG',  
  150. 'EH',  
  151. 'ER',  
  152. 'ES',  
  153. 'ET',  
  154. 'FI',  
  155. 'FJ',  
  156. 'FK',  
  157. 'FM',  
  158. 'FO',  
  159. 'FR',  
  160. 'SX',  
  161. 'GA',  
  162. 'GB',  
  163. 'GD',  
  164. 'GE',  
  165. 'GF',  
  166. 'GH',  
  167. 'GI',  
  168. 'GL',  
  169. 'GM',  
  170. 'GN',  
  171. 'GP',  
  172. 'GQ',  
  173. 'GR',  
  174. 'GS',  
  175. 'GT',  
  176. 'GU',  
  177. 'GW',  
  178. 'GY',  
  179. 'HK',  
  180. 'HM',  
  181. 'HN',  
  182. 'HR',  
  183. 'HT',  
  184. 'HU',  
  185. 'ID',  
  186. 'IE',  
  187. 'IL',  
  188. 'IN',  
  189. 'IO',  
  190. 'IQ',  
  191. 'IR',  
  192. 'IS',  
  193. 'IT',  
  194. 'JM',  
  195. 'JO',  
  196. 'JP',  
  197. 'KE',  
  198. 'KG',  
  199. 'KH',  
  200. 'KI',  
  201. 'KM',  
  202. 'KN',  
  203. 'KP',  
  204. 'KR',  
  205. 'KW',  
  206. 'KY',  
  207. 'KZ',  
  208. 'LA',  
  209. 'LB',  
  210. 'LC',  
  211. 'LI',  
  212. 'LK',  
  213. 'LR',  
  214. 'LS',  
  215. 'LT',  
  216. 'LU',  
  217. 'LV',  
  218. 'LY',  
  219. 'MA',  
  220. 'MC',  
  221. 'MD',  
  222. 'MG',  
  223. 'MH',  
  224. 'MK',  
  225. 'ML',  
  226. 'MM',  
  227. 'MN',  
  228. 'MO',  
  229. 'MP',  
  230. 'MQ',  
  231. 'MR',  
  232. 'MS',  
  233. 'MT',  
  234. 'MU',  
  235. 'MV',  
  236. 'MW',  
  237. 'MX',  
  238. 'MY',  
  239. 'MZ',  
  240. 'NA',  
  241. 'NC',  
  242. 'NE',  
  243. 'NF',  
  244. 'NG',  
  245. 'NI',  
  246. 'NL',  
  247. 'NO',  
  248. 'NP',  
  249. 'NR',  
  250. 'NU',  
  251. 'NZ',  
  252. 'OM',  
  253. 'PA',  
  254. 'PE',  
  255. 'PF',  
  256. 'PG',  
  257. 'PH',  
  258. 'PK',  
  259. 'PL',  
  260. 'PM',  
  261. 'PN',  
  262. 'PR',  
  263. 'PS',  
  264. 'PT',  
  265. 'PW',  
  266. 'PY',  
  267. 'QA',  
  268. 'RE',  
  269. 'RO',  
  270. 'RU',  
  271. 'RW',  
  272. 'SA',  
  273. 'SB',  
  274. 'SC',  
  275. 'SD',  
  276. 'SE',  
  277. 'SG',  
  278. 'SH',  
  279. 'SI',  
  280. 'SJ',  
  281. 'SK',  
  282. 'SL',  
  283. 'SM',  
  284. 'SN',  
  285. 'SO',  
  286. 'SR',  
  287. 'ST',  
  288. 'SV',  
  289. 'SY',  
  290. 'SZ',  
  291. 'TC',  
  292. 'TD',  
  293. 'TF',  
  294. 'TG',  
  295. 'TH',  
  296. 'TJ',  
  297. 'TK',  
  298. 'TM',  
  299. 'TN',  
  300. 'TO',  
  301. 'TL',  
  302. 'TR',  
  303. 'TT',  
  304. 'TV',  
  305. 'TW',  
  306. 'TZ',  
  307. 'UA',  
  308. 'UG',  
  309. 'UM',  
  310. 'US',  
  311. 'UY',  
  312. 'UZ',  
  313. 'VA',  
  314. 'VC',  
  315. 'VE',  
  316. 'VG',  
  317. 'VI',  
  318. 'VN',  
  319. 'VU',  
  320. 'WF',  
  321. 'WS',  
  322. 'YE',  
  323. 'YT',  
  324. 'RS',  
  325. 'ZA',  
  326. 'ZM',  
  327. 'ME',  
  328. 'ZW',  
  329. 'A1',  
  330. 'A2',  
  331. 'O1',  
  332. 'AX',  
  333. 'GG',  
  334. 'IM',  
  335. 'JE',  
  336. 'BL',  
  337. 'MF',  
  338. 'BQ',  
  339. 'SS',  
  340. 'O1',  
  341. ); 
  342.  
  343. /** 
  344. * 3 letters country codes. 
  345. * @var array 
  346. */ 
  347. public $GEOIP_COUNTRY_CODES3 = array( 
  348. '',  
  349. 'AP',  
  350. 'EU',  
  351. 'AND',  
  352. 'ARE',  
  353. 'AFG',  
  354. 'ATG',  
  355. 'AIA',  
  356. 'ALB',  
  357. 'ARM',  
  358. 'CUW',  
  359. 'AGO',  
  360. 'ATA',  
  361. 'ARG',  
  362. 'ASM',  
  363. 'AUT',  
  364. 'AUS',  
  365. 'ABW',  
  366. 'AZE',  
  367. 'BIH',  
  368. 'BRB',  
  369. 'BGD',  
  370. 'BEL',  
  371. 'BFA',  
  372. 'BGR',  
  373. 'BHR',  
  374. 'BDI',  
  375. 'BEN',  
  376. 'BMU',  
  377. 'BRN',  
  378. 'BOL',  
  379. 'BRA',  
  380. 'BHS',  
  381. 'BTN',  
  382. 'BVT',  
  383. 'BWA',  
  384. 'BLR',  
  385. 'BLZ',  
  386. 'CAN',  
  387. 'CCK',  
  388. 'COD',  
  389. 'CAF',  
  390. 'COG',  
  391. 'CHE',  
  392. 'CIV',  
  393. 'COK',  
  394. 'CHL',  
  395. 'CMR',  
  396. 'CHN',  
  397. 'COL',  
  398. 'CRI',  
  399. 'CUB',  
  400. 'CPV',  
  401. 'CXR',  
  402. 'CYP',  
  403. 'CZE',  
  404. 'DEU',  
  405. 'DJI',  
  406. 'DNK',  
  407. 'DMA',  
  408. 'DOM',  
  409. 'DZA',  
  410. 'ECU',  
  411. 'EST',  
  412. 'EGY',  
  413. 'ESH',  
  414. 'ERI',  
  415. 'ESP',  
  416. 'ETH',  
  417. 'FIN',  
  418. 'FJI',  
  419. 'FLK',  
  420. 'FSM',  
  421. 'FRO',  
  422. 'FRA',  
  423. 'SXM',  
  424. 'GAB',  
  425. 'GBR',  
  426. 'GRD',  
  427. 'GEO',  
  428. 'GUF',  
  429. 'GHA',  
  430. 'GIB',  
  431. 'GRL',  
  432. 'GMB',  
  433. 'GIN',  
  434. 'GLP',  
  435. 'GNQ',  
  436. 'GRC',  
  437. 'SGS',  
  438. 'GTM',  
  439. 'GUM',  
  440. 'GNB',  
  441. 'GUY',  
  442. 'HKG',  
  443. 'HMD',  
  444. 'HND',  
  445. 'HRV',  
  446. 'HTI',  
  447. 'HUN',  
  448. 'IDN',  
  449. 'IRL',  
  450. 'ISR',  
  451. 'IND',  
  452. 'IOT',  
  453. 'IRQ',  
  454. 'IRN',  
  455. 'ISL',  
  456. 'ITA',  
  457. 'JAM',  
  458. 'JOR',  
  459. 'JPN',  
  460. 'KEN',  
  461. 'KGZ',  
  462. 'KHM',  
  463. 'KIR',  
  464. 'COM',  
  465. 'KNA',  
  466. 'PRK',  
  467. 'KOR',  
  468. 'KWT',  
  469. 'CYM',  
  470. 'KAZ',  
  471. 'LAO',  
  472. 'LBN',  
  473. 'LCA',  
  474. 'LIE',  
  475. 'LKA',  
  476. 'LBR',  
  477. 'LSO',  
  478. 'LTU',  
  479. 'LUX',  
  480. 'LVA',  
  481. 'LBY',  
  482. 'MAR',  
  483. 'MCO',  
  484. 'MDA',  
  485. 'MDG',  
  486. 'MHL',  
  487. 'MKD',  
  488. 'MLI',  
  489. 'MMR',  
  490. 'MNG',  
  491. 'MAC',  
  492. 'MNP',  
  493. 'MTQ',  
  494. 'MRT',  
  495. 'MSR',  
  496. 'MLT',  
  497. 'MUS',  
  498. 'MDV',  
  499. 'MWI',  
  500. 'MEX',  
  501. 'MYS',  
  502. 'MOZ',  
  503. 'NAM',  
  504. 'NCL',  
  505. 'NER',  
  506. 'NFK',  
  507. 'NGA',  
  508. 'NIC',  
  509. 'NLD',  
  510. 'NOR',  
  511. 'NPL',  
  512. 'NRU',  
  513. 'NIU',  
  514. 'NZL',  
  515. 'OMN',  
  516. 'PAN',  
  517. 'PER',  
  518. 'PYF',  
  519. 'PNG',  
  520. 'PHL',  
  521. 'PAK',  
  522. 'POL',  
  523. 'SPM',  
  524. 'PCN',  
  525. 'PRI',  
  526. 'PSE',  
  527. 'PRT',  
  528. 'PLW',  
  529. 'PRY',  
  530. 'QAT',  
  531. 'REU',  
  532. 'ROU',  
  533. 'RUS',  
  534. 'RWA',  
  535. 'SAU',  
  536. 'SLB',  
  537. 'SYC',  
  538. 'SDN',  
  539. 'SWE',  
  540. 'SGP',  
  541. 'SHN',  
  542. 'SVN',  
  543. 'SJM',  
  544. 'SVK',  
  545. 'SLE',  
  546. 'SMR',  
  547. 'SEN',  
  548. 'SOM',  
  549. 'SUR',  
  550. 'STP',  
  551. 'SLV',  
  552. 'SYR',  
  553. 'SWZ',  
  554. 'TCA',  
  555. 'TCD',  
  556. 'ATF',  
  557. 'TGO',  
  558. 'THA',  
  559. 'TJK',  
  560. 'TKL',  
  561. 'TKM',  
  562. 'TUN',  
  563. 'TON',  
  564. 'TLS',  
  565. 'TUR',  
  566. 'TTO',  
  567. 'TUV',  
  568. 'TWN',  
  569. 'TZA',  
  570. 'UKR',  
  571. 'UGA',  
  572. 'UMI',  
  573. 'USA',  
  574. 'URY',  
  575. 'UZB',  
  576. 'VAT',  
  577. 'VCT',  
  578. 'VEN',  
  579. 'VGB',  
  580. 'VIR',  
  581. 'VNM',  
  582. 'VUT',  
  583. 'WLF',  
  584. 'WSM',  
  585. 'YEM',  
  586. 'MYT',  
  587. 'SRB',  
  588. 'ZAF',  
  589. 'ZMB',  
  590. 'MNE',  
  591. 'ZWE',  
  592. 'A1',  
  593. 'A2',  
  594. 'O1',  
  595. 'ALA',  
  596. 'GGY',  
  597. 'IMN',  
  598. 'JEY',  
  599. 'BLM',  
  600. 'MAF',  
  601. 'BES',  
  602. 'SSD',  
  603. 'O1',  
  604. ); 
  605.  
  606. /** 
  607. * Contry names. 
  608. * @var array 
  609. */ 
  610. public $GEOIP_COUNTRY_NAMES = array( 
  611. '',  
  612. 'Asia/Pacific Region',  
  613. 'Europe',  
  614. 'Andorra',  
  615. 'United Arab Emirates',  
  616. 'Afghanistan',  
  617. 'Antigua and Barbuda',  
  618. 'Anguilla',  
  619. 'Albania',  
  620. 'Armenia',  
  621. 'Curacao',  
  622. 'Angola',  
  623. 'Antarctica',  
  624. 'Argentina',  
  625. 'American Samoa',  
  626. 'Austria',  
  627. 'Australia',  
  628. 'Aruba',  
  629. 'Azerbaijan',  
  630. 'Bosnia and Herzegovina',  
  631. 'Barbados',  
  632. 'Bangladesh',  
  633. 'Belgium',  
  634. 'Burkina Faso',  
  635. 'Bulgaria',  
  636. 'Bahrain',  
  637. 'Burundi',  
  638. 'Benin',  
  639. 'Bermuda',  
  640. 'Brunei Darussalam',  
  641. 'Bolivia',  
  642. 'Brazil',  
  643. 'Bahamas',  
  644. 'Bhutan',  
  645. 'Bouvet Island',  
  646. 'Botswana',  
  647. 'Belarus',  
  648. 'Belize',  
  649. 'Canada',  
  650. 'Cocos (Keeling) Islands',  
  651. 'Congo, The Democratic Republic of the',  
  652. 'Central African Republic',  
  653. 'Congo',  
  654. 'Switzerland',  
  655. "Cote D'Ivoire",  
  656. 'Cook Islands',  
  657. 'Chile',  
  658. 'Cameroon',  
  659. 'China',  
  660. 'Colombia',  
  661. 'Costa Rica',  
  662. 'Cuba',  
  663. 'Cape Verde',  
  664. 'Christmas Island',  
  665. 'Cyprus',  
  666. 'Czech Republic',  
  667. 'Germany',  
  668. 'Djibouti',  
  669. 'Denmark',  
  670. 'Dominica',  
  671. 'Dominican Republic',  
  672. 'Algeria',  
  673. 'Ecuador',  
  674. 'Estonia',  
  675. 'Egypt',  
  676. 'Western Sahara',  
  677. 'Eritrea',  
  678. 'Spain',  
  679. 'Ethiopia',  
  680. 'Finland',  
  681. 'Fiji',  
  682. 'Falkland Islands (Malvinas)',  
  683. 'Micronesia, Federated States of',  
  684. 'Faroe Islands',  
  685. 'France',  
  686. 'Sint Maarten (Dutch part)',  
  687. 'Gabon',  
  688. 'United Kingdom',  
  689. 'Grenada',  
  690. 'Georgia',  
  691. 'French Guiana',  
  692. 'Ghana',  
  693. 'Gibraltar',  
  694. 'Greenland',  
  695. 'Gambia',  
  696. 'Guinea',  
  697. 'Guadeloupe',  
  698. 'Equatorial Guinea',  
  699. 'Greece',  
  700. 'South Georgia and the South Sandwich Islands',  
  701. 'Guatemala',  
  702. 'Guam',  
  703. 'Guinea-Bissau',  
  704. 'Guyana',  
  705. 'Hong Kong',  
  706. 'Heard Island and McDonald Islands',  
  707. 'Honduras',  
  708. 'Croatia',  
  709. 'Haiti',  
  710. 'Hungary',  
  711. 'Indonesia',  
  712. 'Ireland',  
  713. 'Israel',  
  714. 'India',  
  715. 'British Indian Ocean Territory',  
  716. 'Iraq',  
  717. 'Iran, Islamic Republic of',  
  718. 'Iceland',  
  719. 'Italy',  
  720. 'Jamaica',  
  721. 'Jordan',  
  722. 'Japan',  
  723. 'Kenya',  
  724. 'Kyrgyzstan',  
  725. 'Cambodia',  
  726. 'Kiribati',  
  727. 'Comoros',  
  728. 'Saint Kitts and Nevis',  
  729. "Korea, Democratic People's Republic of",  
  730. 'Korea, Republic of',  
  731. 'Kuwait',  
  732. 'Cayman Islands',  
  733. 'Kazakhstan',  
  734. "Lao People's Democratic Republic",  
  735. 'Lebanon',  
  736. 'Saint Lucia',  
  737. 'Liechtenstein',  
  738. 'Sri Lanka',  
  739. 'Liberia',  
  740. 'Lesotho',  
  741. 'Lithuania',  
  742. 'Luxembourg',  
  743. 'Latvia',  
  744. 'Libya',  
  745. 'Morocco',  
  746. 'Monaco',  
  747. 'Moldova, Republic of',  
  748. 'Madagascar',  
  749. 'Marshall Islands',  
  750. 'Macedonia',  
  751. 'Mali',  
  752. 'Myanmar',  
  753. 'Mongolia',  
  754. 'Macau',  
  755. 'Northern Mariana Islands',  
  756. 'Martinique',  
  757. 'Mauritania',  
  758. 'Montserrat',  
  759. 'Malta',  
  760. 'Mauritius',  
  761. 'Maldives',  
  762. 'Malawi',  
  763. 'Mexico',  
  764. 'Malaysia',  
  765. 'Mozambique',  
  766. 'Namibia',  
  767. 'New Caledonia',  
  768. 'Niger',  
  769. 'Norfolk Island',  
  770. 'Nigeria',  
  771. 'Nicaragua',  
  772. 'Netherlands',  
  773. 'Norway',  
  774. 'Nepal',  
  775. 'Nauru',  
  776. 'Niue',  
  777. 'New Zealand',  
  778. 'Oman',  
  779. 'Panama',  
  780. 'Peru',  
  781. 'French Polynesia',  
  782. 'Papua New Guinea',  
  783. 'Philippines',  
  784. 'Pakistan',  
  785. 'Poland',  
  786. 'Saint Pierre and Miquelon',  
  787. 'Pitcairn Islands',  
  788. 'Puerto Rico',  
  789. 'Palestinian Territory',  
  790. 'Portugal',  
  791. 'Palau',  
  792. 'Paraguay',  
  793. 'Qatar',  
  794. 'Reunion',  
  795. 'Romania',  
  796. 'Russian Federation',  
  797. 'Rwanda',  
  798. 'Saudi Arabia',  
  799. 'Solomon Islands',  
  800. 'Seychelles',  
  801. 'Sudan',  
  802. 'Sweden',  
  803. 'Singapore',  
  804. 'Saint Helena',  
  805. 'Slovenia',  
  806. 'Svalbard and Jan Mayen',  
  807. 'Slovakia',  
  808. 'Sierra Leone',  
  809. 'San Marino',  
  810. 'Senegal',  
  811. 'Somalia',  
  812. 'Suriname',  
  813. 'Sao Tome and Principe',  
  814. 'El Salvador',  
  815. 'Syrian Arab Republic',  
  816. 'Swaziland',  
  817. 'Turks and Caicos Islands',  
  818. 'Chad',  
  819. 'French Southern Territories',  
  820. 'Togo',  
  821. 'Thailand',  
  822. 'Tajikistan',  
  823. 'Tokelau',  
  824. 'Turkmenistan',  
  825. 'Tunisia',  
  826. 'Tonga',  
  827. 'Timor-Leste',  
  828. 'Turkey',  
  829. 'Trinidad and Tobago',  
  830. 'Tuvalu',  
  831. 'Taiwan',  
  832. 'Tanzania, United Republic of',  
  833. 'Ukraine',  
  834. 'Uganda',  
  835. 'United States Minor Outlying Islands',  
  836. 'United States',  
  837. 'Uruguay',  
  838. 'Uzbekistan',  
  839. 'Holy See (Vatican City State)',  
  840. 'Saint Vincent and the Grenadines',  
  841. 'Venezuela',  
  842. 'Virgin Islands, British',  
  843. 'Virgin Islands, U.S.',  
  844. 'Vietnam',  
  845. 'Vanuatu',  
  846. 'Wallis and Futuna',  
  847. 'Samoa',  
  848. 'Yemen',  
  849. 'Mayotte',  
  850. 'Serbia',  
  851. 'South Africa',  
  852. 'Zambia',  
  853. 'Montenegro',  
  854. 'Zimbabwe',  
  855. 'Anonymous Proxy',  
  856. 'Satellite Provider',  
  857. 'Other',  
  858. 'Aland Islands',  
  859. 'Guernsey',  
  860. 'Isle of Man',  
  861. 'Jersey',  
  862. 'Saint Barthelemy',  
  863. 'Saint Martin',  
  864. 'Bonaire, Saint Eustatius and Saba',  
  865. 'South Sudan',  
  866. 'Other',  
  867. ); 
  868.  
  869. /** 
  870. * 2 letters continent codes. 
  871. * @var array 
  872. */ 
  873. public $GEOIP_CONTINENT_CODES = array( 
  874. '--',  
  875. 'AS',  
  876. 'EU',  
  877. 'EU',  
  878. 'AS',  
  879. 'AS',  
  880. 'NA',  
  881. 'NA',  
  882. 'EU',  
  883. 'AS',  
  884. 'NA',  
  885. 'AF',  
  886. 'AN',  
  887. 'SA',  
  888. 'OC',  
  889. 'EU',  
  890. 'OC',  
  891. 'NA',  
  892. 'AS',  
  893. 'EU',  
  894. 'NA',  
  895. 'AS',  
  896. 'EU',  
  897. 'AF',  
  898. 'EU',  
  899. 'AS',  
  900. 'AF',  
  901. 'AF',  
  902. 'NA',  
  903. 'AS',  
  904. 'SA',  
  905. 'SA',  
  906. 'NA',  
  907. 'AS',  
  908. 'AN',  
  909. 'AF',  
  910. 'EU',  
  911. 'NA',  
  912. 'NA',  
  913. 'AS',  
  914. 'AF',  
  915. 'AF',  
  916. 'AF',  
  917. 'EU',  
  918. 'AF',  
  919. 'OC',  
  920. 'SA',  
  921. 'AF',  
  922. 'AS',  
  923. 'SA',  
  924. 'NA',  
  925. 'NA',  
  926. 'AF',  
  927. 'AS',  
  928. 'AS',  
  929. 'EU',  
  930. 'EU',  
  931. 'AF',  
  932. 'EU',  
  933. 'NA',  
  934. 'NA',  
  935. 'AF',  
  936. 'SA',  
  937. 'EU',  
  938. 'AF',  
  939. 'AF',  
  940. 'AF',  
  941. 'EU',  
  942. 'AF',  
  943. 'EU',  
  944. 'OC',  
  945. 'SA',  
  946. 'OC',  
  947. 'EU',  
  948. 'EU',  
  949. 'NA',  
  950. 'AF',  
  951. 'EU',  
  952. 'NA',  
  953. 'AS',  
  954. 'SA',  
  955. 'AF',  
  956. 'EU',  
  957. 'NA',  
  958. 'AF',  
  959. 'AF',  
  960. 'NA',  
  961. 'AF',  
  962. 'EU',  
  963. 'AN',  
  964. 'NA',  
  965. 'OC',  
  966. 'AF',  
  967. 'SA',  
  968. 'AS',  
  969. 'AN',  
  970. 'NA',  
  971. 'EU',  
  972. 'NA',  
  973. 'EU',  
  974. 'AS',  
  975. 'EU',  
  976. 'AS',  
  977. 'AS',  
  978. 'AS',  
  979. 'AS',  
  980. 'AS',  
  981. 'EU',  
  982. 'EU',  
  983. 'NA',  
  984. 'AS',  
  985. 'AS',  
  986. 'AF',  
  987. 'AS',  
  988. 'AS',  
  989. 'OC',  
  990. 'AF',  
  991. 'NA',  
  992. 'AS',  
  993. 'AS',  
  994. 'AS',  
  995. 'NA',  
  996. 'AS',  
  997. 'AS',  
  998. 'AS',  
  999. 'NA',  
  1000. 'EU',  
  1001. 'AS',  
  1002. 'AF',  
  1003. 'AF',  
  1004. 'EU',  
  1005. 'EU',  
  1006. 'EU',  
  1007. 'AF',  
  1008. 'AF',  
  1009. 'EU',  
  1010. 'EU',  
  1011. 'AF',  
  1012. 'OC',  
  1013. 'EU',  
  1014. 'AF',  
  1015. 'AS',  
  1016. 'AS',  
  1017. 'AS',  
  1018. 'OC',  
  1019. 'NA',  
  1020. 'AF',  
  1021. 'NA',  
  1022. 'EU',  
  1023. 'AF',  
  1024. 'AS',  
  1025. 'AF',  
  1026. 'NA',  
  1027. 'AS',  
  1028. 'AF',  
  1029. 'AF',  
  1030. 'OC',  
  1031. 'AF',  
  1032. 'OC',  
  1033. 'AF',  
  1034. 'NA',  
  1035. 'EU',  
  1036. 'EU',  
  1037. 'AS',  
  1038. 'OC',  
  1039. 'OC',  
  1040. 'OC',  
  1041. 'AS',  
  1042. 'NA',  
  1043. 'SA',  
  1044. 'OC',  
  1045. 'OC',  
  1046. 'AS',  
  1047. 'AS',  
  1048. 'EU',  
  1049. 'NA',  
  1050. 'OC',  
  1051. 'NA',  
  1052. 'AS',  
  1053. 'EU',  
  1054. 'OC',  
  1055. 'SA',  
  1056. 'AS',  
  1057. 'AF',  
  1058. 'EU',  
  1059. 'EU',  
  1060. 'AF',  
  1061. 'AS',  
  1062. 'OC',  
  1063. 'AF',  
  1064. 'AF',  
  1065. 'EU',  
  1066. 'AS',  
  1067. 'AF',  
  1068. 'EU',  
  1069. 'EU',  
  1070. 'EU',  
  1071. 'AF',  
  1072. 'EU',  
  1073. 'AF',  
  1074. 'AF',  
  1075. 'SA',  
  1076. 'AF',  
  1077. 'NA',  
  1078. 'AS',  
  1079. 'AF',  
  1080. 'NA',  
  1081. 'AF',  
  1082. 'AN',  
  1083. 'AF',  
  1084. 'AS',  
  1085. 'AS',  
  1086. 'OC',  
  1087. 'AS',  
  1088. 'AF',  
  1089. 'OC',  
  1090. 'AS',  
  1091. 'EU',  
  1092. 'NA',  
  1093. 'OC',  
  1094. 'AS',  
  1095. 'AF',  
  1096. 'EU',  
  1097. 'AF',  
  1098. 'OC',  
  1099. 'NA',  
  1100. 'SA',  
  1101. 'AS',  
  1102. 'EU',  
  1103. 'NA',  
  1104. 'SA',  
  1105. 'NA',  
  1106. 'NA',  
  1107. 'AS',  
  1108. 'OC',  
  1109. 'OC',  
  1110. 'OC',  
  1111. 'AS',  
  1112. 'AF',  
  1113. 'EU',  
  1114. 'AF',  
  1115. 'AF',  
  1116. 'EU',  
  1117. 'AF',  
  1118. '--',  
  1119. '--',  
  1120. '--',  
  1121. 'EU',  
  1122. 'EU',  
  1123. 'EU',  
  1124. 'EU',  
  1125. 'NA',  
  1126. 'NA',  
  1127. 'NA',  
  1128. 'AF',  
  1129. '--',  
  1130. ); 
  1131.  
  1132. /** @var WC_Logger Logger instance */ 
  1133. public static $log = false; 
  1134.  
  1135. /** 
  1136. * Logging method. 
  1137. * @param string $message Log message. 
  1138. * @param string $level Optional. Default 'info'. 
  1139. * emergency|alert|critical|error|warning|notice|info|debug 
  1140. */ 
  1141. public static function log( $message, $level = 'info' ) { 
  1142. if ( empty( self::$log ) ) { 
  1143. self::$log = wc_get_logger(); 
  1144. self::$log->log( $level, $message, array( 'source' => 'geoip' ) ); 
  1145.  
  1146. /** 
  1147. * Open geoip file. 
  1148. * @param string $filename 
  1149. * @param int $flags 
  1150. */ 
  1151. public function geoip_open( $filename, $flags ) { 
  1152. $this->flags = $flags; 
  1153. if ( $this->flags & self::GEOIP_SHARED_MEMORY ) { 
  1154. $this->shmid = @shmop_open( self::GEOIP_SHM_KEY, 'a', 0, 0 ); 
  1155. } else { 
  1156. if ( $this->filehandle = fopen( $filename, 'rb' ) ) { 
  1157. if ( $this->flags & self::GEOIP_MEMORY_CACHE ) { 
  1158. $s_array = fstat( $this->filehandle ); 
  1159. $this->memory_buffer = fread( $this->filehandle, $s_array['size'] ); 
  1160. } else { 
  1161. $this->log( 'GeoIP API: Can not open ' . $filename, 'error' ); 
  1162.  
  1163. $this->_setup_segments(); 
  1164.  
  1165. /** 
  1166. * Setup segments. 
  1167. * @return WC_Geo_IP instance 
  1168. */ 
  1169. private function _setup_segments() { 
  1170. $this->databaseType = self::GEOIP_COUNTRY_EDITION; 
  1171. $this->record_length = self::STANDARD_RECORD_LENGTH; 
  1172.  
  1173. if ( $this->flags & self::GEOIP_SHARED_MEMORY ) { 
  1174. $offset = @shmop_size( $this->shmid ) - 3; 
  1175.  
  1176. for ( $i = 0; $i < self::STRUCTURE_INFO_MAX_SIZE; $i++ ) { 
  1177. $delim = @shmop_read( $this->shmid, $offset, 3 ); 
  1178. $offset += 3; 
  1179.  
  1180. if ( ( chr( 255 ) . chr( 255 ) . chr( 255 ) ) == $delim ) { 
  1181. $this->databaseType = ord( @shmop_read( $this->shmid, $offset, 1 ) ); 
  1182.  
  1183. if ( $this->databaseType >= 106 ) { 
  1184. $this->databaseType -= 105; 
  1185.  
  1186. $offset++; 
  1187.  
  1188. if ( self::GEOIP_REGION_EDITION_REV0 == $this->databaseType ) { 
  1189. $this->databaseSegments = self::GEOIP_STATE_BEGIN_REV0; 
  1190. } elseif ( self::GEOIP_REGION_EDITION_REV1 == $this->databaseType ) { 
  1191. $this->databaseSegments = self::GEOIP_STATE_BEGIN_REV1; 
  1192. } elseif ( ( self::GEOIP_CITY_EDITION_REV0 == $this->databaseType ) 
  1193. || ( self::GEOIP_CITY_EDITION_REV1 == $this->databaseType ) 
  1194. || ( self::GEOIP_ORG_EDITION == $this->databaseType ) 
  1195. || ( self::GEOIP_ORG_EDITION_V6 == $this->databaseType ) 
  1196. || ( self::GEOIP_DOMAIN_EDITION == $this->databaseType ) 
  1197. || ( self::GEOIP_DOMAIN_EDITION_V6 == $this->databaseType ) 
  1198. || ( self::GEOIP_ISP_EDITION == $this->databaseType ) 
  1199. || ( self::GEOIP_ISP_EDITION_V6 == $this->databaseType ) 
  1200. || ( self::GEOIP_USERTYPE_EDITION == $this->databaseType ) 
  1201. || ( self::GEOIP_USERTYPE_EDITION_V6 == $this->databaseType ) 
  1202. || ( self::GEOIP_LOCATIONA_EDITION == $this->databaseType ) 
  1203. || ( self::GEOIP_ACCURACYRADIUS_EDITION == $this->databaseType ) 
  1204. || ( self::GEOIP_CITY_EDITION_REV0_V6 == $this->databaseType ) 
  1205. || ( self::GEOIP_CITY_EDITION_REV1_V6 == $this->databaseType ) 
  1206. || ( self::GEOIP_NETSPEED_EDITION_REV1 == $this->databaseType ) 
  1207. || ( self::GEOIP_NETSPEED_EDITION_REV1_V6 == $this->databaseType ) 
  1208. || ( self::GEOIP_ASNUM_EDITION == $this->databaseType ) 
  1209. || ( self::GEOIP_ASNUM_EDITION_V6 == $this->databaseType ) 
  1210. ) { 
  1211. $this->databaseSegments = 0; 
  1212. $buf = @shmop_read( $this->shmid, $offset, self::SEGMENT_RECORD_LENGTH ); 
  1213.  
  1214. for ( $j = 0; $j < self::SEGMENT_RECORD_LENGTH; $j++ ) { 
  1215. $this->databaseSegments += ( ord( $buf[ $j ] ) << ( $j * 8 ) ); 
  1216.  
  1217. if ( ( self::GEOIP_ORG_EDITION == $this->databaseType ) 
  1218. || ( self::GEOIP_ORG_EDITION_V6 == $this->databaseType ) 
  1219. || ( self::GEOIP_DOMAIN_EDITION == $this->databaseType ) 
  1220. || ( self::GEOIP_DOMAIN_EDITION_V6 == $this->databaseType ) 
  1221. || ( self::GEOIP_ISP_EDITION == $this->databaseType ) 
  1222. || ( self::GEOIP_ISP_EDITION_V6 == $this->databaseType ) 
  1223. ) { 
  1224. $this->record_length = self::ORG_RECORD_LENGTH; 
  1225.  
  1226. break; 
  1227. } else { 
  1228. $offset -= 4; 
  1229. if ( ( self::GEOIP_COUNTRY_EDITION == $this->databaseType ) 
  1230. || ( self::GEOIP_COUNTRY_EDITION_V6 == $this->databaseType ) 
  1231. || ( self::GEOIP_PROXY_EDITION == $this->databaseType ) 
  1232. || ( self::GEOIP_NETSPEED_EDITION == $this->databaseType ) 
  1233. ) { 
  1234. $this->databaseSegments = self::GEOIP_COUNTRY_BEGIN; 
  1235. } else { 
  1236. $filepos = ftell( $this->filehandle ); 
  1237. fseek( $this->filehandle, -3, SEEK_END ); 
  1238.  
  1239. for ( $i = 0; $i < self::STRUCTURE_INFO_MAX_SIZE; $i++ ) { 
  1240.  
  1241. $delim = fread( $this->filehandle, 3 ); 
  1242. if ( ( chr( 255 ) . chr( 255 ) . chr( 255 ) ) == $delim ) { 
  1243.  
  1244. $this->databaseType = ord( fread( $this->filehandle, 1 ) ); 
  1245. if ( $this->databaseType >= 106 ) { 
  1246. $this->databaseType -= 105; 
  1247.  
  1248. if ( self::GEOIP_REGION_EDITION_REV0 == $this->databaseType ) { 
  1249. $this->databaseSegments = self::GEOIP_STATE_BEGIN_REV0; 
  1250. } elseif ( self::GEOIP_REGION_EDITION_REV1 == $this->databaseType ) { 
  1251. $this->databaseSegments = self::GEOIP_STATE_BEGIN_REV1; 
  1252. } elseif ( ( self::GEOIP_CITY_EDITION_REV0 == $this->databaseType ) 
  1253. || ( self::GEOIP_CITY_EDITION_REV1 == $this->databaseType ) 
  1254. || ( self::GEOIP_CITY_EDITION_REV0_V6 == $this->databaseType ) 
  1255. || ( self::GEOIP_CITY_EDITION_REV1_V6 == $this->databaseType ) 
  1256. || ( self::GEOIP_ORG_EDITION == $this->databaseType ) 
  1257. || ( self::GEOIP_DOMAIN_EDITION == $this->databaseType ) 
  1258. || ( self::GEOIP_ISP_EDITION == $this->databaseType ) 
  1259. || ( self::GEOIP_ORG_EDITION_V6 == $this->databaseType ) 
  1260. || ( self::GEOIP_DOMAIN_EDITION_V6 == $this->databaseType ) 
  1261. || ( self::GEOIP_ISP_EDITION_V6 == $this->databaseType ) 
  1262. || ( self::GEOIP_LOCATIONA_EDITION == $this->databaseType ) 
  1263. || ( self::GEOIP_ACCURACYRADIUS_EDITION == $this->databaseType ) 
  1264. || ( self::GEOIP_NETSPEED_EDITION_REV1 == $this->databaseType ) 
  1265. || ( self::GEOIP_NETSPEED_EDITION_REV1_V6 == $this->databaseType ) 
  1266. || ( self::GEOIP_USERTYPE_EDITION == $this->databaseType ) 
  1267. || ( self::GEOIP_USERTYPE_EDITION_V6 == $this->databaseType ) 
  1268. || ( self::GEOIP_ASNUM_EDITION == $this->databaseType ) 
  1269. || ( self::GEOIP_ASNUM_EDITION_V6 == $this->databaseType ) 
  1270. ) { 
  1271. $this->databaseSegments = 0; 
  1272. $buf = fread( $this->filehandle, self::SEGMENT_RECORD_LENGTH ); 
  1273.  
  1274. for ( $j = 0; $j < self::SEGMENT_RECORD_LENGTH; $j++ ) { 
  1275. $this->databaseSegments += ( ord( $buf[ $j ] ) << ( $j * 8 ) ); 
  1276.  
  1277. if ( ( self::GEOIP_ORG_EDITION == $this->databaseType ) 
  1278. || ( self::GEOIP_DOMAIN_EDITION == $this->databaseType ) 
  1279. || ( self::GEOIP_ISP_EDITION == $this->databaseType ) 
  1280. || ( self::GEOIP_ORG_EDITION_V6 == $this->databaseType ) 
  1281. || ( self::GEOIP_DOMAIN_EDITION_V6 == $this->databaseType ) 
  1282. || ( self::GEOIP_ISP_EDITION_V6 == $this->databaseType ) 
  1283. ) { 
  1284. $this->record_length = self::ORG_RECORD_LENGTH; 
  1285.  
  1286. break; 
  1287. } else { 
  1288. fseek( $this->filehandle, -4, SEEK_CUR ); 
  1289.  
  1290. if ( ( self::GEOIP_COUNTRY_EDITION == $this->databaseType ) 
  1291. || ( self::GEOIP_COUNTRY_EDITION_V6 == $this->databaseType ) 
  1292. || ( self::GEOIP_PROXY_EDITION == $this->databaseType ) 
  1293. || ( self::GEOIP_NETSPEED_EDITION == $this->databaseType ) 
  1294. ) { 
  1295. $this->databaseSegments = self::GEOIP_COUNTRY_BEGIN; 
  1296.  
  1297. fseek( $this->filehandle, $filepos, SEEK_SET ); 
  1298.  
  1299. return $this; 
  1300.  
  1301. /** 
  1302. * Close geoip file. 
  1303. * @return bool 
  1304. */ 
  1305. public function geoip_close() { 
  1306. if ( $this->flags & self::GEOIP_SHARED_MEMORY ) { 
  1307. return true; 
  1308.  
  1309. return fclose( $this->filehandle ); 
  1310.  
  1311. /** 
  1312. * Common get record. 
  1313. * @param string $seek_country 
  1314. * @return WC_Geo_IP_Record instance 
  1315. */ 
  1316. private function _common_get_record( $seek_country ) { 
  1317. // workaround php's broken substr, strpos, etc handling with 
  1318. // mbstring.func_overload and mbstring.internal_encoding 
  1319. $mbExists = extension_loaded( 'mbstring' ); 
  1320. if ( $mbExists ) { 
  1321. $enc = mb_internal_encoding(); 
  1322. mb_internal_encoding( 'ISO-8859-1' ); 
  1323.  
  1324. $record_pointer = $seek_country + ( 2 * $this->record_length - 1 ) * $this->databaseSegments; 
  1325.  
  1326. if ( $this->flags & self::GEOIP_MEMORY_CACHE ) { 
  1327. $record_buf = substr( $this->memory_buffer, $record_pointer, FULL_RECORD_LENGTH ); 
  1328. } elseif ( $this->flags & self::GEOIP_SHARED_MEMORY ) { 
  1329. $record_buf = @shmop_read( $this->shmid, $record_pointer, FULL_RECORD_LENGTH ); 
  1330. } else { 
  1331. fseek( $this->filehandle, $record_pointer, SEEK_SET ); 
  1332. $record_buf = fread( $this->filehandle, FULL_RECORD_LENGTH ); 
  1333.  
  1334. $record = new WC_Geo_IP_Record(); 
  1335. $record_buf_pos = 0; 
  1336. $char = ord( substr( $record_buf, $record_buf_pos, 1 ) ); 
  1337. $record->country_code = $this->GEOIP_COUNTRY_CODES[ $char ]; 
  1338. $record->country_code3 = $this->GEOIP_COUNTRY_CODES3[ $char ]; 
  1339. $record->country_name = $this->GEOIP_COUNTRY_NAMES[ $char ]; 
  1340. $record->continent_code = $this->GEOIP_CONTINENT_CODES[ $char ]; 
  1341. $str_length = 0; 
  1342.  
  1343. $record_buf_pos++; 
  1344.  
  1345. // Get region 
  1346. $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) ); 
  1347. while ( 0 != $char ) { 
  1348. $str_length++; 
  1349. $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) ); 
  1350.  
  1351. if ( $str_length > 0 ) { 
  1352. $record->region = substr( $record_buf, $record_buf_pos, $str_length ); 
  1353.  
  1354. $record_buf_pos += $str_length + 1; 
  1355. $str_length = 0; 
  1356.  
  1357. // Get city 
  1358. $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) ); 
  1359. while ( 0 != $char ) { 
  1360. $str_length++; 
  1361. $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) ); 
  1362.  
  1363. if ( $str_length > 0 ) { 
  1364. $record->city = substr( $record_buf, $record_buf_pos, $str_length ); 
  1365.  
  1366. $record_buf_pos += $str_length + 1; 
  1367. $str_length = 0; 
  1368.  
  1369. // Get postal code 
  1370. $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) ); 
  1371. while ( 0 != $char ) { 
  1372. $str_length++; 
  1373. $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) ); 
  1374.  
  1375. if ( $str_length > 0 ) { 
  1376. $record->postal_code = substr( $record_buf, $record_buf_pos, $str_length ); 
  1377.  
  1378. $record_buf_pos += $str_length + 1; 
  1379.  
  1380. // Get latitude and longitude 
  1381. $latitude = 0; 
  1382. $longitude = 0; 
  1383. for ( $j = 0; $j < 3; ++$j ) { 
  1384. $char = ord( substr( $record_buf, $record_buf_pos++, 1 ) ); 
  1385. $latitude += ( $char << ( $j * 8 ) ); 
  1386.  
  1387. $record->latitude = ( $latitude / 10000 ) - 180; 
  1388.  
  1389. for ( $j = 0; $j < 3; ++$j ) { 
  1390. $char = ord( substr( $record_buf, $record_buf_pos++, 1 ) ); 
  1391. $longitude += ( $char << ( $j * 8 ) ); 
  1392.  
  1393. $record->longitude = ( $longitude / 10000 ) - 180; 
  1394.  
  1395. if ( self::GEOIP_CITY_EDITION_REV1 == $this->databaseType ) { 
  1396. $metroarea_combo = 0; 
  1397. if ( 'US' === $record->country_code ) { 
  1398. for ( $j = 0; $j < 3; ++$j ) { 
  1399. $char = ord( substr( $record_buf, $record_buf_pos++, 1 ) ); 
  1400. $metroarea_combo += ( $char << ( $j * 8 ) ); 
  1401.  
  1402. $record->metro_code = $record->dma_code = floor( $metroarea_combo / 1000 ); 
  1403. $record->area_code = $metroarea_combo % 1000; 
  1404.  
  1405. if ( $mbExists ) { 
  1406. mb_internal_encoding( $enc ); 
  1407.  
  1408. return $record; 
  1409.  
  1410. /** 
  1411. * Get record. 
  1412. * @param int $ipnum 
  1413. * @return WC_Geo_IP_Record instance 
  1414. */ 
  1415. private function _get_record( $ipnum ) { 
  1416. $seek_country = $this->_geoip_seek_country( $ipnum ); 
  1417. if ( $seek_country == $this->databaseSegments ) { 
  1418. return null; 
  1419.  
  1420. return $this->_common_get_record( $seek_country ); 
  1421.  
  1422. /** 
  1423. * Seek country IPv6. 
  1424. * @param int $ipnum 
  1425. * @return string 
  1426. */ 
  1427. public function _geoip_seek_country_v6( $ipnum ) { 
  1428. // arrays from unpack start with offset 1 
  1429. // yet another php mystery. array_merge work around 
  1430. // this broken behaviour 
  1431. $v6vec = array_merge( unpack( 'C16', $ipnum ) ); 
  1432.  
  1433. $offset = 0; 
  1434. for ( $depth = 127; $depth >= 0; --$depth ) { 
  1435. if ( $this->flags & self::GEOIP_MEMORY_CACHE ) { 
  1436. $buf = $this->_safe_substr( 
  1437. $this->memory_buffer,  
  1438. 2 * $this->record_length * $offset,  
  1439. 2 * $this->record_length 
  1440. ); 
  1441. } elseif ( $this->flags & self::GEOIP_SHARED_MEMORY ) { 
  1442. $buf = @shmop_read( 
  1443. $this->shmid,  
  1444. 2 * $this->record_length * $offset,  
  1445. 2 * $this->record_length 
  1446. ); 
  1447. } else { 
  1448. if ( 0 != fseek( $this->filehandle, 2 * $this->record_length * $offset, SEEK_SET ) ) { 
  1449. break; 
  1450.  
  1451. $buf = fread( $this->filehandle, 2 * $this->record_length ); 
  1452. $x = array( 0, 0 ); 
  1453. for ( $i = 0; $i < 2; ++$i ) { 
  1454. for ( $j = 0; $j < $this->record_length; ++$j ) { 
  1455. $x[ $i ] += ord( $buf[ $this->record_length * $i + $j ] ) << ( $j * 8 ); 
  1456.  
  1457. $bnum = 127 - $depth; 
  1458. $idx = $bnum >> 3; 
  1459. $b_mask = 1 << ( $bnum & 7 ^ 7 ); 
  1460. if ( ( $v6vec[ $idx ] & $b_mask ) > 0 ) { 
  1461. if ( $x[1] >= $this->databaseSegments ) { 
  1462. return $x[1]; 
  1463. $offset = $x[1]; 
  1464. } else { 
  1465. if ( $x[0] >= $this->databaseSegments ) { 
  1466. return $x[0]; 
  1467. $offset = $x[0]; 
  1468.  
  1469. $this->log( 'GeoIP API: Error traversing database - perhaps it is corrupt?', 'error' ); 
  1470.  
  1471. return false; 
  1472.  
  1473. /** 
  1474. * Seek country. 
  1475. * @param int $ipnum 
  1476. * @return string 
  1477. */ 
  1478. private function _geoip_seek_country( $ipnum ) { 
  1479. $offset = 0; 
  1480. for ( $depth = 31; $depth >= 0; --$depth ) { 
  1481. if ( $this->flags & self::GEOIP_MEMORY_CACHE ) { 
  1482. $buf = $this->_safe_substr( 
  1483. $this->memory_buffer,  
  1484. 2 * $this->record_length * $offset,  
  1485. 2 * $this->record_length 
  1486. ); 
  1487. } elseif ( $this->flags & self::GEOIP_SHARED_MEMORY ) { 
  1488. $buf = @shmop_read( 
  1489. $this->shmid,  
  1490. 2 * $this->record_length * $offset,  
  1491. 2 * $this->record_length 
  1492. ); 
  1493. } else { 
  1494. if ( 0 != fseek( $this->filehandle, 2 * $this->record_length * $offset, SEEK_SET ) ) { 
  1495. break; 
  1496.  
  1497. $buf = fread( $this->filehandle, 2 * $this->record_length ); 
  1498.  
  1499. $x = array( 0, 0 ); 
  1500. for ( $i = 0; $i < 2; ++$i ) { 
  1501. for ( $j = 0; $j < $this->record_length; ++$j ) { 
  1502. $x[ $i ] += ord( $buf[ $this->record_length * $i + $j ] ) << ( $j * 8 ); 
  1503. if ( $ipnum & ( 1 << $depth ) ) { 
  1504. if ( $x[1] >= $this->databaseSegments ) { 
  1505. return $x[1]; 
  1506.  
  1507. $offset = $x[1]; 
  1508. } else { 
  1509. if ( $x[0] >= $this->databaseSegments ) { 
  1510. return $x[0]; 
  1511.  
  1512. $offset = $x[0]; 
  1513.  
  1514. $this->log( 'GeoIP API: Error traversing database - perhaps it is corrupt?', 'error' ); 
  1515.  
  1516. return false; 
  1517.  
  1518. /** 
  1519. * Record by addr. 
  1520. * @param string $addr 
  1521. * @return int 
  1522. */ 
  1523. public function geoip_record_by_addr( $addr ) { 
  1524. if ( null == $addr ) { 
  1525. return 0; 
  1526.  
  1527. $ipnum = ip2long( $addr ); 
  1528. return $this->_get_record( $ipnum ); 
  1529.  
  1530. /** 
  1531. * Country ID by addr IPv6. 
  1532. * @param string $addr 
  1533. * @return int|bool 
  1534. */ 
  1535. public function geoip_country_id_by_addr_v6( $addr ) { 
  1536. if ( ! defined( 'AF_INET6' ) ) { 
  1537. $this->log( 'GEOIP (geoip_country_id_by_addr_v6): PHP was compiled with --disable-ipv6 option' ); 
  1538. return false; 
  1539. $ipnum = inet_pton( $addr ); 
  1540. return $this->_geoip_seek_country_v6( $ipnum ) - self::GEOIP_COUNTRY_BEGIN; 
  1541.  
  1542. /** 
  1543. * Country ID by addr. 
  1544. * @param string $addr 
  1545. * @return int 
  1546. */ 
  1547. public function geoip_country_id_by_addr( $addr ) { 
  1548. $ipnum = ip2long( $addr ); 
  1549. return $this->_geoip_seek_country( $ipnum ) - self::GEOIP_COUNTRY_BEGIN; 
  1550.  
  1551. /** 
  1552. * Country code by addr IPv6. 
  1553. * @param string $addr 
  1554. * @return string 
  1555. */ 
  1556. public function geoip_country_code_by_addr_v6( $addr ) { 
  1557. $country_id = $this->geoip_country_id_by_addr_v6( $addr ); 
  1558. if ( false !== $country_id && isset( $this->GEOIP_COUNTRY_CODES[ $country_id ] ) ) { 
  1559. return $this->GEOIP_COUNTRY_CODES[ $country_id ]; 
  1560.  
  1561. return false; 
  1562.  
  1563. /** 
  1564. * Country code by addr. 
  1565. * @param string $addr 
  1566. * @return string 
  1567. */ 
  1568. public function geoip_country_code_by_addr( $addr ) { 
  1569. if ( self::GEOIP_CITY_EDITION_REV1 == $this->databaseType ) { 
  1570. $record = $this->geoip_record_by_addr( $addr ); 
  1571. if ( false !== $record ) { 
  1572. return $record->country_code; 
  1573. } else { 
  1574. $country_id = $this->geoip_country_id_by_addr( $addr ); 
  1575. if ( false !== $country_id && isset( $this->GEOIP_COUNTRY_CODES[ $country_id ] ) ) { 
  1576. return $this->GEOIP_COUNTRY_CODES[ $country_id ]; 
  1577.  
  1578. return false; 
  1579.  
  1580. /** 
  1581. * Encode string. 
  1582. * @param string $string 
  1583. * @param int $start 
  1584. * @param int $length 
  1585. * @return string 
  1586. */ 
  1587. private function _safe_substr( $string, $start, $length ) { 
  1588. // workaround php's broken substr, strpos, etc handling with 
  1589. // mbstring.func_overload and mbstring.internal_encoding 
  1590. $mb_exists = extension_loaded( 'mbstring' ); 
  1591.  
  1592. if ( $mb_exists ) { 
  1593. $enc = mb_internal_encoding(); 
  1594. mb_internal_encoding( 'ISO-8859-1' ); 
  1595.  
  1596. $buf = substr( $string, $start, $length ); 
  1597.  
  1598. if ( $mb_exists ) { 
  1599. mb_internal_encoding( $enc ); 
  1600.  
  1601. return $buf;