| Server IP : 116.153.78.57 / Your IP : 43.159.78.123 Web Server : nginx/1.28.0 System : Linux 1763701629066 6.8.0-53-generic #55-Ubuntu SMP PREEMPT_DYNAMIC Fri Jan 17 15:37:52 UTC 2025 x86_64 User : www ( 1001) PHP Version : 8.2.28 Disable Function : passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /www/wwwroot/www.lengcat.cn/wp-content/themes/onenav/inc/functions/ |
Upload File : |
<?php
/*
* @Author: iowen
* @Author URI: https://www.iowen.cn/
* @Date: 2023-01-17 22:37:17
* @LastEditors: iowen
* @LastEditTime: 2025-06-04 15:47:01
* @FilePath: /onenav/inc/functions/io-user.php
* @Description:
*/
/**
* 用户中心是否开启
* @return bool
*/
function io_user_center_enable(){
if(is_login() && isset($_GET['uc_key']) && $_GET['uc_key'] === io_get_option('uc_key')){
return false;
}
return io_get_option('user_center', false) ? true : false;
}
/**
* 获取隐藏的手机号码
* @param string $phone
* @return string
*/
function io_hide_phone($phone){
if (strlen($phone) > 10) {
return substr_replace($phone, '****', 3, 4);
}
return $phone;
}
/**
* 隐藏邮箱号码
* @param string $email
* @return string
*/
function io_hide_email($email){
$email_args = explode('@', $email);
if (isset($email_args[0])) {
return substr($email_args[0], 0, 1) . '****' . substr($email_args[0], -1) . '@' . $email_args[1];
}
return $email;
}
/**
* 获取隐藏的内容
* @param mixed $to
* @param mixed $type
* @return string
*/
function io_get_hide_info($to, $type){
if ('email' === $type)
return io_hide_email($to);
else
return io_hide_phone($to);
}
/**
* 获取用户的手机号码
* @param int $user_id
* @param bool $hide
* @return mixed
*/
function io_get_user_phone($user_id, $hide = true)
{
$phone = get_user_meta($user_id, 'phone_number', true);
if (!$phone) {
return false;
}
if ($hide) {
return io_hide_phone($phone);
}
return $phone;
}
/**
* 获取用户权限描述字符.
* @param mixed $user_id
* @return string
*/
function io_get_user_cap_string($user_id)
{
if(!$user_id) {
return __('游客', 'i_theme');
}
if (user_can($user_id, 'manage_options')) {
return __('管理员', 'i_theme');
}
if (user_can($user_id, 'edit_others_posts')) {
return __('编辑', 'i_theme');
}
if (user_can($user_id, 'publish_posts')) {
return __('作者', 'i_theme');
}
if (user_can($user_id, 'edit_posts')) {
return __('投稿者', 'i_theme');
}
return __('读者', 'i_theme');
}
/**
* 根据meta获取用户
* 检查手机号是否存在
*
* @param mixed $value meta 值,如:手机号
* @param mixed $field
* @return mixed
*/
function io_get_user_by( $value, $field = 'phone')
{
$cache = wp_cache_get($value, 'user_by_' . $field, true);
if (false !== $cache) {
return $cache;
}
$query = new WP_User_Query(array('meta_key' => 'phone_number', 'meta_value' => $value));
if (!is_wp_error($query) && !empty($query->get_results())) {
$user = $query->get_results()[0];
wp_cache_set($value, $user, 'user_by_' . $field);
return $user;
} else {
return false;
}
}
/**
* 绑定手机号,清空对应缓存
* @param mixed $user_id
* @param mixed $type
* @param mixed $new_phone
* @param mixed $old_phone
* @return void
*/
function io_bind_phone_del_cache($user_id, $type, $new_phone, $old_phone){
wp_cache_delete($old_phone, 'user_by_phone');
}
add_action('io_user_bind_new_email_or_phone', 'io_bind_phone_del_cache', 10, 4);
/**
* 是否禁止注册
*
* @return bool
*/
function io_is_close_register(){
if (is_super_admin()) {
return false;
}
return !get_option('users_can_register');
}
/**
* Summary of io_get_user_cover
* @param mixed $user_id
* @param mixed $size
* @param mixed $default
* @return mixed
*/
function io_get_user_cover($user_id, $size = 'full', $default = ''){
if (!in_array($size, array('full', 'mini'))) {
$size = 'full';
}
if ($cover = get_user_meta($user_id, 'io_user_cover', true)) {
return $cover . $size . '.jpg';
}
return $default ? $default : get_theme_file_uri('/assets/images/user-default-cover-'.$size.'.jpg');
}
/**
* 保存用户的验证成功状态
* @param mixed $type
* @param mixed $user_id
* @return void
*/
function io_set_user_verify_state($type, $user_id){
if(!session_id()) session_start();
$_SESSION['user_verify_state_' . $type . '_' . $user_id] = current_time('mysql');
io_refresh_captcha_time();
}
/**
* 校验用户验证是否通过
* @param mixed $type
* @param mixed $user_id
* @return array
*/
function io_is_user_verify($type, $user_id){
$name = array(
'email' => __('旧邮箱', 'i_theme'),
'phone' => __('旧手机号', 'i_theme'),
);
if(!session_id()) session_start();
if (empty($_SESSION['user_verify_state_' . $type . '_' . $user_id])) {
return array('error' => 1, 'msg' => sprintf( '%s验证失败!',$name[$type]));
} else {
$time_x = strtotime(current_time('mysql')) - strtotime($_SESSION['user_verify_state_' . $type . '_' . $user_id]);
if ($time_x > (60*5)) { // 5分钟
return array('error' => 1, 'msg' => sprintf( '%s验证已过期,请重新验证!',$name[$type]));
}
return array('error' => 0, 'msg' => sprintf( '%s验证成功!',$name[$type]));
}
}
/**
* 刷新验证码限制时间
* @param mixed $second
* @return void
*/
function io_refresh_captcha_time($second = 60){
if(!session_id()) session_start();
if (!empty($_SESSION['code_time'])) {
$_SESSION['code_time'] = date('Y-m-d H:i:s', strtotime('-' . $second . ' second', strtotime($_SESSION['code_time'])));
}
}
/**
* 强制绑定邮箱或手机
* @return void
*/
function io_redirect_user_bind_page()
{
$is_bind = io_get_option('bind_email','must');
$bind_type = io_get_option('bind_type',array());
if ( $is_bind!='must' || empty($bind_type) || is_super_admin() ) {
return;
}
$user = wp_get_current_user();
$tab = !empty($_GET['action']) ? $_GET['action'] : '';
$redirect_to = !empty($_GET['redirect_to']) ? $_GET['redirect_to'] : home_url();
if (!empty($user->ID) && !is_admin() && 'bind' != $tab) {
//已经登录
$email = $user->user_email;
if (!$email && in_array('email', $bind_type)) {
$bind_url = add_query_arg('redirect_to', $redirect_to, home_url().'/login/?action=bind&type=bind');
wp_safe_redirect($bind_url);
exit;
}
$phone = io_get_user_phone($user->ID);
if (!$phone && in_array('phone', $bind_type)) {
$bind_url = add_query_arg('redirect_to', $redirect_to, home_url().'/login/?action=bind&type=bind');
wp_safe_redirect($bind_url);
exit;
}
}
}
add_action('template_redirect', 'io_redirect_user_bind_page');
function is_user_page($name){
return get_query_var('user_child_route') == $name;
}
/**
* 绑定提示
* @return void
*/
function add_remind_bind(){
$user = wp_get_current_user();
$is_bind = io_get_option('bind_email','');
if(!$user->ID || $is_bind!='bind' || is_404() || !io_get_option('remind_bind',false) || is_user_page('security') || is_io_login()) {
return;
}
$bind_type = io_get_option('bind_type',array());
$title = '';
$email = $user->user_email;
if (!$email && in_array('email', $bind_type)) {
$title = __('你没有绑定邮箱!','i_theme');
} else {
$phone = io_get_user_phone($user->ID);
if (!$phone && in_array('phone', $bind_type)) {
$title = __('你没有绑定手机号!','i_theme');
}else{
return;
}
}
if( !io_get_option('remind_only',false) || ( io_get_option('remind_only',false) && !isset($_COOKIE['io_remind_only'])) || (isset($_COOKIE['io_remind_only'])&& $_COOKIE['io_remind_only']!="1") ){
?>
<div id='io-remind-bind' class="io-bomb">
<div class="io-bomb-overlay"></div>
<div class="io-bomb-body text-center" style="max-width:260px">
<div class="io-bomb-content rounded bg-white p-3">
<i class="iconfont icon-tishi text-128 text-success"></i>
<p class="text-md mt-3"><?php echo $title ?></p>
<a href="<?php echo home_url().'/login/?action=bind&type=bind' ?>" class="btn btn-danger mt-3 popup-bind-close"><?php _e('前往绑定','i_theme') ?></a>
</div>
<div class="btn-close-bomb mt-2 text-center">
<i class="iconfont popup-bind-close icon-close-circle"></i>
</div>
</div>
<script>
$(document).ready(function(){
<?php echo io_get_option('remind_only',false)?"if(getCookie('io_remind_only')!=1)":"" ?>
$('#io-remind-bind').addClass('io-bomb-open');
});
$(document).on('click','.popup-bind-close',function() {
$('#io-remind-bind').removeClass('io-bomb-open').addClass('io-bomb-close');
<?php echo (io_get_option('remind_only',false)?'setCookie("io_remind_only",1,1);':'') ?>
setTimeout(function(){
$('#io-remind-bind').remove();
},600);
});
</script>
</div>
<?php
}
}
add_action( 'wp_footer', 'add_remind_bind' );
/**
* 绑定按钮
* @param mixed $user_id
* @return string
*/
function io_bind_oauth_html( $user_id ){
if (!$user_id) {
return '';
}
$btn = '';
$like = io_get_uc_link('safe');
$args = get_social_type_data();
$weixin_type = io_get_option('open_weixin_gzh_key', 'gzh', 'type');
foreach ($args as $arg) {
$name = $arg['name'];
$type = $arg['type'];
$class = $arg['class'];
$name_key = $arg['n_key'];
$icon = '<i class="iconfont ' . $arg['icon'] . '"></i>';
if ('alipay' == $type) {
if (wp_is_mobile() && !strpos($_SERVER['HTTP_USER_AGENT'], 'Alipay')) {
continue;
}
}
$bind_href = io_get_oauth_login_url($type, $like);
if ($bind_href) {
$meta_key = $type;
if ('weixin_gzh' == $type) {
$meta_key = 'wechat_'.$weixin_type;
}
$oauth_info = get_user_meta($user_id, $meta_key . '_getUserInfo', true);
$oauth_id = get_user_meta($user_id, $meta_key . '_openid', true);
$_btn = '';
if ( $oauth_id ) {
$name .= !empty($oauth_info['name']) ? ' ' . esc_attr($oauth_info['name']) : (!empty($oauth_info[$name_key]) ? ' ' . esc_attr($oauth_info[$name_key]) : __('帐号','i_theme'));
$_btn = '<a data-toggle="tooltip" href="javascript:;" openid="' . esc_attr($oauth_id) . '" title="'.__('解绑','i_theme') . $name . '" data-user_id="' . $user_id . '" data-type="' . $type . '" data-action="unbound_open_id" class="btn btn-block unbound-open-id vc-l-violet '.$class.'">' . $icon . ' ' . __('已绑定','i_theme') . $name . '</a>';
} else {
if ('weixin_gzh' === $type) {
$class .= ' qrcode-signin is-popup weixin-' . $weixin_type;
}
$_btn = '<a data-toggle="tooltip" title="'.__('绑定','i_theme') . $name . '" href="' . esc_url(add_query_arg(array('bind' => $type), $bind_href)) . '" class="btn btn-block btn-outline vc-blue '.$class.'">' . $icon . ' ' . __('绑定','i_theme') . $name . __('帐号','i_theme') . '</a>';
}
$btn .= '<div class="col-12 col-md-6 my-2">'.$_btn.'</div>';
}
}
if (io_get_option('open_prk',false)) {
$list = io_get_option('open_prk_list','');
$bind_href = io_get_oauth_login_url('prk', io_get_current_url());
if (is_array($list)) {
foreach ($list as $type) { //聚合登录增加前置io_
$oauth_info = get_user_meta($user_id, 'io_' . $type . '_getUserInfo', true);
$oauth_id = get_user_meta($user_id, 'io_' . $type . '_openid', true);
$name = get_open_login_name($type);
$_btn = '';
$ico = $type;
if('wx'===$type){
$ico = 'wechat';
}
if('sina'===$type){
$ico = 'weibo';
}
$icon = '<i class="iconfont icon-' . $ico . '"></i>';
if ($oauth_info && $oauth_id) {
$name .= !empty($oauth_info['nickname']) ? ' ' . esc_attr($oauth_info['nickname']) : __('帐号','i_theme');
$_btn = '<a data-toggle="tooltip" href="javascript:;" openid="' . esc_attr($oauth_id) . '" title="'.__('解绑','i_theme') . $name . '" data-user_id="' . $user_id . '" data-type="io_' . $type . '" data-action="unbound_open_id" class="btn btn-block unbound-open-id vc-l-violet ">' . $icon . ' ' . __('已绑定','i_theme') . $name . '</a>';
} else {
$_btn = '<a data-toggle="tooltip" title="'.__('绑定','i_theme') . $name . '" href="' . esc_url(add_query_arg(array('type' => $type), $bind_href)) . '" class="btn btn-block btn-outline vc-blue ' . $class . '">' . $icon . ' ' . __('绑定','i_theme') . $name . __('帐号','i_theme') . '</a>';
}
$btn .= '<div class="col-12 col-md-6 my-2">'.$_btn.'</div>';
}
}
}
$html = '<div class="text-lg pb-3 border-bottom border-color border-2w mb-3 mt-5">'.__('账号绑定','i_theme').'</div>';
$html .= '<div class="row">';
$html .= $btn;
$html .= '</div>';
return $html;
}
/**
* 后台用户表格添加自定义内容
* @param mixed $columns
* @return mixed
*/
function io_admin_users_columns($columns){
$orderby = isset($_REQUEST['orderby']) ? $_REQUEST['orderby'] : '';//箭头按钮
$order = isset($_REQUEST['order']) && 'desc' == $_REQUEST['order'] ? 'asc' : 'desc';
$_role = $columns['role'];
unset($columns['role']);
unset($columns['name']);
unset($columns['posts']);
unset($columns['email']);
$columns['user_data'] = '<a href="' . add_query_arg(array('orderby' => 'display_name', 'order' => $order)) . '"><span>昵称</span></a>';
$columns['user_data'] .= ' · <a href="' . add_query_arg(array('orderby' => 'email', 'order' => $order)) . '"><span>邮箱</span></a>';
$columns['user_data'] .= ' · <a href="' . add_query_arg(array('orderby' => 'phone_number', 'order' => $order)) . '"><span>手机号</span></a>';
$columns['oauth'] = '绑定账号';
$columns['all_time'] = '<a href="' . add_query_arg(array('orderby' => 'user_registered', 'order' => $order)) . '"><span>注册</span></a> · <a href="' . add_query_arg(array('orderby' => 'last_login', 'order' => $order)) . '"><span>登录</span></a>';
$columns['role'] = $_role;
return $columns;
}
add_filter('manage_users_columns', 'io_admin_users_columns');
/**
* 后台用户表格自定义内容
* @param mixed $output
* @param mixed $column_name
* @param mixed $user_id
* @return mixed
*/
function io_admin_output_users_columns($output, $column_name, $user_id){
$user = get_userdata($user_id);
switch ($column_name) {
case "user_data":
$user_email = empty($user->display_name) ? '未设置' : $user->display_name;
$user_email = empty($user->user_email) ? '未设置' : '<a href="mailto:' . $user->user_email . '">' . $user->user_email . '</a>';
$phone_number = get_user_meta($user->ID, 'phone_number', true)?:'未绑定';
return '<div style="font-size: 12px;">昵称:' . $user->display_name . '<br>邮箱:' . $user_email . '<br>手机:' . $phone_number . '</div>';
case "all_time":
$last_login = get_user_meta($user->ID, 'last_login', true);
$last_login = '最近登录:'. ($last_login ? '<span title="' . $last_login . '">' . io_date_time($last_login) . '</span>' : '--');
$reg_time = get_date_from_gmt($user->user_registered);
$reg_time = '注册时间:'. ($reg_time ? '<span title="' . $reg_time . '">' . io_date_time($reg_time) . '</span>' : '--');
$last_ip = get_user_meta($user->ID, 'last_login_ip', true);
$last_ip = '登录地点:'. ($reg_time ? '<span title="' . $last_ip . '">' . io_get_ip_location($last_ip) . '</span>' : '--');
return '<div style="font-size: 12px;">' . $reg_time . '<br>' . $last_login . '<br>' . $last_ip . '</div>';
case "oauth":
$args = get_social_type_data();
$oauth = array();
foreach ($args as $arg) {
$name = $arg['name'];
$type = $arg['type'];
if (io_get_oauth_login_url($type)) {
if ('weixin_gzh' == $type) {
$type = 'wechat_'.io_get_option('open_weixin_gzh_key', 'gzh', 'type');
}
$oauth_id = get_user_meta($user_id, $type . '_openid', true);
if ($oauth_id) {
$oauth[] = $name;
}
}
}
$html = $oauth ? '已绑定:' . implode('、', $oauth) : '未绑定';
return '<div style="font-size: 12px;">' . $html . '</div>';
}
return $output;
}
add_filter('manage_users_custom_column', 'io_admin_output_users_columns', 10, 3);
function io_admin_users_list_sort_query_args($args){
$orderby = isset($_REQUEST['orderby']) ? $_REQUEST['orderby'] : '';
if (in_array($orderby, array('last_login', 'phone_number'))) {
$args['orderby'] = 'meta_value';
$args['meta_key'] = $orderby;
}
//默认排序方式为注册时间
if (!isset($_REQUEST['orderby'])) {
$args['order'] = 'desc';
$args['orderby'] = 'user_registered';
}
return $args;
}
add_filter('users_list_table_query_args', 'io_admin_users_list_sort_query_args');
/**
* 用户中心绑定、修改信息html
*
* @param mixed $type
* @param mixed $user
* @param mixed $step
* @return string
*/
function io_get_user_bind_info_html($type = 'email', $user = '', $step = 1){
$user = $user ? : wp_get_current_user();
switch ($type) {
case 'email':
$name = __('邮箱','i_theme');
$to = $user->user_email;
$title = $to ? __('修改邮箱','i_theme'):__('绑定邮箱','i_theme');
$icon = 'icon-email';
break;
case 'phone':
$name = __('手机号','i_theme');
$to = io_get_user_phone($user->ID);
$title = $to ? __('修改手机号','i_theme'):__('绑定手机号','i_theme');
$icon = 'icon-phone-num';
break;
case 'password':
$is_new = get_user_meta($user->ID, 'oauth_new', true);
$title = $is_new ? __('设置密码','i_theme') : __('修改密码','i_theme');
$icon = 'icon-key-circle';
break;
case 'reset_password':
$title = __('重设密码','i_theme');
$icon = 'icon-key-circle';
break;
}
$head_fx = '';
$bind_tip = '';
if ('password' === $type) {
$head_fx = 'fx-yellow';
$bind_html = io_get_password_set_from($is_new, $user);
} elseif ('reset_password' === $type) {
$head_fx = 'fx-red';
$bind_html = io_get_password_reset_from($user);
} else {
if ($to) {
$bind_tip = '<div class="mx-3 mt-3 step-simple text-xs">
<span class="' . (1 === $step ? 'active' : '') . '">' . sprintf(__('验证旧%s', 'i_theme'), $name) . '</span>
<span class="' . (2 === $step ? 'active' : '') . '">' . sprintf(__('设置新%s', 'i_theme'), $name) . '</span>
<span class="' . (3 === $step ? 'active' : '') . '">' . __('修改成功', 'i_theme') . '</span></div>';
if (1 === $step) {
$bind_html = io_get_verify_user_from($to, $type);
} elseif (2 === $step) {
$bind_html = io_get_user_bind_from($type, false);
}
} else {
$bind_html = io_get_user_bind_from($type);
}
}
$html = '';
$html .= io_get_modal_header($head_fx, $icon);
$html .= '<div class="modal-body blur-bg">';
$html .= '<div class="text-center pt-3">'.$title.'</div>';
$html .= $bind_tip;
$html .= $bind_html;
$html .= '</div>';
return $html;
}
/**
* 验证邮箱或者手机权限
* @param mixed $to
* @param mixed $type
* @return string
*/
function io_get_verify_user_from($to, $type = 'email'){
$des = array(
'email' => __('获取验证码以验证旧邮箱:', 'i_theme'),
'phone' => __('获取验证码以验证旧手机号:', 'i_theme'),
);
$form = '';
$input = '<div class="mb-4">';
$input .= '<div class="text-xs text-muted mb-3">' . $des[$type] . '<code>'.io_get_hide_info($to, $type).'</code></div>';
$input .= '<div class="form-group verification mb-3">
<input type="text" name="verification_code" tabindex="3" id="verification_code" placeholder="' . __('验证码', 'i_theme') . '" size="6" class="form-control"/>
<a href="javascript:;" class="btn-token col-form-label text-sm" data-action="verify_user_email_or_phone_token">' . __('发送验证码', 'i_theme') . '</a>
</div>';
$input .= '<div class="form-group mb-3">'.get_captcha_input_html('verify_user_competence').'</div>';
$input .= '</div>';
$input .= '<input type="hidden" name="action" value="verify_user_competence">';
$input .= '<input type="hidden" name="type" value="' . $type . '">';
$input .= '<button type="submit" class="btn vc-blue btn-shadow btn-submit btn-block"><i class="iconfont icon-competence mr-1"></i>'.__('立即验证','i_theme').'</button>';
$form = '<form class="user-bind-from p-3">' . $input . '</form>';
return $form;
}
/**
* 绑定邮箱或者手机
* @param mixed $type
* @param mixed $is_new
* @return string
*/
function io_get_user_bind_from($type = 'email',$is_new = true){
$form = '';
$placeholder = array(
'email' => __('请输入邮箱', 'i_theme'),
'phone' => __('请输入手机号', 'i_theme'),
);
$des = array(
'email' => __('请输入您需要修改的新邮箱。', 'i_theme'),
'phone' => __('请输入您需要修改的新手机号。', 'i_theme'),
);
$input = '';
$input .= '<div class="mb-4">';
$input .= $is_new ? '' : '<div class="text-xs text-muted mb-1">' . $des[$type] . '</div>';
$input .= '<div class="form-group mb-3">
<input type="text" name="email_phone" tabindex="2" id="user_email" placeholder="' . $placeholder[$type] . '" size="30" class="form-control"/>
</div>
<div class="form-group mb-3 verification" style="display:none">
<input type="text" name="verification_code" tabindex="3" id="verification_code" placeholder="' . __('验证码', 'i_theme') . '" size="6" class="form-control"/>
<a href="javascript:;" class="btn-token col-form-label text-sm" data-action="bind_new_email_or_phone_token">' . __('发送验证码', 'i_theme') . '</a>
</div> ';
$input .= '<div class="form-group mb-3">'.get_captcha_input_html('user_bind_number_captcha').'</div>';
$input .= '</div>';
$input .= io_get_agreement_input();
$input .= '<input type="hidden" name="action" value="user_bind_new_email_or_phone">';
$input .= '<input type="hidden" name="type" value="' . $type . '">';
$input .= '<button type="submit" class="btn vc-blue btn-shadow btn-submit btn-block"><i class="iconfont icon-adopt mr-1"></i>'.__('确认提交','i_theme').'</button>';
$form = '<form class="user-bind-from p-3">' . $input . '</form>';
return $form;
}
/**
* 用户协议html
* @param mixed $checked
* @return string
*/
function io_get_agreement_input($checked = ''){
$option = io_get_option('user_agreement', array('switch'=>false));
$html = '';
if($option['switch']){
if(''===$checked ){
$checked = $option['default'];
}
$agreement = '';
if($option['pact_page']){
$agreement = ' <a target="_blank" href="' . get_permalink($option['pact_page']) . '">'.__('用户协议','i_theme').'</a>';
}
if($option['privacy_page']){
$agreement .= '、<a target="_blank" href="' . get_permalink($option['privacy_page']) . '">'.__('隐私声明','i_theme').'</a>';
}
$checked = $checked ? ' checked="checked"' : '';
$input = '<input type="checkbox" class="custom-control-input" name="user_agreement" id="user_agreement"' . $checked . ' value="agree">';
$input .= '<label class="custom-control-label" for="user_agreement">' . __('阅读并同意','i_theme') . $agreement . '</label>';
$html = '<div class="custom-control custom-checkbox text-xs mb-2 text-muted">' . $input . '</div>';
}
return $html;
}
/**
* 用户协议判断
* @return void
*/
function io_ajax_agreement_judgment(){
if (io_get_option('user_agreement', false, 'switch') && empty($_REQUEST['user_agreement'])) {
io_error (array('status' => 3, 'msg' => __('请先阅读并同意用户协议', 'i_theme')));
exit();
}
}
/**
* 获取安全信息设置按钮
*
* @param mixed $user
* @param mixed $type
* @return string
*/
function io_get_security_info_bind_btn($user, $type = 'email'){
if (!$user) {
return '';
}
switch ($type) {
case 'email':
$title = __('绑定邮箱','i_theme');
$to = $user->user_email;
$icon = 'icon-email';
break;
case 'phone':
$title = __('绑定手机','i_theme');
$to = io_get_user_phone($user->ID);
$icon = 'icon-phone-num';
break;
default:
$title = __('设置密码','i_theme');
$to = '';
$icon = 'icon-key-circle';
break;
}
$url = esc_url(add_query_arg(array('type' => $type, 'action' => 'get_user_security_info_set_modal'), admin_url( 'admin-ajax.php' )));
if('password'===$type){
$tip = __('修改密码','i_theme');
$class = 'vc-theme btn-shadow';
$name = $tip;
}else{
if($to){
$tip = __('换绑账号','i_theme');
$class = 'vc-l-gray';
$name = __('已绑定:','i_theme'). io_get_hide_info($to, $type);
}else{
$tip = __('绑定账号','i_theme');
$class = 'vc-l-red btn-outline';
$name = $title;
}
}
$html = '<div class="d-flex my-4 align-items-center">
<div class="text-sm text-muted">' . $title . '</div>
<a data-toggle="tooltip" title="' . $tip . '" href="' . $url . '" class="btn user-bind-modal btn-sm ml-auto ' . $class . '"><i class="iconfont ' . $icon . ' mr-2"></i>' . $name . '</a>
</div>';
return $html;
}
/**
* 获取密码设置表单
* @param mixed $is_new
* @param mixed $user
* @return string
*/
function io_get_password_set_from($is_new, $user){
$user_email = $user->user_email;
$phone = io_get_user_phone($user->ID);
$html = '';
$html .= '<form class="user-bind-from p-3">';
$html .= '<div class="mb-4">';
if (!$is_new) {
$html .= '<div class="form-group position-relative mb-3">';
$html .= '<input type="password" name="user_pass_old" tabindex="1" placeholder="' . __('请输入原密码','i_theme') . '" size="30" class="form-control"/>';
$html .= '<div class="password-show-btn" data-show="0"><i class="iconfont icon-chakan-line"></i></div>';
$html .= '</div>';
} else {
$html .= '<input type="hidden" name="oauth_new" value="' . $is_new . '">';
}
$html .= '<div class="form-group position-relative mb-3">';
$html .= '<input type="password" name="user_pass" tabindex="2" placeholder="' . __('请输入新密码','i_theme') . '" size="30" class="form-control"/>';
$html .= '<div class="password-show-btn" data-show="0"><i class="iconfont icon-chakan-line"></i></div>';
$html .= '</div>';
$html .= '<div class="form-group position-relative mb-3">';
$html .= '<input type="password" name="user_pass2" tabindex="3" placeholder="' . __('请再次输入新密码','i_theme') . '" size="30" class="form-control"/>';
$html .= '<div class="password-show-btn" data-show="0"><i class="iconfont icon-chakan-line"></i></div>';
$html .= '</div>';
$html .= '<div class="form-group mb-3">'.get_captcha_input_html('user_change_password').'</div>';
$html .= '</div>';
$html .= '<input type="hidden" name="action" value="user_change_password">';
$html .= '<button type="button" class="btn vc-yellow btn-shadow btn-submit btn-block"><i class="iconfont icon-adopt mr-1"></i>'.__('确认提交','i_theme').'</button>';
$html .= '</form>';
if (!$is_new && ($user_email || $phone)) {
$url = esc_url(add_query_arg(array('type' => 'reset_password', 'action' => 'get_user_security_info_set_modal'), admin_url( 'admin-ajax.php' )));
$html .= '<div class="text-right px-3 pb-2 mt-n3">';
$html .= '<a href="' . $url . '" class="text-xs user-reset-password text-muted"><i class="iconfont icon-tishi mr-1"></i>'.__('忘记密码?点击重设密码。','i_theme').'</a>';
$html .= '</div>';
}
return $html;
}
/**
* 重设密码表单
*
* @param mixed $user
* @return string
*/
function io_get_password_reset_from($user=''){
$user = $user ? : wp_get_current_user();
if(!$user->ID){
$html = '<form method="post" class="wp-user-form" id="wp_login_form">';
}else{
$html = '<form class="p-3" id="wp_login_form">';
}
$html .= '<div class="form-group mb-3">
<input type="text" name="email_phone" tabindex="2" id="user_email" placeholder="' . get_reg_name('lost_verify') . '" size="30" class="form-control input-material"/>
</div>
<div class="form-group mb-3 verification" style="display:none">
<input type="text" name="verification_code" tabindex="3" id="verification_code" placeholder="' . __('验证码', 'i_theme') . '" size="6" class="form-control input-material"/>
<a href="javascript:;" class="btn-token col-form-label text-sm" data-action="lost_email_or_phone_token">' . __('发送验证码', 'i_theme') . '</a>
</div>
<div class="form-group position-relative mb-3">
<input type="password" name="user_pass" tabindex="4" id="user_pwd1" placeholder="' . __('密码', 'i_theme') . '" size="30" class="form-control input-material"/>
<div class="password-show-btn" data-show="0"><i class="iconfont icon-chakan-line"></i></div>
</div>
<div class="form-group position-relative mb-3">
<input type="password" name="user_pass2" tabindex="5" id="user_pwd2" placeholder="' . __('确认密码', 'i_theme') . '" size="30" class="form-control input-material"/>
<div class="password-show-btn" data-show="0"><i class="iconfont icon-chakan-line"></i></div>
</div>
<div class="form-group mb-3">' . get_captcha_input_html('reset_password', 'form-control input-material') . '</div>
<div class="login_fields">
<input type="hidden" name="action" value="reset_password" />
<input type="submit" id="submit" name="user-submit" value="' . __('提交', 'i_theme') . '" class="btn vc-theme btn-block btn-shadow" />
'.(!$user->ID?'':'<input type="hidden" name="redirect_to" value="' . io_get_current_url() . '?reset=true" />').'
</div>';
$html .= '</form>';
return $html;
}
function io_user_restrict_admin() {
$can = 'manage_options';
if(io_get_option('edit_to_admin', false)){
$can = 'edit_posts'; //'edit_others_posts';
}
if (is_admin() && !current_user_can($can) && !wp_doing_ajax()) {
wp_redirect(home_url('user/'));
exit;
}
}
add_action( 'admin_init', 'io_user_restrict_admin', 1 );
/**
* 获取用户不同状态的文章数量
* @param int $user_id
* @param int $status
* @return int
*/
function get_user_post_count($user_id, $status = 'publish', $post_type = 'post') {
global $wpdb;
if(!$user_id){
return 0;
}
$cache_key = 'post_count_' . $user_id . '_' . $status;
$cache_num = wp_cache_get($cache_key, 'post_count_' . $post_type, true);
if (false !== $cache_num) {
return $cache_num;
}
if ('all' == $status) {
$count = $wpdb->get_var($wpdb->prepare("SELECT COUNT(`ID`) FROM $wpdb->posts WHERE `post_author` = %d AND `post_type` = %s", $user_id, $post_type));
} else {
$count = $wpdb->get_var($wpdb->prepare("SELECT COUNT(`ID`) FROM $wpdb->posts WHERE `post_author` = %d AND `post_type` = %s AND `post_status` = %s", $user_id, $post_type, $status));
}
wp_cache_set($cache_key, $count, 'post_count_' . $post_type, DAY_IN_SECONDS);
return $count;
}
/**
* 获取作者签名
*/
function get_user_desc($user_id) {
$des = get_user_meta($user_id, 'description', true);
if (!$des) {
$des = __('帅气的我简直无法用语言描述!', 'i_theme');
}
return esc_attr($des);
}
/**
* 获取用户点赞、查看数量
* @param mixed $user_id
* @return mixed
*/
function io_get_user_badges($user_id, $rand_color = false)
{
if (!$user_id) {
return;
}
$post_n = io_number_format(get_user_post_count($user_id, 'publish'));
$com_n = io_number_format(get_user_comment_count($user_id));
$like_n = io_number_format(get_user_posts_meta_sum($user_id, '_like_count'));
$view_n = io_number_format(get_user_posts_meta_sum($user_id, 'views'));
$user_url = get_author_posts_url($user_id);
$badges = array(
array(
'title' => sprintf(__('共%s篇文章', 'i_theme'), strip_tags($post_n)),
'icon' => 'icon-post',
'text' => $post_n,
'color' => $rand_color ? 'vc-l-blue' : 'vc-l-white',
'url' => $user_url
),
array(
'title' => sprintf(__('共%s条评论', 'i_theme'), strip_tags($com_n)),
'icon' => 'icon-comment',
'text' => $com_n,
'color' => $rand_color ? 'vc-l-purple' : 'vc-l-white',
'url' => $user_url
),
array(
'title' => sprintf(__('获得%s个赞', 'i_theme'), strip_tags($like_n)),
'icon' => 'icon-like-line',
'text' => $like_n,
'color' => $rand_color ? 'vc-l-yellow' : 'vc-l-white',
'url' => $user_url
),
array(
'title' => __('人气 ', 'i_theme') . strip_tags($view_n),
'icon' => 'icon-hot',
'text' => $view_n,
'color' => $rand_color ? 'vc-l-red' : 'vc-l-white',
'url' => $user_url
)
);
$badges = apply_filters('user_count_badges', $badges, $user_id);
$html = '';
foreach ($badges as $badge) {
$html .= '<span class="badge ' . $badge['color'] . ' flex-fill" data-toggle="tooltip" title="' . $badge['title'] . '"><i class="iconfont ' . $badge['icon'] . '"></i>' . $badge['text'] . '</span>';
}
return $html;
}
/**
* 获取用户操作面板
* @return string
*/
function io_get_menu_user_box($class = '') {
static $html = null;
if (null !== $html) {
return '<div class="menu-user-box ' . $class . '">' . $html . '</div>';
}
if (io_is_close_register() && !is_user_logged_in()) {
$html = '';
return $html;
}
$user = wp_get_current_user();
$user_id = $user->ID;
$con = '';
if ($user_id) {
$btn = '<div class="d-flex justify-content-around mt-2">';
$btn .= io_get_menu_user_btn(home_url('user/'), 'icon-user', __('个人中心', 'i_theme'), 'vc-l-blue', false);
if (io_get_option('is_contribute', true)) {
$btn .= io_get_menu_user_btn(io_get_template_page_url('template-contribute.php'), 'icon-creation', __('收录投稿', 'i_theme'), 'vc-l-purple', false);
}
$btn .= io_get_menu_user_btn(wp_logout_url(home_url()), 'icon-quit', __('安全退出', 'i_theme'), 'vc-l-red', false);
$btn .= '</div>';
if (is_super_admin()) {
$btn .= '<div class="d-flex justify-content-around mt-2">';
$btn .= io_get_menu_user_btn(io_get_admin_iocf_url(), 'icon-theme', __('主题设置', 'i_theme'), 'vc-l-yellow');
$btn .= io_get_menu_user_btn(io_get_admin_iocf_url('', 'home_module'), 'icon-home-config', __('首页配置', 'i_theme'), 'vc-l-cyan');
$btn .= io_get_menu_user_btn(admin_url(), 'icon-seting', __('后台管理', 'i_theme'), 'vc-l-yellow');
$btn .= '</div>';
}
$con .= io_get_user_box($user);
$con .= '<div class="mt-2 text-center user-btn">' . $btn . '</div>';
} else {
$btn = '<div class="d-flex justify-content-around mt-2">';
$btn .= io_get_menu_user_btn(wp_login_url(io_get_current_url()), 'icon-user', __('登录', 'i_theme'), 'vc-l-blue');
$btn .= io_get_menu_user_btn(wp_registration_url(), 'icon-register', __('注册', 'i_theme'), 'vc-l-green');
$btn .= io_get_menu_user_btn(wp_lostpassword_url(io_get_current_url()), 'icon-password', __('找回密码', 'i_theme'), 'vc-l-yellow');
$btn .= '</div>';
$con .= io_get_user_box($user);
$con .= '<div class="text-center user-btn">' . $btn . '</div>';
$social_btn = '';//get_social_login_btn(); TODO 微信登陆需要弹窗登录支持。。。。。。。。。。。
if ($social_btn) {
$con .= '<p class="social-separator my-3">' . __('快速登录', 'i_theme') . '</p>';
$con .= '<div class="social-login-btn my-2 d-flex flex-wrap justify-content-center">';
$con .= $social_btn;
$con .= '</div>';
}
}
$html = $con;
return '<div class="menu-user-box ' . $class . '">' . $html . '</div>';
}
/**
* 获取用户信息框
* @param mixed $user
* @return string
*/
function io_get_user_box($user) {
$user_id = $user->ID;
if ($user_id) {
$url = get_author_posts_url($user_id);
$avatar = get_avatar($user_id);
$user_name = $user->display_name;
$desc = get_user_desc($user_id);
$badge = io_get_user_badges($user_id);
$badge = $badge ? '<div class="author-badge mt-2 d-flex justify-content-center">' . $badge . '</div>' : '';
} else {
$url = wp_login_url(io_get_current_url());
$avatar = '<img src="' . get_theme_file_uri('/assets/images/gravatar.jpg') . '" class="avatar avatar-96 photo" height="96" width="96">';
$user_name = __('未登录', 'i_theme');
$desc = __('登录后即可体验更多功能', 'i_theme');
$badge = '';
}
$user_box = '<div class="nav-user-box br-lg mt-n5 fx-bg fx-shadow px-3 py-2" js-href="' . esc_url($url) . '">';
$user_box .= '<div class="user-info d-flex align-items-center position-relative">';
$user_box .= '<div class="avatar-img">' . $avatar . '</div>';
$user_box .= '<div class="user-right flex-fill overflow-hidden ml-2">';
$user_box .= '<b>' . $user_name . '</b><div class="text-xs line1">' . $desc . '</div>';
$user_box .= '</div>';
$user_box .= '</div>';
$user_box .= $badge;
$user_box .= '</div>';
return $user_box;
}
/**
* 获取用户操作按钮
* @param mixed $link
* @param mixed $icon
* @param mixed $text
* @param mixed $color
* @param bool $target
* @param string $class
* @param string $type
* @return string
*/
function io_get_menu_user_btn($link, $icon, $text, $color, $target = true, $class = '', $type = 'box') {
$target = $target ? 'target="_blank"' : '';
$icon = $icon ? '<i class="iconfont ' . $icon . '"></i>' : '';
if ($type == 'box') {
$btn = '<button js-href="' . esc_url($link) . '" class="btn menu-user-btn text-xs flex-fill ' . $class . ' ' . $color . '" ' . $target . ' rel="nofollow">' . $icon . '<span class="white-nowrap">' . $text . '</span></button>';
} else {
$btn = '<button js-href="' . esc_url($link) . '" class="menu-user-btn" ' . $target . ' rel="nofollow"><div class="badge ' . $color . ' i-btn">' . $icon . '</div><div class="' . $color . ' text-color">' . $text . '</div></button>';
}
return $btn;
}
/**
* 获取用户收藏的已发布文章 ID 列表。
*
* 验证文章状态
* 缓存验证结果
*
* @param int|string|null $user_id 用户 ID,如果为空则默认获取当前用户 ID。
* @param string $post_type 文章类型,默认 'sites',可为 'app'、'book'、'post' 等。
* @return int[] 返回已发布状态的文章 ID 数组。
*/
function io_get_user_star_post_ids($user_id = null, $post_type = 'sites')
{
$user_id = absint($user_id ?: get_current_user_id());
if (!$user_id) {
return [];
}
$cache_key = 'user_star_' . $user_id . '_' . sanitize_key($post_type);
$cached_posts = wp_cache_get($cache_key, 'user_stars');
if ($cached_posts) {
return $cached_posts;
}
$meta_key = 'io_star_' . sanitize_key($post_type);
$starred_posts = get_user_meta($user_id, $meta_key, true) ?: [];
// 空数组直接返回
if (empty($starred_posts)) {
return [];
}
// 批量查询所有文章状态
$valid_posts = get_posts([
'post__in' => $starred_posts,
'post_status' => 'publish',
'post_type' => $post_type,
'fields' => 'ids', // 只返回ID
'posts_per_page' => -1, // 获取全部
'no_found_rows' => true, // 禁用分页计数
'update_post_meta_cache' => false, // 不更新meta缓存
'update_post_term_cache' => false, // 不更新term缓存
]);
wp_cache_set($cache_key, $valid_posts, 'user_stars', DAY_IN_SECONDS);
// 只在有变化时更新(比较数组差异)
if (array_diff($starred_posts, $valid_posts)) {
update_user_meta($user_id, $meta_key, $valid_posts);
}
return $valid_posts;
}
/**
* 用户收藏变更时清除所有缓存层
*/
add_action('updated_user_meta', function ($meta_id, $user_id, $meta_key, $_meta_value) {
if (strpos($meta_key, 'io_star_') === 0) {
$post_type = substr($meta_key, 8);
$cache_key = 'user_star_' . $user_id . '_' . $post_type;
wp_cache_delete($cache_key, 'user_stars'); // 清除对象缓存
}
}, 10, 4);
/**
* 获取文章收藏数量.
* @param mixed $post_id 文章ID
* @return int
*/
function io_get_posts_star_count($post_id)
{
$post_id = $post_id ? $post_id : get_the_ID();
$star = get_post_meta($post_id, '_star_count', true);
if ('' === $star) {
$star = 0;
// 初始化收藏数
update_post_meta($post_id, '_like_count', 0);
}
return $star;
}
/**
* 判断是否文章是否被当前用户收藏.
* @param mixed $post_id
* @param mixed $post_type 文章类型
* @return bool
*/
function io_is_my_star($post_id = '', $post_type = '')
{
if (!is_user_logged_in()) {
return false;
}
if (empty($post_type)) {
$post_type = get_post_type($post_id);
}
$user_star_post = (array)get_user_meta(get_current_user_id(), 'io_star_' . $post_type, true);
if (in_array($post_id, $user_star_post)) {
return true;
}
return false;
}
/**
* 统计用户收藏的文章数.
* @param mixed $user_id
* @param mixed $post_type
* @return int
*/
function io_count_user_star_posts($user_id, $post_type = "sites")
{
$ids = io_get_user_star_post_ids($user_id, $post_type);
if ($ids) {
return count($ids);
}
return 0;
}
/**
* 统计用户收藏的所有文章数.
* @param mixed $user_id
* @return int
*/
function io_count_user_star_all_posts($user_id)
{
$count = 0;
$post_types = array('sites', 'app', 'book', 'post');
foreach ($post_types as $post_type) {
$count += io_count_user_star_posts($user_id, $post_type);
}
return $count;
}