私が達成しようとしているのは以下の通りです:私たちのウェブサイトのすべてのユーザーに対して、私は一度サービスへのAPIリクエスト(他のデータベースと対話するlocal REST API)をしてユーザーがログアウトして再度ログインするまでWP_User(sub)クラス(この値はアプリケーション内の各ページで1回使用されるため、ページロードごとに1回取得する必要があるため、パフォーマンス上非常に望ましくありません)。
私がこれまでに発見した懸念の分離に関して最もエレガントな方法は、O'Reillyの本WordPressによるWebアプリケーションの構築&Brian Messenlehner&にあるように、WP_Userクラスを拡張(サブクラス化)することによって行われます。ジェイソンコールマン。
サンプルコードはここで見られます: 作者のGitHubのこのファイルを見てください 。
ただし、問題は、このStudent(WP_Userを拡張したサブクラス)をコード内で使用できないことです。現在のユーザーのStudentインスタンスを1つ取得するには、次の方法でインスタンス化する必要があります。
$student = new Student($current_user->ID);
ページ上でこれを行うと、インスタンスは常に再作成され(したがって、タイトルのライフサイクルを参照してください)、$student->assignments
への呼び出しは新しいページに移動した後にWP_User
サブクラス自体の内部にキャッシュされることはないページをリロードしているので、すべてのページがロードされるたびに、トラフィックが多い本番環境ではおそらく機能しないAPIとデータベースを使用しています。
WordPress自体の$current_user
グローバル変数(これはWP_User
インスタンスです)はログイン直後に作成されたように見え、私の理解する限りではアプリケーション全体を通して利用可能です。私が本当に欲しいのは、アプリケーション全体で同じ可用性が、WP_User
クラスの代わりに私のサブクラス(Student)にあることですが、もっと重要なのは、ログインユーザーごとにAPIヒットが一度だけ行われるようにすることです。ちょうど$current_user->user_login
にあるWP_User
のように)。
私はuser_meta
にWP_User
を追加することも検討しました、そしてそれに関連してこの質問をチェックアウトしました、それは部分的に役に立つように思われました:
しかし、これはWordPressオブジェクトキャッシュであるwp_cache_get
を通して明確に取得されます。
ページの作成時にStudentサブクラスの値を複数回使用することはありませんが、値はアプリケーションのすべてのページで1回使用されるため、ページが読み込まれるたびに1回取得する必要があります。
私はここで間違った方向に考えているだけなのでしょうか、それともWordPress内でこれがどのように可能になるでしょうか。私は本当にトラフィックの多い本番環境で実行する必要がありますここで良い長期的なソリューションが必要です。ご協力ありがとうございます
よくわかっていれば、Wordpressのインストールでログインからユーザーのログアウトまで、別のRESTサービスから取得した値をキャッシュする必要があるので、このwp_login
にフックして値とキャッシュを取得します。 トランジェントAPI 、 オプションAPI または 永続キャッシング プラグイン。
add_action('wp_login', 'my_get_and_cache_rest_value');
function my_get_and_cache_rest_value ($user_login, $user) {
// do your rest call
// cache it using Transient API, Options API or a persistent caching plugin
}
それからWP_User
オブジェクトを拡張して、必要なデータをキャッシュから取得するためのマジックコールを設定できます。
class MY_User extends WP_User {
// no constructor so WP_User's constructor is used
// method to get cached data
function getMyCachedData() {
// get data via my cache solution
if ( ! isset( $this->data->myData ) )
$this->data->myData = my_get_cached_data( $this->ID );
return $this->data->myData;
}
// magic method to detect $user->my_data
function __get( $key ) {
if ( $key == 'my_data' )
{
return $this->getMyCachedData();
}
else
{
// fallback to default WP_User magic method
return parent::__get( $key );
}
}
}
これが誰かに役立つことを願い、@ Danielに応援します。
以下は質問全体に答えるものではありませんが、それはこの部分に対処します:
@ダニエル:
$current_user
グローバル変数...は、私の理解する限り、アプリケーション全体を通して利用可能です。私が本当に欲しいのは、アプリケーション全体で同じ可用性があることです。
私も同様のニーズを抱えていましたが、これが私が思いついたことです。
set_current_user
フック( wp_set_current_user() 関数内)があり、アクションが起動されるまでに$current_user
グローバル変数はWP_Userのインスタンスに設定されるため、このフックを使用して「操作を実行する」ことができます。それ。
wp_get_current_user() を呼び出すと、基本的にグローバルな$current_user
の値が返されますが、特定の条件下ではwp_set_current_user()
を呼び出すことになり、カスタムアクションが起動する可能性があります。
だから、カスタムプラグイン(これはtheme function.phpファイルではうまくいくとは思わない)で、アクションを定義することができます。
add_action( 'set_current_user', 'extend_current_user', PHP_INT_MAX );
そして、あなたの行動はグローバルな$current_user
を上書きすることができます:
public function extend_current_user()
{
global $current_user;
if( $current_user->ID == 0 )
return;
$current_user = new Student( $current_user->ID );
}
その後、あなたのStudentクラスは Transient API を使用してRESTfulデータをキャッシュし、そのデータを公開するメソッドまたはプロパティを提供できます。そして、グローバルな$current_user
はStudentのインスタンスとして残るので、それらが必要なときはいつでもそれらのメソッド/プロパティは常にwp_get_current_user()
から利用可能です。
もちろん、こうすることで、 防御的なプログラマー は、wp_get_current_user()
への呼び出しがメソッドを呼び出す前にStudentのインスタンスを返すことを確認したいでしょう。
あなたの質問は少し広いですが、主な問題はあなたが外部のAPIにアプローチしたいすべての新入生のために一度だけであるようです。
これを行うには、 wp_insert_user
にフックする必要があります。これは、新しいユーザーを登録するコア機能です。定義上、この関数は新しいユーザーごとに一度だけ呼び出されます。この関数の最後にフック user_register
があります。これはAPIにアプローチできる場所です。
add_action ('user_register','wpse185731_approach_api');
function wpse185731_approach_api ($user_id) {
$userdata = get_userdata( $user_id );
if ( some condition based on $userdata) {
... approach API with $userdata, then store with:
add_user_meta( $user_id, $meta_key, $meta_value, $unique );
}
}
あなたはおそらくあなたのテーマではなく、プラグインでこれをしたいと思うでしょう。