Custom Field Suite をWordPressマルチサイトに対応させる

Custom Field Suite をWordPressマルチサイトに対応させる

※こちらの方法はプラグインソースを直接編集している無理やりな方法です。最初からマルチサイトに対応しているプラグインを選択できるならそちらのほうをおすすめします(ACFとか)。

Custon Field Suiteはもともとマルチサイト非対応で、最初に CFS()->get() が呼び出されたblog_idのプレフィクスのwp_postテーブルに対するselectクエリをキャッシュとして保持し、使い回すため、switch_to_blogするとその後のCFS()->get()で正しく結果を受け取れないという動作が発生してしまっていた。

includes/field_group.php 15行目あたりのキャッシュを返す処理を無効化すれば、switch_to_blogしても動作するようになったが、そうするとクエリ数が膨大になってしまう。

キャッシュ部分をよく見るとCustom Field Suiteのキャッシュはマルチサイトを想定していない配列に確保していたので、ここをマルチサイトに対応した構造にカスタマイズ。

includes/field_group.php
public function load_field_groups() {
    global $wpdb;
        
    /*
    if ( isset( $this->cache['field_groups'] ) ) {
        return $this->cache['field_groups'];
    }
    */
    if ( isset( $this->cache['field_groups'][$wpdb->posts] ) ) {
        return $this->cache['field_groups'][$wpdb->posts];
    }        
        ...中略...

    //$this->cache['field_groups'] = $output;
    $this->cache['field_groups'][$wpdb->posts] = $output;

    return $output;
}
includes/api.php
public function get_field( $field_name, $post_id, $options ) {
    global $wpdb,$post; //$wpdbを追加

    ...中略...

    // Trigger get_fields if not in cache
    //if ( ! isset( $this->cache[ $post_id ][ $options['format'] ][ $field_name ] ) ) {
    if ( ! isset( $this->cache[ $wpdb->posts ][ $post_id ][ $options['format'] ][ $field_name ] ) ) {
        $fields = $this->get_fields( $post_id, $options );
        return isset( $fields[ $field_name ] ) ? $fields[ $field_name ] : null;
    }
    return $this->cache[ $wpdb->posts ][ $post_id ][ $options['format'] ][ $field_name ];
}
public function get_fields( $post_id, $options ) {
    global $post, $wpdb;

    ...中略...

    // Return cached results
    //if ( isset( $this->cache[ $post_id ][ $options['format'] ] ) ) {
    if ( isset( $this->cache[ $wpdb->posts ][ $post_id ][ $options['format'] ] ) ) {
        return $this->cache[ $wpdb->posts ][ $post_id ][ $options['format'] ];
    }

    ...中略...

    //$this->cache[ $post_id ][ $options['format'] ] = $field_data;
    $this->cache[ $wpdb->posts ][ $post_id ][ $options['format'] ] = $field_data;
    return $field_data;
}

これで無駄なクエリ数も抑えられた…と思う。
直接ソースを弄っているので、当然アップデートすると元に戻ってしまうので注意。