dolibarr 25.0.0-alpha
phone.lib.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2026 Open-Dsi <support@open-dsi.fr>
3 * Copyright (C) 2026 MDW <mdeweerd@users.noreply.github.com>
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 */
18
34function dol_parse_phone($phone)
35{
36 $phone = trim((string) $phone);
37 if ($phone === '') {
38 return array('code' => '', 'number' => '');
39 }
40
41 if (strpos($phone, '+') === 0) {
42 $pos = strpos($phone, ' ');
43 if ($pos !== false) {
44 return array(
45 'code' => substr($phone, 0, $pos),
46 'number' => substr($phone, $pos + 1)
47 );
48 }
49 // Phone starts with + but has no space: try to keep it as-is in code
50 return array('code' => '', 'number' => $phone);
51 }
52
53 return array('code' => '', 'number' => $phone);
54}
55
69function dol_build_phone($db, $code, $number)
70{
71 $number = preg_replace('/[\s\-\.\‍(\‍)]/', '', trim((string) $number));
72 $code = trim((string) $code);
73
74 if ($number === '') {
75 return '';
76 }
77
78 if ($code !== '') {
79 // Strip national trunk prefix (e.g. leading "0" for France)
80 $sql = "SELECT trunk_prefix FROM ".$db->prefix()."c_country";
81 $sql .= " WHERE phone_code = ".((int) ltrim($code, '+'));
82 $sql .= " AND trunk_prefix IS NOT NULL AND trunk_prefix != ''";
83 $sql .= " LIMIT 1";
84 $resql = $db->query($sql);
85 if ($resql) {
86 $obj = $db->fetch_object($resql);
87 if ($obj && isset($obj->trunk_prefix) && $obj->trunk_prefix !== '' && $obj->trunk_prefix !== null) {
88 $prefix = $obj->trunk_prefix;
89 if (strpos($number, $prefix) === 0) {
90 $number = substr($number, strlen($prefix));
91 }
92 }
93 $db->free($resql);
94 }
95 }
96
97 if ($code !== '') {
98 return $code.' '.$number;
99 }
100
101 return $number;
102}
103
111function dol_get_trunk_prefix($db, $phone_code)
112{
113 $phone_code = trim((string) $phone_code);
114 if ($phone_code === '') {
115 return '';
116 }
117
118 $sql = "SELECT trunk_prefix FROM ".$db->prefix()."c_country";
119 $sql .= " WHERE phone_code = ".((int) ltrim($phone_code, '+'));
120 $sql .= " AND trunk_prefix IS NOT NULL AND trunk_prefix != ''";
121 $sql .= " LIMIT 1";
122 $resql = $db->query($sql);
123 if ($resql) {
124 $obj = $db->fetch_object($resql);
125 if ($obj && isset($obj->trunk_prefix) && $obj->trunk_prefix !== '' && $obj->trunk_prefix !== null) {
126 $db->free($resql);
127 return $obj->trunk_prefix;
128 }
129 $db->free($resql);
130 }
131
132 return '';
133}
134
142{
143 static $cache = null;
144 if ($cache !== null) {
145 return $cache;
146 }
147
148 $cache = array();
149 $sql = "SELECT DISTINCT trunk_prefix FROM ".$db->prefix()."c_country";
150 $sql .= " WHERE trunk_prefix IS NOT NULL AND trunk_prefix != ''";
151 $resql = $db->query($sql);
152 if ($resql) {
153 while ($obj = $db->fetch_object($resql)) {
154 $cache[] = $obj->trunk_prefix;
155 }
156 $db->free($resql);
157 }
158
159 return $cache;
160}
161
173function dol_natural_search_phone($db, $fields, $value, $nofirstand = 0)
174{
175 $value = trim((string) $value);
176 if ($value === '') {
177 return '';
178 }
179
180 $stripped = preg_replace('/[\s\-\.\‍(\‍)]/', '', $value);
181
182 $candidates = array($stripped);
183 if (strpos($stripped, '+') !== 0) {
184 foreach (dol_get_all_trunk_prefixes($db) as $prefix) {
185 if ($prefix !== '' && strpos($stripped, $prefix) === 0) {
186 $candidates[] = substr($stripped, strlen($prefix));
187 }
188 }
189 }
190
191 $candidates = array_values(array_unique(array_filter($candidates, function (string $c) {
192 return $c !== '';
193 })));
194 if (empty($candidates)) {
195 $candidates = array($value);
196 }
197
198 return natural_search($fields, implode('|', $candidates), 0, $nofirstand);
199}
200
208function dol_get_phone_code_from_country($db, $country_id)
209{
210 $country_id = (int) $country_id;
211 if ($country_id <= 0) {
212 return '';
213 }
214
215 $sql = "SELECT phone_code FROM ".$db->prefix()."c_country WHERE rowid = ".((int) $country_id);
216 $resql = $db->query($sql);
217 if ($resql) {
218 $obj = $db->fetch_object($resql);
219 if ($obj && !empty($obj->phone_code)) {
220 $db->free($resql);
221 return '+'.$obj->phone_code;
222 }
223 $db->free($resql);
224 }
225
226 return '';
227}
$c
Definition line.php:346
natural_search($fields, $value, $mode=0, $nofirstand=0, $sqltoadd='')
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
dol_get_trunk_prefix($db, $phone_code)
Get the national trunk prefix for a phone code.
dol_get_all_trunk_prefixes($db)
Get the list of all distinct national trunk prefixes known in llx_c_country.
dol_build_phone($db, $code, $number)
Build a normalized phone string from code and number parts.
Definition phone.lib.php:69
dol_natural_search_phone($db, $fields, $value, $nofirstand=0)
Build a natural_search() SQL fragment for a phone/fax field, tolerant of the international storage fo...
dol_parse_phone($phone)
Parse a stored phone number into country code and number parts.
Definition phone.lib.php:34
dol_get_phone_code_from_country($db, $country_id)
Get the phone calling code for a country.