ユーザー登録フォームでかなりハマったので記録しておく。
まず、ユーザー登録フォームにオリジナルの項目を追加したいときは、チュートリアルを参考にして
1)$contactmethodに項目を追加してuser_contactmethodsフックにかける
2)その項目を保存する処理をprofile_updateフックにかける
という具合になる。
だが、実は1)をすると2)は必要なくなる。WPが勝手にPOSTデータからユーザー項目を追加してくれる。
ここで落とし穴なのが、よくあるチェックボックスで選択させる複数の値を取る項目だ。
これは適切に処理されずArrayという文字列で記録されてしまう。
なのでこのような項目のみ、2)で自前で適切に処理すればよい(といっても配列ごとadd_user_metaすれば良いのだ)
これは久々にハマった。正直3時間くらい費やしてやっと原因が掴めた。
なぜ今までハマらなかったのか?
実はTMLのフォーム機能はあまり使っておらず、自前でプロフィール編集や登録フォームを作り、リダイレクトやモデレーション、ログインの機能においてのみTMLを補助的に使っていた。
今回は徹底的にTMLに依存して実装しようとしたのだが、結局余計な労力をしょいこむことになってしまった。
プラグインの功罪だ。
その後、さらなる落とし穴にハマる・・・
上記の実装で概ね満足な動作をするので、一件落着、と思いきやそうではなかった。
実はこのフォームに「管理者モード」を追加しようとした。つまりuser_idのパラメータをURLに付け、管理者権限であればユーザーの情報を編集できるようにしたかった。
自前のコードであれば話は本当に簡単だ。セキュリティさえ注意すればものの数行でこのモードを追加できる。
しかし、プラグインに頼り切るとそんな小手先の工夫でも大いに難儀する事になる。
まずぶち当たったのが、自分のものでないプロフィールページを送信するとWPのコアから止められてしまう。「本当に実行しますか?」というやつだ。
このブロックはcheck_admin_referer()というのが担当していて、TMLのコアに入っているので手出しできない。
色々やってみたが諦めた。
そして、たったこれだけの機能追加のために大幅に考え方を変える必要が出てきた。
まず、フォームをほぼTMLから切り離し、独自の処理をする方向で。WPのコア機能とも決別。
フォーム内のhiddenにaction=”profile”とあるので、これを別のものにすると、TMLが反応しなくなる。
そして$contactmethodに自分の項目を追加するのをやめる。これで勝手にデータを処理されてしまうのを防ぐ。
そして自前の処理(POSTデータから取ってきてwp_update_user() , update_user_meta()など)を適当なフックで実装。
なんの事もない、完全なオリジナルフォームにするということで、こっちの方が遥かに話が速い。
結論(やっぱり)
TMLのフォーム機能は使わないのが吉、そしてWPのコア機能の影響も外す
それから、標準のパスワードジェネレータなどを使いたいときは
wp_enqueue_script( ‘user-profile’ );
これをロードしておく
WordPressでのサービスサイト構築やカスタマイズにおいて往々としてあるのが、プラグインを使いまわしてある程度の所までは非常に快適に作り上げる事ができるのだが、そこを一歩超えた要求が出てくると途端に地獄を見る、というパターンだ。
もちろん、ほとんどの場合プラグインだけでは満足することができない。
そうすると、今回のように自分で作れそうな部分は作った方がコントロールしやすいのだが、工数・予算は確実に増え、コストダウン・スピード開発のメリットが徐々になくなっていく。
自分自身がオーナーの場合様々な迂回策も取れるが、受託開発の場合そうはいかない。
その場合、今自分がやろうとしているように、色々なケースに対応できる開発パターンを確立しておいた方が良いと思っている。
最近思い始めたのが、ユーザー周りや各種管理画面の制作コストはPHPフレームワークを使った場合に比べ余計にコストがかかりそうということ。
コメント