WordPressでユーザー情報に項目を追加するぞい 〜ver.新規登録時〜

この記事はだいぶ前に書かれたものなので情報が古いかもしれません
プロフィール

この記事を三行にまとめると

新規にユーザーを追加するときに項目を追加してみましょう
「user_new_form」というアクションフックを追加します
スタイリッシュかと言われると自分でもよく分からない
以前、Wordpressのユーザー情報に任意の項目を追加する方法を紹介しました。

WordPressでユーザー情報に項目を追加するぞい

あの時はすでに作成されているユーザーに情報を追加するやり方でしたが、今回は新規にユーザーを追加するときに項目を追加してみましょう。



連絡先情報に追加

前回はfunctions.phpに以下のコードを記述することで、ユーザー編集時の「連絡先情報」のところに任意のテキストボックスを追加することができました。

function set_user_meta($profile) {
  $profile['pr'] = 'PR';
  return $profile;
}
add_filter('user_contactmethods', 'set_user_meta', 10, 1);

詳細な説明は今回は省略しますが、これでPRという項目を追加することができました。

新規追加時にもPRのテキストボックスを表示するには、ここにさらに「user_new_form」というアクションフックを追加します。

function set_user_meta($profile) {
  $profile['pr'] = 'PR';
  return $profile;
}
add_filter('user_contactmethods', 'set_user_meta', 10, 1);

//以下のコードを追加
function set_user_new_profile() {
  echo '<table class="form-table"><tr class="form-field"><th><label for="pr">PR</label></th><td><input type="text" name="pr" /></td></tr></table>';
}
add_action('user_new_form', 'set_user_new_profile');

これで新規追加時にPRという項目のテキストボックスが追加されます。

PRのテキストボックスを追加しました

各項目はテーブルレイアウトになってるんですが、この方法で項目を追加した場合、そのテーブルの中に項目が追加されるわけではないようなので、他の項目と見た目をそろえるなら自分でtableタグから記述する必要があります。



あなたについてに追加

テキストボックスで項目を追加する場合は上記のやり方で簡単に実装できるのですが、それ以外の、例えばテキストエリアなどで項目を追加する場合はちょいめんどうです。

というのも、連絡先情報はテキストボックスしか追加できないので、例えばPRの項目をテキストエリアで追加したい場合は、編集画面の「あなたについて」の方に追加する必要があります。

これも前回のおさらいになりますが、あなたについての方にテキストエリアを表示するコードは以下の通り。

//編集画面に項目を追加
function set_user_profile($bool) {
  global $profileuser;

  //PRのテキストエリアを追加
  echo '<tr><th><label for="pr">PR</label></th><td><textarea name="pr" rows="5" cols="30">'.esc_html($profileuser->pr).'</textarea></td></tr>';
    
  return $bool;
}
add_action('show_password_fields', 'set_user_profile');

//データの更新処理
function update_user_profile($user_id, $old_user_data) {
  if(isset($_POST['pr'])) {
    update_user_meta($user_id, 'pr', $_POST['pr'], $old_user_data->pr);
  }
}
add_action('profile_update', 'update_user_profile', 10, 2);

「show_password_fields」と「profile_update」という二つのアクションフックが必要になります。

じゃあこれと「user_new_form」のアクションフックを組み合わせればええやんって思うかもしれませんが、事はそう簡単にいかない。

//編集画面に項目を追加
function set_user_profile($bool) {
  global $profileuser;

  //PRのテキストエリアを追加(編集時)
  echo '<tr><th><label for="pr">PR</label></th><td><textarea name="pr" rows="5" cols="30">'.esc_html($profileuser->pr).'</textarea></td></tr>';
    
  return $bool;
}
add_action('show_password_fields', 'set_user_profile');

//データの更新処理
function update_user_profile($user_id, $old_user_data) {
  if(isset($_POST['pr'])) {
    update_user_meta($user_id, 'pr', $_POST['pr'], $old_user_data->pr);
  }
}
add_action('profile_update', 'update_user_profile');

//新規追加時に項目を追加
function set_user_new_profile() {
  //PRのテキストエリアを追加(新規登録時)
  echo '<table class="form-table"><tr class="form-field"><th><label for="pr">PR</label></th><td><textarea name="pr" rows="5" cols="30"></textarea></td></tr></table>';
}
add_action('user_new_form', 'set_user_new_profile');

実際にやってみれば分かるんですが、確かにこう書けば新規追加時にPRのテキストエリアが表示されます。でもこれだとPRのデータがデータベースに登録されません。

どういう仕様なのかはよく分かりませんが、新規追加時に追加項目もデータベースに登録するためには「user_contactmethods」のフィルターフックが必須のようです。

なので、こう書けば新規追加時の登録はできるようになる。

//編集画面に項目を追加
function set_user_profile($bool) {
  global $profileuser;

  //PRのテキストエリアを追加(編集時)
  echo '<tr><th><label for="pr">PR</label></th><td><textarea name="pr" rows="5" cols="30">'.esc_html($profileuser->pr).'</textarea></td></tr>';
    
  return $bool;
}
add_action('show_password_fields', 'set_user_profile');

//データの更新処理
function update_user_profile($user_id, $old_user_data) {
  if(isset($_POST['pr'])) {
    update_user_meta($user_id, 'pr', $_POST['pr'], $old_user_data->pr);
  }
}
add_action('profile_update', 'update_user_profile');

//フィルターフック
function set_user_meta($profile) {
  $profile['pr'] = 'PR';
  return $profile;
}
add_filter('user_contactmethods', 'set_user_meta', 10, 1);

//新規追加時に項目を追加
function set_user_new_profile() {
  //PRのテキストエリアを追加(新規登録時)
  echo '<table class="form-table"><tr class="form-field"><th><label for="pr">PR</label></th><td><textarea name="pr" rows="5" cols="30"></textarea></td></tr></table>';
}
add_action('user_new_form', 'set_user_new_profile');

でもこれだと、今度は編集時にちょいおかしなことになる。簡単に言うと連絡先情報とあなたについての両方にPRの項目が表示されてしまいます。

別にエラーにはならないけど……

こんな感じ。別にこのままでもエラーにはならないし内容の編集もできますが、まあスタイリッシュではないですよね。



こんなやり方はどうだろう?

じゃあどうしましょうかって話なのだけど、とりあえず考えつくものとしては、user_contactmethodsのフィルターフックを新規追加時のみ有効になるようにするとかですかね。

function set_user_meta($profile) {
  $profile['pr'] = 'PR';
  return $profile;
}

//新規追加時のみuser_contactmethodsを動かす
function only_user_new() {
  add_filter('user_contactmethods', 'set_user_meta', 10, 1);
}
add_action('load-user-new.php', 'only_user_new');

Wordpressのアクションフックは、「load-ページ名」と書くことで、そのページを開いた時だけ動くフックを作成できます。ユーザーの新規追加は「user-new.php」というページで開かれるので、「load-user-new.php」のアクションフックでuser_contactmethodsのフィルターをフックするようにしておけばデータの登録も正常に行えるし、編集時の連絡先情報の方にPRが表示されることもなくなります。

このやり方がスタイリッシュかと言われると自分でもよく分からないけど、動きとしては問題ないので今回はこれでオッケーってことにしときましょう。プラグイン化すればもうちょいキレイな書き方ができるかもですが。






テキストエリアやプルダウンを追加する場合は若干手間はかかりますが、これで新規追加時にも好きな項目を追加することができます。一回ユーザーを登録してからじゃないと追加項目が登録できないのはめんどいって場合はこっちの方法も試してみてくださいな。
 もしかしたら何か関連しているかも? 
 質問や感想などお気軽にコメントしてください