@@ -1,9 +1,5 @@
< ? php
/**
* Native WordPress identity certification operations.
*
* @package AKSRT
*/
/** Native WordPress identity application review. @package AKSRT */
namespace AKSRT\Admin\Native ;
@@ -11,214 +7,177 @@ defined('ABSPATH') || exit;
trait UsersMenusVerify {
private function count_verify_status ( string $status ) : int {
global $wpdb ;
$table = \AKSRT\Core\DBMigrator :: table ( 'identity_application' );
return ( int ) $wpdb -> get_var ( $wpdb -> prepare ( " SELECT COUNT(*) FROM { $table } WHERE status = %s " , $status )) ;
}
private function count_verify_status ( string $status ) : int {
global $wpdb ;
$table = \AKSRT\Core\DBMigrator :: table ( 'identity_application' );
$stored = $status === 'pending' ? 'manual_pending' : $status ;
return ( int ) $wpdb -> get_var ( $wpdb -> prepare (
" SELECT COUNT(*) FROM { $table } WHERE type = %s AND channel = %s AND status = %s " ,
'general' ,
'manual' ,
$stored
));
}
public function render_verify_page () : void {
$this -> ensure_cap ();
$filters = $this -> get_verify_filters ();
$page_num = max ( 1 , ( int ) ( $_GET [ 'paged' ] ? ? 1 ));
$result = $this -> query_verify_requests ( $filters , $page_num , 20 );
$counts = $this -> get_verify_status_counts ();
echo '<div class="wrap"><h1>' . esc_html__ ( '身份认证' , 'aksrt' ) . '</h1>' ;
$this -> flash ();
echo '<p>' . esc_html ( sprintf ( __ ( '人工 待审 %1$d · 已通过 %2$d · 已驳回 %3$d · 已取消 %4$d ' , 'aksrt' ), $counts [ 'pending' ], $counts [ 'verifi ed' ], $counts [ 'rejected' ], $counts [ 'cancelled' ])) . '</p>' ;
$this -> render_verify_filters ( $filters );
$this -> render_verify_table ( $result [ 'items' ]);
$this -> pagination ( $result [ 'pages' ], $page_num );
echo '</div>' ;
}
public function render_verify_page () : void {
$this -> ensure_cap ();
$filters = $this -> get_verify_filters ();
$page = max ( 1 , ( int ) ( $_GET [ 'paged' ] ? ? 1 ));
$data = $this -> query_verify_requests ( $filters , $page , 20 );
$counts = $this -> get_verify_status_counts ();
echo '<div class="wrap"><h1>' . esc_html__ ( '身份认证' , 'aksrt' ) . '</h1>' ;
$this -> flash ();
printf ( '<p>%s</p>' , esc_html ( sprintf ( __ ( '待审核 %1$d · 已通过 %2$d · 已拒绝 %3$d' , 'aksrt' ), $counts [ 'pending' ], $counts [ 'approv ed' ], $counts [ 'rejected' ]))) ;
$this -> render_verify_filters ( $filters );
$this -> render_verify_table ( $data [ 'items' ]);
$this -> pagination ( $data [ 'pages' ], $page );
echo '</div>' ;
}
/** @return array{status:string,keyword:string,date_from:string,date_to:string } */
private function get_verify_filters () : array {
$status = isset ( $_GET [ 'status' ]) ? sanitize_key (( string ) wp_unslash ( $_GET [ 'status' ])) : 'pending' ;
if ( ! in_array ( $status , [ 'pending' , 'verifi ed' , 'rejected' , 'cancelled' , '' ], true )) {
$status = 'pending' ;
}
return [
'status' => $status ,
'keyword' => isset ( $_GET [ 'keyword' ]) ? sanitize_text_field (( string ) wp_unslash ( $_GET [ 'keyword' ])) : '' ,
'date_from' => $this -> sanitize_verify_date ( $_GET [ 'date_from' ] ? ? '' ),
'date_to' => $this -> sanitize_verify_date ( $_GET [ 'date_to' ] ? ? '' ),
];
}
/** @return array{status:string,keyword:string} */
private function get_verify_filters () : array {
$status = isset ( $_GET [ 'status' ]) ? sanitize_key (( string ) wp_unslash ( $_GET [ 'status' ])) : 'pending' ;
if ( ! in_array ( $status , [ 'pending' , 'approv ed' , 'rejected' , '' ], true )) $status = 'pending' ;
return [
'status' => $status ,
'keyword' => isset ( $_GET [ 'keyword' ]) ? sanitize_text_field (( string ) wp_unslash ( $_GET [ 'keyword' ])) : '' ,
];
}
private function sanitize_verify_date ( $value ) : string {
$value = sanitize_text_field (( string ) wp_unslash ( $value ));
return preg_match ( '/^\d{4}-\d{2}-\d{2}$/' , $value ) ? $value : '' ;
}
/** @return array{pending:int,approved:int,rejected:int} */
private function get_verify_status_counts () : array {
return [
'pending' => $this -> count_verify_status ( 'pending' ),
'approved' => $this -> count_verify_status ( 'verified' ),
'rejected' => $this -> count_verify_status ( 'rejected' ),
];
}
/** @return array{pending:int,verified:int,rejected:int,cancelled:int,total :int} */
private function get_verify_status_counts ( ): array {
global $wpdb ;
$table = \AKSRT\Core\DBMigrator :: table ( 'identity_application' );
$counts = [ 'pending' => 0 , 'verified' => 0 , 'rejected' => 0 , 'c anc elled' => 0 , 'total' => 0 ];
$rows = $wpdb -> get_results ( " SELECT status, COUNT(*) total FROM { $table } GROUP BY status " , ARRAY_A ) ;
foreach (( array ) $rows as $row ) {
$status = ( string ) ( $row [ 'status' ] ? ? ' ') ;
$total = ( int ) ( $row [ 'total' ] ? ? 0 );
$public = \AKSRT\Identity\TransitionService :: public_status ( $status );
if ( in_array ( $status , [ 'manual_pending' , 'provider_faile d', 'provider_unsupported' , 'provider_expired' ], true ) ) {
$counts [ 'pending '] += $total ;
} elseif ( isset ( $counts [ $public ])) {
$counts [ $public ] += $total ;
}
$counts [ 'total '] += $total ;
}
return $counts ;
}
/** @return array{items:array<int,array<string,mixed>>,pages :int} */
private function query_verify_requests ( array $filters , int $page , int $per_page ) : array {
global $wpdb ;
$table = \AKSRT\Core\DBMigrator :: table ( 'identity_application' );
$where = [ " a.type = 'general' " , " a.ch ann el = 'manual' " ];
$params = [] ;
if ( $filters [ 'status' ] !== '' ) {
$where [] = 'a.status = %s ';
$params [] = $filters [ 'status' ] === 'pending' ? 'manual_pending' : ( $filters [ 'status' ] === 'approved' ? 'verified' : $filters [ 'status' ] );
}
if ( $filters [ 'keywor d'] !== '' ) {
$like = '%' . $wpdb -> esc_like ( $filters [ 'keyword ']) . '%' ;
$where [] = '(CAST(u.ID AS CHAR) LIKE %s OR u.display_name LIKE %s OR u.user_login LIKE %s OR u.user_email LIKE %s OR a.public_name LIKE %s OR a.provider_result_summary LIKE %s)' ;
array_push ( $params , $like , $like , $like , $like , $like , $like ) ;
}
$condition = implode ( ' AND ', $where ) ;
$base = " FROM { $table } a INNER JOIN { $wpdb -> users } u ON u.ID = a.user_id WHERE { $condition } " ;
$count_sql = " SELECT COUNT(*) { $base } " ;
$total = $params ? ( int ) $wpdb -> get_var ( $wpdb -> prepare ( $count_sql , $params )) : ( int ) $wpdb -> get_var ( $count_sql );
$limit = max ( 1 , min ( 100 , $per_page ));
$query_params = array_merge ( $params , [ $limit , ( max ( 1 , $page ) - 1 ) * $limit ]);
$sql = " SELECT a.id, a.application_uuid, a.user_id, a.type, a.channel, a.status, a.public_name, a.provider_result_summary AS description, a.manual_reason, a.review_note, a.evidence_ids, a.created_at, u.display_name, u.user_login, u.user_email { $base } ORDER BY a.created_at DESC, a.id DESC LIMIT %d OFFSET %d " ;
$rows = $wpdb -> get_results ( $wpdb -> prepare ( $sql , $query_params ), ARRAY_A );
return [ 'items' => is_array ( $rows ) ? $rows : [], 'pages' => max ( 1 , ( int ) ceil ( max ( 1 , $total ) / $limit ))];
}
/** @return array{items:array<int,array<string,mixed>>,pages:int,total:int} */
private function query_verify_requests ( array $filters , int $page_num , int $per_page ) : array {
global $wpdb ;
$table = \AKSRT\Core\DBMigrator :: table ( 'identity_application ') ;
$where = [ '1=1' ];
$params = [] ;
if ( $filters [ 'status' ] === 'pending' ) {
$where [] = " a.status IN ('manual_pending','provider_failed','provider_unsupported','provider_expired') " ;
} elseif ( $filters [ 'status '] !== '' ) {
$where [] = 'a.status = %s ';
$params [] = $filters [ 'status' ];
}
if ( $filters [ 'keyword' ] !== '' ) {
$like = '%' . $wpdb -> esc_like ( $filters [ 'keyword' ]) . '%' ;
$where [] = '(CAST(u.ID AS CHAR) LIKE %s OR u.display_name LIKE %s OR u.user_login LIKE %s OR u.user_email LIKE %s OR a.public_name LIKE %s OR a.application_uuid LIKE %s)' ;
array_push ( $params , $like , $like , $like , $like , $like , $like );
}
if ( $filters [ 'date_from' ] !== '' ) {
$where [] = 'a.created_at >= %s' ;
$params [] = $filters [ 'date_from' ] . ' 00:00:00' ;
}
if ( $filters [ 'date_to' ] !== '' ) {
$where [] = 'a.created_at <= %s' ;
$params [] = $filters [ 'date_to' ] . ' 23:59:59' ;
}
$where_sql = implode ( ' AND ' , $where );
$total_sql = " SELECT COUNT(*) FROM { $table } a INNER JOIN { $wpdb -> users } u ON u.ID = a.user_id WHERE { $where_sql } " ;
$total = $params ? ( int ) $wpdb -> get_var ( $wpdb -> prepare ( $total_sql , $params )) : ( int ) $wpdb -> get_var ( $total_sql );
$query_params = array_merge ( $params , [ $per_page , ( $page_num - 1 ) * $per_page ]);
$sql = " SELECT a.*, u.display_name, u.user_login, u.user_email FROM { $table } a INNER JOIN { $wpdb -> users } u ON u.ID = a.user_id WHERE { $where_sql } ORDER BY a.created_at DESC, a.id DESC LIMIT %d OFFSET %d " ;
$items = $wpdb -> get_results ( $wpdb -> prepare ( $sql , $query_params ), ARRAY_A );
return [ 'items' => is_array ( $items ) ? $items : [], 'pages' => max ( 1 , ( int ) ceil ( max ( 1 , $total ) / $per_page )), 'total' => $total ];
}
private function render_verify_filters ( array $filters ) : void {
echo '<form method="get" style="margin:12px 0;display:flex;gap:8px;align-items:end;flex-wrap:wrap;">' ;
echo '<input type="hidden" name="page" value="aksrt_user_auth" />' ;
echo '<label>' . esc_html__ ( '状态' , 'aksrt' ) . '<br><select name="status"> ';
foreach ([ 'pending' => __ ( '待审核' , 'aksrt' ), 'approved' => __ ( '已通过' , 'aksrt' ), 'rejected' => __ ( '已拒绝' , 'aksrt' ), '' => __ ( '全部' , 'aksrt' )] as $key => $label ) {
printf ( '<option value="%s"%s>%s</option>' , esc_attr ( $key ), selected ( $filters [ 'status' ], $key , false ), esc_html ( $label )) ;
}
echo '</select></label><label>' . esc_html__ ( '搜索' , 'aksrt' ) . '<br><input type="search" name="keyword" value="' . esc_attr ( $filters [ 'keyword' ]) . '" /></label>' ;
submit_button ( __ ( '筛选' , 'aksrt' ), 'secondary ', '' , false );
echo '</form> ';
}
private function render_verify_filters ( array $fil ter s ) : void {
echo '<form method="get" style="margin:12px 0;display:flex;gap:8px;align-items:end;flex-wrap:wrap;" >';
echo '<input type="hidden" name="page" value="aksrt_user_auth" / >';
echo '<label>' . esc_html__ ( '状态' , 'aksrt' ) . '<br><select name="status">' ;
foreach ([ 'pending' => __ ( '人工待审' , 'aksrt' ), 'verified' => __ ( '已通过' , 'aksrt' ), 'rejected' => __ ( '已驳回' , 'aksrt' ), 'cancelled' => __ ( '已取消' , 'aksrt' ), '' => __ ( '全部' , 'aksrt' )] as $key => $label ) {
printf ( '<option value="%s"%s>%s</option>' , esc_attr ( $key ), selected ( $filters [ 'status' ], $key , false ), esc_html ( $label ));
}
echo '</select></label>' ;
echo '<label>' . esc_html__ ( '搜索' , 'aksrt' ) . '<br><input type="search" name="keyword" value="' . esc_attr ( $filters [ 'keyword' ]) . '" /></label>' ;
echo '<label>' . esc_html__ ( '申请起始日期' , 'aksrt' ) . '<br><input type="date" name="date_from" value="' . esc_attr ( $filters [ 'date_from' ]) . '" /></label>' ;
echo '<label>' . esc_html__ ( '申请结束日期' , 'aksrt' ) . '<br><input type="date" name="date_to" value="' . esc_attr ( $filters [ 'date_to' ]) . '" /></label>' ;
submit_button ( __ ( '筛选' , 'aksrt' ), 'secondary' , '' , false );
echo '</form>' ;
}
private function render_verify_table ( array $i tem s ) : void {
echo '<table class="wp-list-table widefat fixed striped"><thead><tr><th>用户</th><th>状态</th><th>认证名称</th><th>认证简介 / 申请说明</th><th>证明材料</th><th>审核</th></tr></thead><tbody >';
if ( $items === []) echo '<tr><td colspan="6">' . esc_html__ ( '暂无认证申请' , 'aksrt' ) . '</td></tr >';
foreach ( $items as $row ) $this -> render_verify_row ( $row ) ;
echo '</tbody></table>' ;
}
private function render_verify_table ( array $items ) : void {
echo '<table class="wp-list-table widefat fixed striped"><thead><tr><th>用户</th><th>状态</th><th>申请资料</th><th>审核记录</th><th>操作</th></tr></thead><tbody> ';
if ( $item s === []) {
echo '<tr><td colspan="5">' . esc_html__ ( '暂无认证申请' , 'aksrt ') . '</td></tr>' ;
}
foreach ( $items as $row ) {
$this -> render_verify_row ( $row ) ;
}
echo '</tbody></table >';
}
private function render_verify_row ( array $row ) : void {
$user_id = ( int ) $row [ 'user_id '] ;
$statu s = ( string ) $row [ 'status' ];
$application = ( new \AKSRT\Identity\ApplicationRepository ()) -> find_by_id (( int ) $row [ 'id '] ) ? : $row ;
echo '<tr><td><strong><a href="' . esc_url ( get_edit_user_link ( $user_id )) . '">' . esc_html (( string ) $row [ 'display_name' ]) . '</a></strong><div>@' . esc_html (( string ) $row [ 'user_login' ]) . ' · UID ' . $user_id . '</div><div>' . esc_html (( string ) $row [ 'user_email' ]) . '</div></td>' ;
echo '<td>' . esc_html ( $this -> verify_status_label ( $status )) . '<div class="description">' . esc_html (( string ) $row [ 'created_at' ]) . '</div></td>' ;
echo '<td><strong>' . esc_html (( string ) $row [ 'public_name' ]) . '</strong></td>' ;
echo '<td>' . esc_html (( string ) $row [ 'description' ]) . '<p class="description">' . esc_html (( string ) $row [ 'manual_reason' ]) . '</p>' ;
if ( ! empty ( $row [ 'review_note' ])) echo '<p class="description">' . esc_html__ ( '处理留言:' , 'aksrt' ) . esc_html (( string ) $row [ 'review_note' ]) . '</p >';
echo '</td><td>' ;
foreach (( new \AKSRT\Identity\EvidenceService ()) -> items ( $application , true ) as $item ) {
echo '<a href="' . esc_url ( $item [ 'url' ]) . '" target="_blank" rel="noopener noreferrer"><img src="' . esc_url ( $item [ 'thumbnail_url' ]) . '" alt="" style="width:64px;height:64px;object-fit:cover;margin:4px;border-radius:4px;" /></a>' ;
}
echo '</td><td>' ;
$this -> render_verify_actions ( $row );
echo '</td></tr>' ;
}
private function render_verify_row ( array $row ) : void {
$user_id = ( int ) $row [ 'user_id '];
$status = ( string ) $row [ ' status' ] ;
$application = ( new \AKSRT\Identity\ApplicationRepository ()) -> find_by_id (( int ) $row [ 'id' ]) ? : $row ;
$history = ( new \AKSRT\Identity\EventRepository ()) -> for_application (( int ) $row [ 'id' ]);
echo '<tr><td><strong><a href="' . esc_url ( get_edit_user_link ( $user_id )) . '">' . esc_html (( string ) $row [ 'display_name' ]) . '</a></strong>' ;
echo '<div class="description">@' . esc_html (( string ) $row [ 'user_login' ]) . ' · UID ' . $user_id . '</div><div>' . esc_html (( string ) $row [ 'user_email' ]) . '</div></td>' ;
echo '<td>' . wp_kses_post ( $this -> verify_status_badge ( $status )) . '<div class="description">' . esc_html (( string ) $row [ 'provider' ]) . ' / ' . esc_html (( string ) $row [ 'channel' ]) . '</div></td>' ;
echo '<td><strong>' . esc_html (( string ) $row [ 'public_name' ]) . '</strong><div>' . esc_html (( string ) $row [ 'type' ]) . '</div>' ;
echo '<div class="description">UUID: ' . esc_html (( string ) $row [ 'application_uuid' ]) . '</div>' ;
if ( ! empty ( $row [ 'provider_result_code' ])) echo '<div>' . esc_html__ ( '云结果:' , 'aksrt' ) . esc_html (( string ) $row [ 'provider_result_code' ]) . '</div>' ;
foreach (( new \AKSRT\Identity\EvidenceService ()) -> items ( $application , true ) as $item ) {
echo '<a href="' . esc_url ( $item [ 'url' ]) . '" target="_blank" rel="noopener noreferrer"><img src="' . esc_url ( $item [ 'thumbnail_url' ]) . '" alt="" style="width:64px;height:64px;object-fit:cover;margin:8px 8px 0 0;border-radius:4px;" /></a>' ;
}
echo '</td><td>' ;
if ( ! empty ( $row [ 'review_note' ])) echo '<div>' . esc_html (( string ) $row [ 'review_note' ]) . '</div>' ;
if ( $history !== []) echo '<details><summary>' . esc_html ( sprintf ( __ ( '事件记录(%d) ' , 'aksrt' ), count ( $history ))) . '</summary><ol>' ;
foreach ( $history as $event ) echo '<li>' . esc_html (( string ) $event [ 'created_at' ] . ' · ' . ( string ) $event [ 'event_type' ] . ' · ' . ( string ) $event [ 'to_status' ]) . '</li>' ;
if ( $history !== []) echo '</ol></details>' ;
echo '</td><td>' ;
$this -> render_verify_actions ( $row );
echo '</td></tr>' ;
}
private function verify_status_label ( string $status ) : string {
$labels = [ 'manual_pending' => __ ( '待审核' , 'aksrt' ), 'verified' => __ ( '已通过' , 'aksrt' ), 'rejected' => __ ( '已拒绝' , 'aksrt ') ];
return ( string ) ( $labels [ $status ] ? ? $ status) ;
}
private function verify_status_badge ( string $status ) : string {
$labels = [ 'manual_pending' => __ ( '人工待审' , 'aksrt' ), 'verified' => __ ( '已通过' , 'aksrt' ), 'rejected' => __ ( '已驳回' , 'aksrt' ), 'cancelled' => __ ( '已取消' , 'aksrt' ), 'provider_pending' => __ ( '等待核身' , 'aksrt' ), 'provider_processing' => __ ( '云端处理中' , 'aksrt' ), 'provider_failed' => __ ( '云认证失败' , 'aksrt' ), 'provider_unsupported' => __ ( '云端不支持' , 'aksrt' ), 'provider_expired' => __ ( '会话已过期' , 'aksrt' ) ];
return '<span style="display:inline-block;padding:2px 8px;border:1px solid currentColor;border-radius:999px;">' . esc_html ( $labels [ $status ] ? ? $status ) . '</span>' ;
}
private function render_verify_actions ( array $row ) : void {
$status = ( string ) $row [ 'status' ];
if ( $status === 'manual_pending' ) {
foreach ([ 'verified' => __ ( '通过申请' , 'aksrt' ), 'rejected' => __ ( '拒绝申请' , 'aksrt' )] as $next => $label ) {
echo '<form method="post" action="' . esc_url ( admin_url ( 'admin-post.php' )) . '" style="display:grid;gap:5px;margin-bottom:10px;">' ;
echo '<input type="hidden" name="action" value="aksrt_users_review_verify"><input type="hidden" name="user_id" value="' . ( int ) $row [ 'user_id' ] . '"><input type="hidden" name="application_uuid" value="' . esc_attr (( string ) $row [ 'application_uuid' ]) . '"><input type="hidden" name="status" value="' . esc_attr ( $next ) . '">' ;
wp_nonce_field ( 'aksrt_users_review_verify_' . ( int ) $row [ 'user_id' ]);
echo '<input name="name" type="text" maxlength="64" value="' . esc_attr (( string ) $row [ 'public_name' ]) . '" placeholder="' . esc_attr__ ( '认证名称' , 'aksrt' ) . '" required>' ;
echo '<textarea name="description" rows="2" placeholder="' . esc_attr__ ( '认证简介' , 'aksrt' ) . '">' . esc_textarea (( string ) $row [ 'description' ]) . '</textarea>' ;
echo '<textarea name="note" rows="2" ' . ( $next === 'rejected' ? 'required' : '' ) . ' placeholder="' . esc_attr__ ( '处理留言;拒绝时请填写原因' , 'aksrt' ) . '"></textarea>' ;
echo '<button class="button ' . ( $next === 'verified' ? 'button-primary' : '' ) . '">' . esc_html ( $label ) . '</button></form>' ;
}
} else {
echo '<span class="description">' . esc_html__ ( '已处理' , 'aksrt' ) . '</span>' ;
}
echo '<form method="post" action="' . esc_url ( admin_url ( 'admin-post.php' )) . '" onsubmit="return confirm(\'' . esc_js ( __ ( '确定删除此认证申请记录及其证明材料?' , 'aksrt' )) . '\');">' ;
echo '<input type="hidden" name="action" value="aksrt_users_delete_verify"><input type="hidden" name="application_uuid" value="' . esc_attr (( string ) $row [ 'application_uuid' ]) . '">' ;
wp_nonce_field ( 'aksrt_users_delete_verify_' . ( string ) $row [ 'application_uuid' ]);
echo '<button class="button button-link-delete">' . esc_html__ ( '删除记录' , 'aksrt' ) . '</button></form>' ;
}
private function render_verify_actions ( array $row ) : void {
$status = ( string ) $row [ 'status '] ;
if ( in_array ( $status , [ 'manual_pending' , 'provider_failed' , 'provider_unsupported' , 'provider_expire d'], true )) {
foreach ([ 'verified' => __ ( '通过认证' , 'aksrt' ), 'rejected' => __ ( '驳回申请' , 'aksrt' )] as $next => $label ) {
echo '<form method="post" action="' . esc_url ( admin_url ( 'admin-post.php' )) . '" style="display:grid;gap:6px;margin-bottom:8px;"> ';
echo '<input type="hidden" name="action" value="aksrt_users_review_verify" /><input type="hidden" name="user_id" value="' . ( int ) $row [ 'user_id' ] . '" /><input type="hidden" name="application_uuid" value="' . esc_attr (( string ) $row [ 'application_uuid' ]) . '" /><input type="hidden" name="expected_status" value="' . esc_attr ( $status ) . '" /><input type="hidden" name="status" value="' . esc_attr ( $next ) . '" /> ';
wp_nonce_field ( 'aksrt_users_review_verify_' . ( int ) $row [ 'user_id' ] );
echo '<textarea name="note" rows="2" ' . ( $next === 'rejected' ? 'required' : '' ) . '></textarea><button class="button ' . ( $next === 'verified' ? 'button-primary' : '' ) . '">' . esc_html ( $label ) . '</button></form>' ;
}
} elseif ( $status === 'verified ') {
echo '<form method="post" action="' . esc_url ( admin_url ( 'admin-post.php' )) . '"><input type="hidden" name="action" value="aksrt_users_review_verify" /><input type="hidden" name="user_id" value="' . ( int ) $row [ 'user_id' ] . '" /><input type="hidden" name="application_uuid" value="' . esc_attr (( string ) $row [ 'application_uuid' ]) . '" /><input type="hidden" name="expected_status" value="verified" /><input type="hidden" name="status" value="cancelled" />' ;
wp_nonce_field ( 'aksrt_users_review_verify_' . ( int ) $row [ 'user_id' ] );
echo '<textarea name="note" required></textarea><button class="button button-link-delete">' . esc_html__ ( '取消认证' , 'aksrt' ) . '</button></form> ';
} else {
echo '<span class="description">' . esc_html__ ( '无需人工操作' , 'aksrt' ) . '</span>' ;
}
echo '<form method="post" action="' . esc_url ( admin_url ( 'admin-post.php' )) . '" style="margin-top:8px;" onsubmit="return confirm(\'' . esc_js ( __ ( '确定删除这条身份认证记录?关联事件和人工材料也会删除。' , 'aksrt' )) . '\');">' ;
echo '<input type="hidden" name="action" value="aksrt_users_delete_verify" /><input type="hidden" name="application_uuid" value="' . esc_attr (( string ) $row [ 'application_uuid' ]) . '" />' ;
wp_nonce_field ( 'aksrt_users_delete_verify_' . ( string ) $row [ 'application_uuid' ]);
echo '<button class="button button-link-delete">' . esc_html__ ( '删除记录' , 'aksrt' ) . '</button></form>' ;
}
public function handle_review_verify () : void {
if ( ! current_user_can ( 'aksrt_review_identity' ) && ! current_user_can ( self :: CAPABILITY )) wp_die ( esc_html__ ( '权限不足' , 'aksrt ')) ;
$user_id = absint ( $_POST [ 'user_i d'] ? ? 0 );
check_admin_referer ( 'aksrt_users_review_verify_' . $user_id );
$uuid = sanitize_text_field (( string ) wp_unslash ( $_POST [ 'application_uuid' ] ? ? ' ')) ;
$status = sanitize_key (( string ) wp_unslash ( $_POST [ 'status' ] ? ? ' ')) ;
$note = sanitize_textarea_field (( string ) wp_unslash ( $_POST [ 'note' ] ? ? '' ) );
$fields = [
'name' => sanitize_text_field (( string ) wp_unslash ( $_POST [ 'name' ] ? ? '' )),
'description' => sanitize_textarea_field (( string ) wp_unslash ( $_POST [ 'description '] ? ? '' )),
] ;
$result = \AKSRT\User\AuthApply :: review ( $user_id , $uuid , $status , $note , get_current_user_id (), $fields );
$extra = [ 'status' => 'pending '] ;
if ( is_wp_error ( $result )) $extra [ 'aksrt_verify_error' ] = $result -> get_error_message ();
$this -> redirect ( 'aksrt_user_auth' , is_wp_error ( $result ) ? 'verify_failed' : 'verify_updated' , $extra ) ;
}
public function handle_review_verify () : void {
if ( ! current_user_can ( 'aksrt_review_identity' ) && ! current_user_can ( self :: CAPABILITY )) {
wp_die ( esc_html__ ( '权限不足 ', 'aksrt ' ));
}
$user_id = ( int ) ( $_POST [ 'user_id' ] ? ? 0 );
check_admin_referer ( 'aksrt_users_review_verify_' . $user_ id);
$uuid = sanitize_text_field (( string ) wp_unslash ( $_POST [ 'application_uuid' ] ? ? '' ));
$expected = sanitize_key (( string ) wp_unslash ( $_POST [ 'expected_status' ] ? ? '' ));
$status = sanitize_key ( (string ) wp_unslash ( $_POST [ 'status' ] ? ? '' ));
$note = sanitize_textarea_field ( (string ) wp_unslash ( $_POST [ 'note '] ? ? '' ));
$application = ( new \AKSRT\Identity\ApplicationRepository ()) -> find_by_uuid ( $uuid );
$result = ( ! $application || ( int ) $application [ 'user_i d'] !== $user_id || ( string ) $application [ 'status' ] !== $expected )
? new \WP_Error ( 'aksrt_verify_conflict' , __ ( '认证状态已变化,请刷新后重试' , 'aksrt' ))
: \AKSRT\User\AuthApply :: review ( $user_id , $uuid , $status , $note , get_current_user_id (), [ ]);
$extra = [ 'status' => $status === 'cancelled' ? 'cancelled' : 'pending' ];
if ( is_wp_error ( $result )) $extra [ 'aksrt_verify_error' ] = $result -> get_error_message ( );
$this -> redirect ( 'aksrt_user_auth' , is_wp_error ( $result ) ? 'verify_failed' : 'verify_updated' , $extra );
}
public function handle_delete_verify () : void {
if ( ! current_user_can ( 'aksrt_review_identity' ) && ! current_user_can ( self :: CAPABILITY )) {
wp_die ( esc_html__ ( '权限不足' , 'aksrt' ));
}
$uuid = sanitize_text_field (( string ) wp_unslash ( $_POST [ 'application_uuid' ] ? ? '' ));
check_admin_referer ( 'aksrt_users_delete_verify_' . $uuid );
$repo = new \AKSRT\Identity\ApplicationRepository ();
$application = $repo -> find_by_uuid ( $uuid );
if ( ! $application ) {
$this -> redirect ( 'aksrt_user_auth' , 'verify_failed' , [ 'aksrt_verify_error' => __ ( '认证记录不存在' , 'aksrt' )]);
}
( new \AKSRT\Identity\EvidenceService ()) -> delete (( array ) ( $application [ 'evidence_ids' ] ? ? []));
( new \AKSRT\Identity\EventRepository ()) -> delete_for_application (( int ) $application [ 'id' ]);
$deleted = $repo -> delete (( int ) $application [ 'id' ]);
$this -> redirect ( 'aksrt_user_auth' , $deleted ? 'verify_deleted' : 'verify_failed' , $deleted ? [] : [ 'aksrt_verify_error' => __ ( '认证记录删除失败' , 'aksrt' )]);
}
private function get_verify_history ( int $user_id ) : array {
return \AKSRT\User\AuthApply :: get_review_history ( $user_id );
}
public function handle_delete_verify () : void {
if ( ! current_user_can ( 'aksrt_review_identity' ) && ! current_user_can ( self :: CAPABILITY )) wp_die ( esc_html__ ( '权限不足' , 'aksrt' ));
$uuid = sanitize_text_field (( string ) wp_unslash ( $_POST [ 'application_uuid '] ? ? '' ));
check_admin_referer ( 'aksrt_users_delete_verify_' . $uuid );
$repo = new \AKSRT\Identity\ApplicationRepository ( );
$application = $repo -> find_by_uuid ( $uu id);
if (
! $application
|| ( string ) ( $application [ 'type' ] ? ? '' ) !== 'general'
|| ( string ) ( $application [ 'channel '] ? ? '' ) !== 'manual'
) {
$this -> redirect ( 'aksrt_user_auth' , 'verify_faile d', [ 'aksrt_verify_error' => __ ( '认证记录不存在' , 'aksrt' )]);
}
$deleted = $repo -> delete (( int ) $application [ 'id' ]);
if ( ! $deleted ) {
$this -> redirect ( 'aksrt_user_auth' , 'verify_failed' , [ 'aksrt_verify_error' => __ ( '认证记录删除失败' , 'aksrt' )] );
}
( new \AKSRT\Identity\EvidenceService ()) -> delete (( array ) ( $application [ 'evidence_ids' ] ? ? []));
( new \AKSRT\Identity\EventRepository ()) -> delete_for_application (( int ) $application [ 'id' ]);
$this -> redirect ( 'aksrt_user_auth' , 'verify_deleted' );
}
}