admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'prps_front' ), 'i18n' => array( 'send' => __( 'Получить код', 'propusk' ), 'call' => __( 'Подтвердить звонком', 'propusk' ), 'sending' => __( 'Отправляю…', 'propusk' ), 'check' => __( 'Войти', 'propusk' ), 'wait' => __( 'Проверяю…', 'propusk' ), 'again' => __( 'Отправить код ещё раз', 'propusk' ), 'change' => __( 'Другой номер', 'propusk' ), 'error' => __( 'Ошибка связи с сайтом. Попробуйте ещё раз.', 'propusk' ), 'done' => __( 'Готово, входим…', 'propusk' ), 'or' => __( 'или по логину и паролю', 'propusk' ), 'admin' => __( 'Вход по паролю для администратора', 'propusk' ), ), ) ); } private static function enqueue() { if ( ! wp_script_is( 'prps-front', 'registered' ) ) { self::register_assets(); } wp_enqueue_style( 'prps-front' ); wp_enqueue_script( 'prps-front' ); } public static function login_assets() { if ( PRPS_Settings::get( 'wp_login' ) && PRPS_Settings::methods() ) { self::enqueue(); } // Регистрация только по почте выключена: прячем поля логина и почты в форме регистрации WordPress. if ( 'off' === PRPS_Settings::get( 'email_register' ) && PRPS_Settings::methods() ) { wp_register_style( 'prps-register', false, array(), PRPS_VERSION ); wp_enqueue_style( 'prps-register' ); wp_add_inline_style( 'prps-register', '#registerform > p, #registerform > #reg_passmail { display: none; }' ); } } /** * Блок входа: кнопки способов и форма телефона. * * @param array $args redirect, context (login|register|shortcode|profile), skip — способы, которые не показывать. */ public static function widget( array $args = array() ) { $methods = array_diff_key( PRPS_Settings::methods(), array_flip( (array) ( $args['skip'] ?? array() ) ) ); if ( ! $methods ) { return ''; } self::enqueue(); $redirect = (string) ( $args['redirect'] ?? '' ); $context = (string) ( $args['context'] ?? 'shortcode' ); $mode = PRPS_Phone::mode(); $html = '
'; if ( 'login' === $context || 'register' === $context ) { $html .= '

' . esc_html( 'register' === $context ? __( 'Регистрация', 'propusk' ) : __( 'Войти на сайт', 'propusk' ) ) . '

'; } $html .= '
'; foreach ( $methods as $key => $label ) { if ( 'phone' === $key ) { $html .= ''; continue; } /** * Ссылка кнопки способа входа (Pro: MAX открывает окно с QR-кодом). * * @param string $url Адрес. * @param string $key Способ. * @param string $redirect Куда вернуть. */ $url = (string) apply_filters( 'prps/button_url', PRPS_OAuth::start_url( $key, $redirect ), $key, $redirect ); $html .= '' . self::icon( $key ) . '' . esc_html( $label ) . ''; } $html .= '
'; if ( isset( $methods['phone'] ) ) { $html .= ''; } if ( PRPS_Users::can_register() && in_array( $context, array( 'login', 'shortcode' ), true ) ) { $html .= '

' . esc_html__( 'Нет аккаунта? Войдите любым способом — аккаунт создастся сам.', 'propusk' ) . '

'; } /** * Блок входа выведен: дополнения подключают свои скрипты (Pro: окно MAX). HTML блока не меняется. * * @param string $unused Не используется (совместимость с прежними версиями). * @param string $context Где показан блок. */ do_action( 'prps/widget', '', $context ); return $html . '
'; } /** Значки способов входа (SVG без внешних запросов). */ public static function icon( $key ) { $icons = array( 'phone' => '', 'vk' => '', 'yandex' => '', 'max' => '', ); return $icons[ $key ] ?? ''; } public static function shortcode( $atts ) { $atts = shortcode_atts( array( 'redirect' => '' ), $atts, 'propusk' ); if ( is_user_logged_in() ) { $user = wp_get_current_user(); /* translators: %s: имя пользователя */ return '

' . esc_html( sprintf( __( 'Вы вошли как %s.', 'propusk' ), $user->display_name ) ) . ' ' . esc_html__( 'Выйти', 'propusk' ) . '

'; } $redirect = '' !== $atts['redirect'] ? $atts['redirect'] : (string) get_permalink(); return self::widget( array( 'redirect' => esc_url_raw( $redirect ), 'context' => 'shortcode' ) ); } private static function requested_redirect() { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- адрес возврата на странице входа. return isset( $_REQUEST['redirect_to'] ) ? esc_url_raw( wp_unslash( $_REQUEST['redirect_to'] ) ) : ''; } public static function login_form() { if ( PRPS_Settings::get( 'wp_login' ) ) { echo self::widget( array( 'redirect' => self::requested_redirect(), 'context' => 'login' ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- собрано из экранированных частей. } } public static function register_form() { if ( PRPS_Settings::get( 'wp_login' ) ) { echo self::widget( array( 'redirect' => self::requested_redirect(), 'context' => 'register' ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- собрано из экранированных частей. } } /** Регистрация по одной только почте отключена — по 406-ФЗ нужен телефон, Госуслуги или российский сервис входа. */ public static function registration_errors( $errors ) { if ( 'off' === PRPS_Settings::get( 'email_register' ) && PRPS_Settings::methods() ) { $errors->add( 'prps_email_off', __( 'Регистрация по почте отключена. Зарегистрируйтесь по номеру телефона или через VK ID / Яндекс ID.', 'propusk' ) ); } return $errors; } /** Вход по паролю — только для администраторов и редакторов (если так настроено). */ public static function password_rule( $user ) { if ( ! ( $user instanceof WP_User ) || 'admins' !== PRPS_Settings::get( 'password_login' ) || ! PRPS_Settings::methods() ) { return $user; } if ( user_can( $user, 'edit_others_posts' ) || ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) { return $user; } return new WP_Error( 'prps_password_off', __( 'Вход по паролю отключён. Войдите по номеру телефона или через VK ID / Яндекс ID.', 'propusk' ) ); } public static function login_errors( $errors ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['prps_error'] ) ) { $msg = PRPS_OAuth::take_error(); if ( '' !== $msg ) { $errors->add( 'prps', esc_html( $msg ) ); } } return $errors; } }