self::SLUG, 'tab' => $tab ), $args ), admin_url( 'admin.php' ) );
}
/** Хук страницы плагина (страница внутри пункта WP-ADDON). */
public static function hook() {
return PRPS_Wpaddon_Menu::hook( self::SLUG );
}
public static function menu() {
PRPS_Wpaddon_Menu::add_page( __( 'Вход 406-ФЗ', 'propusk' ), __( 'Вход 406-ФЗ', 'propusk' ), self::SLUG, array( __CLASS__, 'render' ) );
}
public static function action_links( $links ) {
array_unshift( $links, '' . esc_html__( 'Настройки', 'propusk' ) . '' );
if ( ! PRPS_Plugin::has_pro_addon() ) {
$links[] = 'Pro';
}
return $links;
}
public static function assets( $hook ) {
if ( self::hook() !== $hook && 'users.php' !== $hook ) {
return;
}
wp_enqueue_style( 'prps-admin', PRPS_URL . 'assets/css/admin.css', array(), PRPS_VERSION );
if ( 'users.php' === $hook ) {
return;
}
wp_enqueue_script( 'prps-admin', PRPS_URL . 'assets/js/admin.js', array(), PRPS_VERSION, true );
wp_localize_script(
'prps-admin',
'prpsAdmin',
array(
'ajax' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'prps_admin' ),
'i18n' => array(
'checking' => __( 'Проверяю…', 'propusk' ),
'copied' => __( 'Скопировано', 'propusk' ),
'error' => __( 'Ошибка запроса. Попробуйте ещё раз.', 'propusk' ),
),
)
);
}
public static function notices() {
$screen = get_current_screen();
if ( ! $screen || self::hook() !== $screen->id ) {
return;
}
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( isset( $_GET['prps_saved'] ) ) {
echo '
' . esc_html__( 'Настройки сохранены.', 'propusk' ) . '
';
}
}
/* =====================================================================
* Сохранение настроек
* =================================================================== */
public static function save() {
if ( empty( $_POST['prps_tab'] ) || ! current_user_can( self::CAP ) ) {
return;
}
$tab = sanitize_key( wp_unslash( $_POST['prps_tab'] ) );
check_admin_referer( 'prps_save_' . $tab );
$post = map_deep( wp_unslash( $_POST ), 'sanitize_text_field' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- очищается map_deep().
$s = PRPS_Settings::all();
if ( 'phone' === $tab ) {
$s['phone'] = empty( $post['phone'] ) ? 0 : 1;
$providers = PRPS_Phone::providers();
$s['provider'] = isset( $providers[ $post['provider'] ?? '' ] ) ? $post['provider'] : 'smsru';
$s['phone_mode'] = 'call' === ( $post['phone_mode'] ?? '' ) ? 'call' : 'sms';
$s['smsru_key'] = preg_replace( '/[^A-Za-z0-9-]/', '', (string) ( $post['smsru_key'] ?? '' ) );
$s['smsru_from'] = substr( preg_replace( '/[^A-Za-z0-9 ._-]/', '', (string) ( $post['smsru_from'] ?? '' ) ), 0, 11 );
$text = trim( (string) ( $post['sms_text'] ?? '' ) );
$s['sms_text'] = false !== strpos( $text, '{code}' ) ? mb_substr( $text, 0, 140 ) : PRPS_Settings::defaults()['sms_text'];
$s['code_length'] = min( 6, max( 4, (int) ( $post['code_length'] ?? 4 ) ) );
$s['limit_phone'] = min( 20, max( 1, (int) ( $post['limit_phone'] ?? 3 ) ) );
$s['limit_ip'] = min( 100, max( 1, (int) ( $post['limit_ip'] ?? 10 ) ) );
}
if ( 'social' === $tab ) {
$s['vk'] = empty( $post['vk'] ) ? 0 : 1;
$s['vk_client_id'] = preg_replace( '/\D/', '', (string) ( $post['vk_client_id'] ?? '' ) );
$s['yandex'] = empty( $post['yandex'] ) ? 0 : 1;
$s['ya_client_id'] = preg_replace( '/[^a-f0-9]/i', '', (string) ( $post['ya_client_id'] ?? '' ) );
$secret = preg_replace( '/[^a-f0-9]/i', '', (string) ( $post['ya_secret'] ?? '' ) );
if ( '' !== $secret || ! empty( $post['ya_secret_clear'] ) ) {
$s['ya_secret'] = $secret; // Пустое поле не стирает сохранённый секрет.
}
}
if ( 'login' === $tab ) {
$s['register'] = empty( $post['register'] ) ? 0 : 1;
$s['email_register'] = 'keep' === ( $post['email_register'] ?? '' ) ? 'keep' : 'off';
$s['password_login'] = 'admins' === ( $post['password_login'] ?? '' ) ? 'admins' : 'all';
$s['link_email'] = empty( $post['link_email'] ) ? 0 : 1;
$s['wp_login'] = empty( $post['wp_login'] ) ? 0 : 1;
$role = sanitize_key( (string) ( $post['role'] ?? '' ) );
$s['role'] = ( '' === $role || PRPS_Users::is_safe_role( $role ) ) ? $role : '';
$redirect = esc_url_raw( (string) ( $post['redirect'] ?? '' ) );
$s['redirect'] = $redirect && wp_validate_redirect( $redirect, '' ) ? $redirect : '';
}
/**
* Сохранение настроек дополнений.
*
* @param array $s Настройки.
* @param string $tab Вкладка.
* @param array $post Очищенные данные формы.
*/
$s = apply_filters( 'prps/save_settings', $s, $tab, $post );
PRPS_Settings::update( $s );
wp_safe_redirect( self::url( $tab, array( 'prps_saved' => 1 ) ) );
exit;
}
/** Проверка ключа SMS.ru: баланс. */
public static function ajax_balance() {
check_ajax_referer( 'prps_admin', 'nonce' );
if ( ! current_user_can( self::CAP ) ) {
wp_send_json_error( array( 'message' => __( 'Недостаточно прав', 'propusk' ) ) );
}
if ( ! PRPS_Smsru::ready() ) {
wp_send_json_error( array( 'message' => __( 'Сначала сохраните ключ API.', 'propusk' ) ) );
}
$balance = PRPS_Smsru::balance();
if ( is_wp_error( $balance ) ) {
wp_send_json_error( array( 'message' => $balance->get_error_message() ) );
}
/* translators: %s: сумма в рублях */
wp_send_json_success( array( 'message' => sprintf( __( 'Ключ работает. Баланс: %s ₽', 'propusk' ), number_format_i18n( $balance, 2 ) ) ) );
}
/* =====================================================================
* Колонка в списке пользователей
* =================================================================== */
public static function users_column( $cols ) {
$cols['prps'] = esc_html__( 'Вход', 'propusk' );
return $cols;
}
public static function users_cell( $out, $col, $user_id ) {
if ( 'prps' !== $col ) {
return $out;
}
$list = array();
foreach ( array( 'phone', 'vk', 'yandex', 'max' ) as $p ) {
if ( '' !== (string) get_user_meta( $user_id, PRPS_Users::meta_key( $p ), true ) ) {
$list[] = '' . esc_html( PRPS_Users::label( $p ) ) . '';
}
}
return $list ? '' . implode( ' ', $list ) . '' : '' . esc_html__( 'пароль', 'propusk' ) . '';
}
/* =====================================================================
* Отрисовка
* =================================================================== */
public static function tabs() {
$tabs = array(
'overview' => __( 'Обзор', 'propusk' ),
'phone' => __( 'Телефон', 'propusk' ),
'social' => __( 'VK ID и Яндекс ID', 'propusk' ),
'login' => __( 'Регистрация и вход', 'propusk' ),
);
if ( ! PRPS_Plugin::has_pro_addon() ) {
$tabs['pro'] = '★ Pro-версия';
}
/**
* Вкладки страницы плагина.
*
* @param array $tabs Вкладки.
*/
return (array) apply_filters( 'prps/admin_tabs', $tabs );
}
private static function tab_icon( $tab ) {
$icons = array(
'overview' => 'dashicons-yes-alt',
'phone' => 'dashicons-smartphone',
'social' => 'dashicons-id',
'login' => 'dashicons-admin-users',
'pro' => 'dashicons-star-filled',
);
/**
* Иконка вкладки.
*
* @param string $icon Класс dashicons.
* @param string $tab Вкладка.
*/
return (string) apply_filters( 'prps/admin_tab_icon', $icons[ $tab ] ?? 'dashicons-admin-generic', $tab );
}
public static function header() {
$is_pro = PRPS_Plugin::has_pro_addon();
echo '';
echo '';
echo '' . esc_html__( 'Вход 406-ФЗ', 'propusk' );
echo $is_pro ? ' Pro' : ' ' . esc_html__( 'Бесплатная версия', 'propusk' ) . '';
echo '
' . esc_html__( 'Вход и регистрация по номеру телефона, через VK ID и Яндекс ID — как требует закон 406-ФЗ', 'propusk' ) . '
';
echo '';
if ( ! $is_pro ) {
printf( '
%s', esc_url( self::url( 'pro' ) ), esc_html__( '★ Получить Pro', 'propusk' ) );
}
echo '
';
}
public static function render() {
if ( ! current_user_can( self::CAP ) ) {
return;
}
$tabs = self::tabs();
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : 'overview';
$tab = isset( $tabs[ $tab ] ) ? $tab : 'overview';
echo '';
self::header();
echo '
';
echo '
';
if ( 'pro' === $tab ) {
PRPS_Admin_Pro_Page::render();
} elseif ( method_exists( 'PRPS_Admin_Views', $tab ) ) {
PRPS_Admin_Views::$tab();
} else {
/**
* Вкладка дополнения.
*
* @param string $tab Вкладка.
*/
do_action( 'prps/admin_tab', $tab );
}
echo '
';
}
/** Карточка-раздел (используется и Pro). */
public static function card_open( $title, $desc = '', array $args = array() ) {
echo '';
if ( '' !== $title ) {
echo '';
if ( ! empty( $args['icon'] ) ) {
echo '
';
}
echo '
' . wp_kses_post( $title ) . '
';
if ( '' !== $desc ) {
echo '
' . wp_kses_post( $desc ) . '
';
}
echo '
';
}
echo '';
}
public static function card_close() {
echo '
';
}
/** Начало формы вкладки. */
public static function form_open( $tab ) {
echo '';
}
}