dolibarr  21.0.0-alpha
dolgeoip.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2009-2012 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  * or see https://www.gnu.org/
18  */
19 
35 class DolGeoIP
36 {
40  public $gi;
41 
45  public $error;
46 
50  public $errorlabel;
51 
58  public function __construct($type, $datfile)
59  {
60  global $conf;
61 
62  $geoipversion = '2'; // 'php', or geoip version '2'
63  if (getDolGlobalString('GEOIP_VERSION')) {
64  $geoipversion = getDolGlobalString('GEOIP_VERSION');
65  }
66 
67  if ($type == 'country') {
68  // geoip may have been already included with PEAR
69  if ($geoipversion == '2' || ($geoipversion != 'php' && !function_exists('geoip_country_code_by_name'))) {
70  if (function_exists('stream_wrapper_restore')) {
71  stream_wrapper_restore('phar');
72  }
73  require_once DOL_DOCUMENT_ROOT.'/includes/geoip2/geoip2.phar';
74  }
75  } elseif ($type == 'city') {
76  // geoip may have been already included with PEAR
77  if ($geoipversion == '2' || ($geoipversion != 'php' && !function_exists('geoip_country_code_by_name'))) {
78  if (function_exists('stream_wrapper_restore')) {
79  stream_wrapper_restore('phar');
80  }
81  require_once DOL_DOCUMENT_ROOT.'/includes/geoip2/geoip2.phar';
82  }
83  } else {
84  print 'ErrorBadParameterInConstructor';
85  return;
86  }
87 
88  // Here, function exists (embedded into PHP or exists because we made include)
89  if (empty($type) || empty($datfile)) {
90  $this->errorlabel = 'Constructor was called with no datafile parameter';
91  dol_syslog('DolGeoIP '.$this->errorlabel, LOG_ERR);
92  return;
93  }
94  if (!file_exists($datfile) || !is_readable($datfile)) {
95  $this->error = 'ErrorGeoIPClassNotInitialized';
96  $this->errorlabel = "Datafile ".$datfile." not found";
97  dol_syslog('DolGeoIP '.$this->errorlabel, LOG_ERR);
98  return;
99  }
100 
101  if ($geoipversion == '2') {
102  try {
103  // @phpstan-ignore-next-line
104  $this->gi = new GeoIp2\Database\Reader($datfile); // '/usr/local/share/GeoIP/GeoIP2-City.mmdb'
105  } catch (Exception $e) {
106  $this->error = $e->getMessage();
107  dol_syslog('DolGeoIP '.$this->errorlabel, LOG_ERR);
108  return;
109  }
110  } elseif (function_exists('geoip_open') && defined('GEOIP_STANDARD')) {
111  $this->gi = geoip_open($datfile, constant('GEOIP_STANDARD'));
112  } elseif (function_exists('geoip_country_code_by_name')) {
113  $this->gi = 'NOGI'; // We are using embedded php geoip functions
114  //print 'function_exists(geoip_country_code_by_name))='.function_exists('geoip_country_code_by_name');
115  //print geoip_database_info();
116  } else {
117  $this->gi = ''; // For avoid error
118  }
119  }
120 
127  public function getCountryCodeFromIP($ip)
128  {
129  global $conf;
130 
131  $geoipversion = '2'; // 'php', or '2'
132  if (getDolGlobalString('GEOIP_VERSION')) {
133  $geoipversion = getDolGlobalString('GEOIP_VERSION');
134  }
135 
136  if (empty($this->gi)) {
137  return '';
138  }
139  if ($this->gi == 'NOGI') {
140  // geoip_country_code_by_addr does not exists
141  return strtolower(geoip_country_code_by_name($ip));
142  } else {
143  if (preg_match('/^[0-9]+.[0-9]+\.[0-9]+\.[0-9]+/', $ip)) {
144  if ($geoipversion == '2') {
145  try {
146  $record = $this->gi->country($ip);
147  return strtolower($record->country->isoCode);
148  } catch (Exception $e) {
149  //return $e->getMessage();
150  return '';
151  }
152  } else {
153  if (!function_exists('geoip_country_code_by_addr')) {
154  return strtolower(geoip_country_code_by_name($ip));
155  }
156  return strtolower(geoip_country_code_by_addr($this->gi, $ip));
157  }
158  } else {
159  if ($geoipversion == '2') {
160  try {
161  $record = $this->gi->country($ip);
162  return strtolower($record->country->isoCode);
163  } catch (Exception $e) {
164  //return $e->getMessage();
165  return '';
166  }
167  } else {
168  if (function_exists('geoip_country_code_by_addr_v6')) {
169  return strtolower(geoip_country_code_by_addr_v6($this->gi, $ip));
170  } elseif (function_exists('geoip_country_code_by_name_v6')) {
171  return strtolower(geoip_country_code_by_name_v6($this->gi, $ip));
172  }
173  return '';
174  }
175  }
176  }
177  }
178 
185  public function getCountryCodeFromName($name)
186  {
187  global $conf;
188 
189  $geoipversion = '2'; // 'php', or '2'
190  if (getDolGlobalString('GEOIP_VERSION')) {
191  $geoipversion = getDolGlobalString('GEOIP_VERSION');
192  }
193 
194  if (empty($this->gi)) {
195  return '';
196  }
197 
198  if ($geoipversion == '2') {
199  try {
200  $record = $this->gi->country($name);
201  return $record->country->isoCode;
202  } catch (Exception $e) {
203  //return $e->getMessage();
204  return '';
205  }
206  } else {
207  return strtolower(geoip_country_code_by_name($name));
208  }
209  }
210 
216  public function getVersion()
217  {
218  global $conf;
219 
220  $geoipversion = '2'; // 'php', or '2'
221  if (getDolGlobalString('GEOIP_VERSION')) {
222  $geoipversion = getDolGlobalString('GEOIP_VERSION');
223  }
224 
225  if ($geoipversion == 'php') {
226  if ($this->gi == 'NOGI') {
227  return geoip_database_info();
228  } else {
229  return 'geoip_database_info() function not available';
230  }
231  }
232 
233  return 'Not available (not using PHP internal geo functions - We are using embedded Geoip v'.$geoipversion.')';
234  }
235 
241  public function close()
242  {
243  if (function_exists('geoip_close')) {
244  // With some geoip with PEAR, geoip_close function may not exists
245  geoip_close($this->gi);
246  }
247  }
248 }
Class to manage GeoIP conversion Usage: $geoip=new GeoIP('country',$datfile); $geoip->getCountryCodeF...
getCountryCodeFromIP($ip)
Return in lower case the country code from an ip.
__construct($type, $datfile)
Constructor.
getVersion()
Return version of data file.
close()
Close geoip object.
getCountryCodeFromName($name)
Return in lower case the country code from a host name.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.