Secura Vita

Category: Works > wordpress » wordpress:ユーザー名を変更する機能を作成しました
2015/09/13
Works

wordpress:ユーザー名を変更する機能を作成しました

wordpress:ユーザー名を変更する機能を作成しました

wordpressはユーザー名が変更できない

wordpressはユーザー名が変更できない仕様になっています。
ユーザーIDを保持したまま名前を変更するにはデータベースを直接さわる他ありません。

ユーザー名が変更できない

ユーザーを新規で作成して元のユーザーを消すという方法が一般的なんでしょうけど、ID変わったり同じメールアドレスが使えなかったりとなにかと不便です。

なので需要があるかどうかわかりませんが、ここを変更できるスクリプトを作ってみましたので参考までに御覧ください。

英語さっぱりなので日本語オンリーです。

一応プラグインとしても配布します。
DLはページ下部にあります。

スポンサーリンク

機能

機能はユーザー名を変更するだけの単純なものです。

「管理者」のみ有効の機能にしています。

wordpressのバージョンは4.3で確認しています。
それ以外のバージョンでも大丈夫だと思いますが、あまり古いとエラーがでるかもです。

下記ソースをfunctions.phpに貼り付けるも良し、プラグインをDLしてインストールするも良しです。

データベースに新たに何かを追加したりはしないのでいらなくなったら削除でOKです。

使い方

例として「hoshijiro」を「shizuka」に変更します。

change_ueser_name

機能が有効化されるとユーザーのメニューに「ユーザー名変更」という項目が現れます。

change_ueser_name

セレクトボックスで変更したいユーザーを選択して変更する名前を入力します。
ログイン中のユーザーは「ログイン中」と表示されます。

change_ueser_name

「確認」を押すとチェックします。エラーは下記の通り。

change_ueser_name
change_ueser_name
change_ueser_name
change_ueser_name
change_ueser_name

チェックが終わると確認画面になります。

change_ueser_name

問題がなければ「変更」を押して処理を完了させてください。

change_ueser_name

あとはユーザーページでユーザー名が変わっていることを確認し、表示名などの変更を行ってください。

change_ueser_name

wordpressにログイン中(自分)のユーザー名を変更した場合

ログイン中ユーザーのユーザー名を変更した場合、ログアウトされた状態になります。

他のページに移動した際にログイン画面が表示されますので変更した名前は必ず覚えておいてください。

authorページも変更される

wordpressはログイン名とauthorページのURLに使用されている名前が同一となっています。
*文字列によっては変換されます。例). → –

ユーザー名を変更するとこの部分も変更されますのでご注意ください。

http://example.com/author/hoshijiro/

http://example.com/author/shizuka/

スクリプト本体

//セッションスタート
add_action( 'init','sv_init_session_start' );
function sv_init_session_start() {
    if ( !session_id() ) {
        session_start();
    }
}

//管理画面メニューに追加
add_action( 'admin_menu', 'sv_change_user_name' );
function sv_change_user_name() {
    add_users_page( 'ユーザー名変更','ユーザー名変更','manage_options','sv-change-user-name.php','sv_change_user_name_func' );
}

//ページの処理
function sv_change_user_name_func() {
    
    //変数の定義
    $user_id = false;
    $new_name = false; 
    
    //セッション
    if(isset( $_SESSION['change_data']) ) {
        $data = $_SESSION['change_data'];
        unset( $_SESSION['change_data'] );
    }
        
    
    if(isset( $_REQUEST['confirm']) ) { //確認の処理
        
        //postされたユーザーIDと変更する名前を変数にセット
        $user_id = intval( $_POST['userid'] );
        $new_name = esc_html( $_POST['username'] );
        
        //どちらも入力されているか
        if( !empty( $new_name ) && !empty( $user_id ) ) {
            
            //名前のチェック
            $illegal_names = array( 'www' , 'web' , 'root' , 'admin' , 'main' , 'invite' , 'administrator' );
            $login_name = sanitize_user( $new_name , true );
            $nice_name = sanitize_title( $login_name , true );
            
            if( !validate_username( $new_name ) ) {
                $error[] = '名前に使用できない文字が含まれています。';
            } else if( in_array( $nice_name , $illegal_names ) ) {
                $error[] = 'この名前は使用できません。';
            } else {
                
                //ユーザIDからデータを取得
                $userdetail = new WP_User( $user_id );
                $userdata = $userdetail->data;

                //ユーザーの比較
                if( get_user_by( 'login' , $login_name ) ) {
                    $error[] = 'このユーザー名はすでに使用されています。';
                } else if( !$userdetail->ID ) {
                    $error[] = '存在しないユーザーです。';
                } else {
                    $_SESSION['change_data'] = array(
                                            'userid' => $userdata->ID,
                                            'login' => $login_name,
                                            'name' => $nice_name
                                            );
                    $detail = '<table class="wp-list-table widefat fixed striped users">';
                    $detail .= '<tr><th>ユーザーID</th><th>ユーザー名</th><th>メールアドレス</th><th>表示名</th></tr>';
                    $detail .= '<tr><td>'.esc_html( $userdata->ID ).'</td><td>'.esc_html( $userdata->user_login ).'</td><td>'.esc_html( $userdata->user_email ).'</td><td>'.esc_html( $userdata->display_name ).'</td></tr>';
                    $detail .= '</table>';
                    $detail .= '<p>このユーザーのユーザー名を[ <strong style="font-size:120%; color:#F00;">'.$login_name.'</strong>]に変更します。</p>';
                }
            }
        } else {
            
            //入力されていない場合
            if( !$user_id ){
                $error[] = '変更するユーザーが選択されてません。';
            }
            if( !$new_name ){
                $error[] = '変更するユーザー名が入力されていません。';
            }
        } 
        
    } else if( isset( $_REQUEST['change'] ) ) {
        
        //$dataから各変数に代入
        $userid = $data['userid'];
        $login = $data['login'];
        $name = $data['name'];
        
        //データベースの処理
        global $wpdb;
        $result = $wpdb->query( 
                    $wpdb->prepare("
                            UPDATE $wpdb->users
                            SET  user_login = %s , user_nicename = %s
                            WHERE ID = %d
                            ",
                            $login,$name,$userid 
                    )
                );
        
        //処理結果
        if( $result ) {
            $complete = '<div class="updated"><p>更新が完了しました。<br><a href="'.esc_url( admin_url( '/user-edit.php?user_id='.$userid ) ).'">ユーザーページ→</a>で確認してください。</p>';
            $complete .= '<p>ニックネーム・表示名は変更されていませんのでユーザーベージより変更してください。</p></div>';
        } else {
            $error[] = '更新に失敗しました。再度実行してください。';
        }

    }
    
    if(!isset( $detail ) ) {
        
        //ユーザーリストの処理
        $select = '<select name="userid"><option value="">選択してください</option>';

        //ログイン中のユーザー情報
        $current_user = wp_get_current_user()->data;

        //ユーザーリスト
        $args = array(
                    'orderby' => 'ID'
                );
        $users = get_users( $args );
        foreach( $users as $user ) {
            $userdata = $user->data;
            $selected = ( $user_id == $userdata->ID ) ? ' selected' : null;
            $loggedin = ( $current_user->ID == $userdata->ID ) ? ':ログイン中' : null;
            $select .= '<option value="'.esc_html( $userdata->ID ).'"'.$selected.'>'.esc_html( $userdata->user_login ).'('.esc_html( $userdata->display_name ).')'.$loggedin.'</option>';
        }

        $select .= '</select>';
        
    }
    
    //////////出力部分//////////
    echo '<div class="wrap"><h1>ユーザー名変更</h1>';
    
    //エラーの表示
    if( isset( $error ) ) {
        echo '<div class="error">';
        foreach( $error as $value ) {
            echo "<p>{$value}</p>";
        }
        echo '</div>';
    }

    //更新完了
    if( isset( $complete ) ) {
        echo $complete;
    }
    
    //フォーム
    echo '<form id="cange_username" method="post" action="'.esc_url( admin_url( '/users.php?page=sv-change-user-name.php' ) ).'">';
    if( isset( $detail ) ) {
        echo <<<EOF
<h3>このユーザーを変更します。</h3>
{$detail}
<h3>選択したユーザのユーザ名を変更する場合は「変更」、ユーザー選択に戻る場合は「戻る」をクリックしてください。</h3>
<input type="submit" name="change" class="button" value="変更">&nbsp;<a href="" class="button">戻る</a>
EOF;
    } else if( isset( $select ) ) {
        echo <<<EOF
<h3>変更するユーザーを選択してください。</h3>
{$select}
<h3>変更するユーザー名を入力してください。</h3>
<p><input type="text" name="username" class="regular-text" value="{$new_name}"></p>
<input type="submit" name="confirm" class="button" value="確認">
EOF;
    }
    echo '</form></div>';
}

2015/09/19[ver.1.0.1]コード修正

1-7行目

値の受け渡しをどうするか考えた結果、セッションを使用することにしました。
セッションを使用する場合ど頭に「session_start()」を書かないといけないんでフック「init」で書いてます。

9-13行目

管理画面のメニューに追加します。

権限は「管理者」にしています。

15行目移行

実行されるスクリプトです。

説明しようと思ったのですが…長い…

要約は以下のとおり

18-26行目

変数を定義しておきます。

セッションにデータがあれば変数に代入してアンセットしておきます。

29-109行目

ボタンを押した時の動作の分岐です。
「confirm」は確認、「change」は変更です。

confirm

  1. セッションを用意
  2. postされた値を取得してチェック
  3. 取得された値のチェックが済んだら名前のチェック
  4. 名前のチェックが済んだらIDからユーザーデータを取得
  5. ユーザーデータに問題がなければユーザーデータをセッションに記録・HTMLを作成して変数に代入

*チェックがNGならエラーを変数に代入

*名前のチェック・変換はwordpressの関数を使用しています。

  • sanitize_user()
    ユーザー名として使えない文字を除去
  • sanitize_title()
    スラッグ(URL)用として変換
  • validate_username()
    入力した名前に使用できない文字が入っていないか

change

  1. セッションからとりだしたデータを各変数に代入
  2. wpdbを使用してユーザーデータの書き換え
  3. 処理結果を変数に代入
111-133行目
  1. ログイン中のユーザー情報を取得
  2. 登録されているユーザーリストの取得
  3. ユーザーリストをselect-optionで展開
    その際に「$userIdと展開されたユーザーIDが同じならselected」、「ログイン中のユーザーなら(ログイン中)の表示」を行う
135行目移行

実際のHTML表示部分です。
上記で設定した変数に基づき表示します。

プラグイン

プラグインのソースは上記のものと全く同じです。プラグインファイルをfunctions.phpにインクルードさせても使えます。

プラグインは下記よりダウンロードしてください。

SV Change User Name [ver.1.0.1]
download

2015/09/19[ver.1.0.1]コード修正

注意!

※一度仮にユーザーを新規追加し、そのユーザーで試してください。
※自分以外のユーザー名を変更する場合は十分気を付けてください(変更前に連絡する等)。
※動作に問題はないと思いますが、使用は自己責任でお願いします。

その他

ソース・プラグインともに何かおかしな点がありましたらコメント・メールにてご連絡ください。

改変も自由に行ってください!報告の義務はないです。

ユーザー名のセキュリティについて書きました。

2015/09/15

wordpress:ユーザー名の付け方だけでログインのセキュリティをアップさせる(2015/09/15)

スポンサーリンク
おもしろかった・役に立った

Comment

  1. Kay より:

    素晴らしい!です。とととても助かりました。ありがとうございます。困っていたところだったので感動たっぷりです。

    1. あつお あつお より:

      返信遅くなりました。コメントありがとうございます!
      この機能は果たして需要があるのかと思っていたのでコメントいただけて嬉しいです。
      多分大丈夫だとは思うんですけど何かありましたらご連絡くださいませ。