<commit_before><?php
/**
 * @author <NAME> <<EMAIL>>
 * @copyright Copyright &copy; S.E.M. 2018-
 * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
 */

namespace sem\helpers\string;

use sem\helpers\Html;

/**
 * Хелпер для работы с номерами мобильных телефонов РФ
 */
class MobilePhoneHelper
{

    /**
     * Максимальная длина номера телефона с учетом префикса
     */
    const MOBILE_PHONE_MAX_LENGHT = 12;

    /**
     * Минимальная длина номера телефона без учета префикса
     */
    const MOBILE_PHONE_MIN_LENGHT = 11;

    /**
     * Производит нормализацию 11-значного номера телефона:
     * если первая его цифра отличается от $prefix, то она заменяется на $prefix.
     * Либо если длина номера телефона 12 сиволов и первые два символа +X, то они заменяются на $prefix.
     *
     * @param string $number номер телефона в виде строки
     * @param string $prefix телефонный префикс
     * @return false|string
     * @todo пересмотреть и сделать возможность использования универсального префикса - высчитывать его длину и т.д.
     */
    public static function normalize($phone, $prefix = '8')
    {

        $phone = preg_replace("/[^0-9+]/", "", $phone);

        if (mb_strlen($phone, 'UTF-8') > self::MOBILE_PHONE_MAX_LENGHT || mb_strlen($phone, 'UTF-8') < self::MOBILE_PHONE_MIN_LENGHT) {
            return false;
        }

        if (mb_strlen($phone, 'UTF-8') == self::MOBILE_PHONE_MAX_LENGHT && mb_substr($phone, 0, 1, 'UTF-8') == '+') {
            return $prefix . mb_substr($phone, 2, null, 'UTF-8');
        }

        if (mb_substr($phone, 0, 1, 'UTF-8') != $prefix) {

            if (mb_strlen($phone, 'UTF-8') == 11) {
                return $prefix . mb_substr($phone, 1, null, 'UTF-8');
            } else {
                return $prefix . $phone;
            }

        } else {
            return $phone;
        }

    }

    /**
     * Преобразует телефонный номер к читабельному виду по маске: (XXX) XXX-XX-XX
     *
     * @param string $phone сплошная последовательность цифр, например 8632216827
     * @param string $codeTag HTML-тег, в который заворачивается код города
     * @param string $phoneTag HTML-тег, в который заворачивается номер телефона
     * @param array $codeTagOptions массив с дополнительными атрибутами для HTML-тега $codeTag
     * @return string красивый номер, например (863) 221-68-27
     */
    public static function format($phone, $codeTag = 'span', $phoneTag = '', $codeTagOptions = [])
    {
        $codePattern = '($2)';
        $numberPattern = ' $3-$4-$5';
<commit_msg>Оптимизирован метод нормализации номера мобильного телефона. Исправлены ее недочеты<commit_after><?php
/**
 * @author <NAME> <<EMAIL>>
 * @copyright Copyright &copy; S.E.M. 2018-
 * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
 */

namespace sem\helpers\string;

use Yii;
use sem\helpers\Html;

/**
 * Хелпер для работы с номерами мобильных телефонов РФ
 */
class MobilePhoneHelper
{

    /**
     * Максимальная длина номера телефона с учетом префикса
     */
    const MOBILE_PHONE_MAX_LENGHT = 12;

    /**
     * Минимальная длина номера телефона без учета префикса
     */
    const MOBILE_PHONE_MIN_LENGHT = 10;

    /**
     * Производит нормализацию мобильного номера телефона,
     * выделяя из $phone возможные символы номера телефона и подставляя префикс,
     * если он отсутствует или требует замены на новый.
     * Например,
     * ```php
     * echo MobilePhoneHelper::normalize('+ (903) 111-22-33', '+7') . "<br>"; // +79031112233
     * echo MobilePhoneHelper::normalize('+7 903 111-22-33', '+7') . "<br>"; // +79031112233
     * echo MobilePhoneHelper::normalize('+8 (903) 111-22-33', '+7') . "<br>"; // +79031112233
     * echo MobilePhoneHelper::normalize('9031112233', '+7') . "<br>"; // +79031112233
     * echo MobilePhoneHelper::normalize('+9031112233', '8') . "<br>"; // 89031112233
     * echo MobilePhoneHelper::normalize('+7 (903) 111-22-33', '8') . "<br>"; // 89031112233
     * echo MobilePhoneHelper::normalize('+8 (903) 111-22-33', '8') . "<br>"; // 89031112233
     * echo MobilePhoneHelper::normalize('(903) 111-22-33', '8') . "<br>"; // 89031112233
     * ```
     * @param string $phone номер телефона в виде строки
     * @param string $prefix телефонный префикс
     * @param null $encoding кодировка
     * @return false|string
     */
    public static function normalize($phone, $prefix = '+7', $encoding = null)
    {
        $phone = preg_replace("/[^0-9+]/ui", "", $phone);

        if ($encoding === null) {
            $encoding = Yii::$app->charset;
        }

        $phoneLen = mb_strlen($phone, $encoding);

        if ($phoneLen > self::MOBILE_PHONE_MAX_LENGHT || $phoneLen < self::MOBILE_PHONE_MIN_LENGHT) {
            return false;
        }

        // Добавляем префик с последним self::MOBILE_PHONE_MIN_LENGHT строки
        return $prefix . mb_substr($phone, -self::MOBILE_PHONE_MIN_LENGHT, null, $encoding);
    }

    /**
     * Преобразует телефонный номер к читабельному виду по маске: (XXX) XXX-XX-XX
     *
     * @param string $phone сплошная последовательность цифр, например 8632216827
     * @param string $codeTag HTML-тег, в который заворачивается код города
     * @param string $phoneTag HTML-тег, в который заворачивается номер телефона
     * @param array $codeTagOptions массив с дополнительными атрибутами для HTML-тега $codeTag
     * @return string красивый номер, например (863) 221-68-27
     */
    public static function format($phone, $codeTag = 'span', $phoneTag = '', $codeTagOptions = [])
    {
        $codePattern = '($2)';
        $numberPattern = ' $3-$4-$5';

{'fraction_non_alphanumeric': 0.1359463276836158, 'fraction_numerical': 0.04766949152542373, 'mean_word_length': 2.8668941979522184, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4911636', 'n_tokens_mistral': 2209, 'n_tokens_neox': 2240, 'n_words': 486}