dolibarr 24.0.1
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-2025 Frédéric France <frederic.france@free.fr>
4 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 * or see https://www.gnu.org/
19 */
20
37{
41 public $gi;
42
46 public $error;
47
51 public $errorlabel;
52
59 public function __construct($type, $datfile)
60 {
61 $datfile = str_replace('DOL_DATA_ROOT', DOL_DATA_ROOT, $datfile);
62
63 $geoipversion = '2'; // 'php', or geoip version '2'
64 if (getDolGlobalString('GEOIP_VERSION')) {
65 $geoipversion = getDolGlobalString('GEOIP_VERSION');
66 }
67
68 try {
69 if ($type == 'country') {
70 // geoip may have been already included with PEAR
71 if ($geoipversion == '2' || ($geoipversion != 'php' && !function_exists('geoip_country_code_by_name'))) {
72 if (function_exists('stream_wrapper_restore')) {
73 stream_wrapper_restore('phar');
74 }
75 include_once DOL_DOCUMENT_ROOT.'/includes/geoip2/geoip2.phar';
76 }
77 } elseif ($type == 'city') {
78 // geoip may have been already included with PEAR
79 if ($geoipversion == '2' || ($geoipversion != 'php' && !function_exists('geoip_country_code_by_name'))) {
80 if (function_exists('stream_wrapper_restore')) {
81 stream_wrapper_restore('phar');
82 }
83 include_once DOL_DOCUMENT_ROOT.'/includes/geoip2/geoip2.phar';
84 }
85 } else {
86 print 'ErrorBadParameterInConstructor';
87 return;
88 }
89 } catch (Exception $e) {
90 $this->error = $e->getMessage();
91 $this->errorlabel = 'Exception '.$this->error;
92 dol_syslog('DolGeoIP '.$this->errorlabel, LOG_ERR);
93 return;
94 }
95
96 // Here, function exists (embedded into PHP or exists because we made include)
97 if (empty($type) || empty($datfile)) {
98 $this->errorlabel = 'Constructor was called with no datafile parameter';
99 dol_syslog('DolGeoIP '.$this->errorlabel, LOG_ERR);
100 return;
101 }
102 if (!file_exists($datfile) || !is_readable($datfile)) {
103 $this->error = 'ErrorGeoIPClassNotInitialized';
104 $this->errorlabel = "Datafile ".$datfile." not found";
105 dol_syslog('DolGeoIP '.$this->errorlabel, LOG_ERR);
106 return;
107 }
108
109 if ($geoipversion == '2') {
110 try {
111 // @phpstan-ignore-next-line
112 $this->gi = new GeoIp2\Database\Reader($datfile); // '/usr/local/share/GeoIP/GeoIP2-City.mmdb'
113 } catch (Exception $e) {
114 $this->error = $e->getMessage();
115 dol_syslog('DolGeoIP '.$this->errorlabel, LOG_ERR);
116 return;
117 }
118 } elseif (function_exists('geoip_open') && defined('GEOIP_STANDARD')) {
119 $this->gi = geoip_open($datfile, constant('GEOIP_STANDARD'));
120 } elseif (function_exists('geoip_country_code_by_name')) {
121 $this->gi = 'NOGI'; // We are using embedded php geoip functions
122 //print 'function_exists(geoip_country_code_by_name))='.function_exists('geoip_country_code_by_name');
123 //print geoip_database_info();
124 } else {
125 $this->gi = ''; // For avoid error
126 }
127 }
128
138 private function getGeoIp2IsoCode($ipOrName)
139 {
140 try {
141 $databasetype = '';
142 if (is_object($this->gi) && method_exists($this->gi, 'metadata')) {
143 // @phan-suppress-next-line PhanUndeclaredClassProperty MaxMind\Db\Reader\Metadata is provided by geoip2.phar and has no stub
144 $databasetype = (string) $this->gi->metadata()->databaseType;
145 }
146 if (strpos($databasetype, 'Country') === false && strpos($databasetype, 'City') !== false) {
147 $record = $this->gi->city($ipOrName);
148 } else {
149 $record = $this->gi->country($ipOrName);
150 }
151 return (string) $record->country->isoCode;
152 } catch (Exception $e) {
153 //return $e->getMessage();
154 return '';
155 }
156 }
157
164 public function getCountryCodeFromIP($ip)
165 {
166 $geoipversion = '2'; // 'php', or '2'
167 if (getDolGlobalString('GEOIP_VERSION')) {
168 $geoipversion = getDolGlobalString('GEOIP_VERSION');
169 }
170
171 if (empty($this->gi)) {
172 return '';
173 }
174 if ($this->gi == 'NOGI') {
175 // geoip_country_code_by_addr does not exists
176 return strtolower(geoip_country_code_by_name($ip));
177 } else {
178 if (preg_match('/^[0-9]+.[0-9]+\.[0-9]+\.[0-9]+/', $ip)) {
179 if ($geoipversion == '2') {
180 return strtolower($this->getGeoIp2IsoCode($ip));
181 } else {
182 if (!function_exists('geoip_country_code_by_addr')) {
183 return strtolower(geoip_country_code_by_name($ip));
184 }
185 return strtolower(geoip_country_code_by_addr($this->gi, $ip));
186 }
187 } else {
188 if ($geoipversion == '2') {
189 return strtolower($this->getGeoIp2IsoCode($ip));
190 } else {
191 if (function_exists('geoip_country_code_by_addr_v6')) {
192 return strtolower(geoip_country_code_by_addr_v6($this->gi, $ip));
193 } elseif (function_exists('geoip_country_code_by_name_v6')) {
194 return strtolower(geoip_country_code_by_name_v6($this->gi, $ip));
195 }
196 return '';
197 }
198 }
199 }
200 }
201
208 public function getCountryCodeFromName($name)
209 {
210 $geoipversion = '2'; // 'php', or '2'
211 if (getDolGlobalString('GEOIP_VERSION')) {
212 $geoipversion = getDolGlobalString('GEOIP_VERSION');
213 }
214
215 if (empty($this->gi)) {
216 return '';
217 }
218
219 if ($geoipversion == '2') {
220 return $this->getGeoIp2IsoCode($name);
221 } else {
222 return strtolower(geoip_country_code_by_name($name));
223 }
224 }
225
231 public function getVersion()
232 {
233 $geoipversion = '2'; // 'php', or '2'
234 if (getDolGlobalString('GEOIP_VERSION')) {
235 $geoipversion = getDolGlobalString('GEOIP_VERSION');
236 }
237
238 if ($geoipversion == 'php') {
239 if ($this->gi == 'NOGI') {
240 return geoip_database_info();
241 } else {
242 return 'geoip_database_info() function not available';
243 }
244 }
245
246 return 'Not available (not using PHP internal geo functions - We are using embedded Geoip v'.$geoipversion.')';
247 }
248
254 public function close()
255 {
256 if (function_exists('geoip_close')) {
257 // With some geoip with PEAR, geoip_close function may not exists
258 geoip_close($this->gi);
259 }
260 }
261}
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.
getGeoIp2IsoCode($ipOrName)
Return the ISO country code for an IP or a host name using the embedded GeoIP2 reader.
close()
Close geoip object.
getCountryCodeFromName($name)
Return in lower case the country code from a host name.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php