В битриксе всегда было полно вспомогательного функционала, который часто располагался в нерелевантных местах. Например вещи, необходимые для работы с ценой, почему-то находились в модуле инфоблоков, или хранилище для адресов в модуле магазина.
На этот раз вроде все на месте. В 17.5 в битриксе появился своего рода «парсер» для номеров телефонов. А заодно вместе с ним и форматтер. Если в двух словах, то битрикс теперь может попытаться преобразовать строковое представление номера телефона в объект, а также преобразовать его обратно в строку в заранее определенном формате. Эдакая нормализация.
Назначение у функционала простое - принять строку, распознать в ней телефон и если получилось - преобразовать в один из поддерживаемых форматов. Как бонус - можно получить информацию о разных параметрах распарсенного номера телефона.
Интерфейс работы довольно прост и, в общем-то, понятен:
use Bitrix\Main\PhoneNumber\Format;
use Bitrix\Main\PhoneNumber\Parser;
$phone = '89011111111';
// Парсим номер телефона с помощью класса-парсера
$parsedPhone = Parser::getInstance()->parse($phone);
// Из объекта распарсенного телефона можно получить разное. Например код страны
echo $parsedPhone->getCountry(); // RU
// или ... опять код страны
echo $parsedPhone->getCountryCode(); // 7
// или тип номера, возможные типы:
// 'noInternationalDialling', 'areaCodeOptional', 'fixedLine',
// 'mobile', 'pager', 'tollFree', 'premiumRate', 'sharedCost',
// 'personalNumber', 'voip', 'uan', 'voicemail'
echo $parsedPhone->getNumberType(); // mobile
// Ну или оригинальный телефон, который был скормлен парсеру
echo $parsedPhone->getRawNumber(); // 89011111111
// А можно переформатировать объект телефона в один из поддерживаемых форматов
// Национальный, видимо "наш"
echo $parsedPhone->format(Format::NATIONAL);
// Международный
echo $parsedPhone->format(Format::INTERNATIONAL);
// Ну и более-менее стандартизированный по https://ru.wikipedia.org/wiki/E.164
echo $parsedPhone->format(Format::E164);
// А еще есть парсинг коротких номеров
echo Parser::getInstance()->parse('911')->format(); //9-11
Функционал используется как нормализатор для номеров телефонов в модуле рассылок.
Непонятно, как ошибки обрабатывать, да и как вообще понять, получилось у библиотеки распознать, а если нет - то почему … но это уже детали.
В общем, ничего особенного, если бы не одно но. Я уже где-то это видел )
В продукт добавляется все больше и больше полу-функций. Все эти полу-функции копируются с какого-нибудь готового решения и потом забрасываются навсегда. Вспомнить хотя бы печально известную либу BX для фронтенда, которая копирует jquery чуть менее, чем полностью и которой никто, кроме разработчиков битрикса, не пользуется. Или распиаренные Битрикс24 сайты, которые скопировали с Тильды? Список можно продолжать.
Вот и в этот раз я почуял, что я уже где-то что-то подобное видел. И вспомнил где - в https://github.com/giggsey/libphonenumber-for-php. Довольно популярная либа для парсинга и форматирования номеров. Предоставляет куда более широкие возможности, задокументирована, покрыта тестами, легко встраивается в проект с помощью composer, интернационализация и многое другое.
Интерфейс работы с либой - практически идентичен (скопировано из официального мануала):
$swissNumberStr = "044 668 18 00";
$phoneUtil = \libphonenumber\PhoneNumberUtil::getInstance();
try {
$swissNumberProto = $phoneUtil->parse($swissNumberStr, "CH");
var_dump($swissNumberProto);
} catch (\libphonenumber\NumberParseException $e) {
var_dump($e);
}
// Produces "+41446681800"
echo $phoneUtil->format($swissNumberProto, \libphonenumber\PhoneNumberFormat::E164);
// Produces "044 668 18 00"
echo $phoneUtil->format($swissNumberProto, \libphonenumber\PhoneNumberFormat::NATIONAL);
// Produces "+41 44 668 18 00"
echo $phoneUtil->format($swissNumberProto, \libphonenumber\PhoneNumberFormat::INTERNATIONAL);
Спрашивается, зачем копировать? Вопрос риторический … Если вам немного не подходит библиотека - ну помогите вы проекту, запилите в нем недостающую фичу и встройте к себе, ведь будет дешевле, чем пилить с нуля и поддерживать полу-продукт. А встроить с composer - вообще не проблема, ведь битрикс поддерживает composer теперь официально. Эх …