web-dev-qa-db-ja.com

ajax経由で呼び出された場合はget_postsが空

Ajax関数の実行中に基本的なget_posts()クエリが空の配列を返す原因は何ですか?

フォームをロードするフロントエンドページがあります。ページに投稿タイトルが表示されたときに表示されるドロップダウンがあります。別の選択リストの値が変わると、選択リストの値を取り込む同じ関数がAjaxを介して呼び出されます。

関数がAjax経由で呼び出されると、結果は空の配列になります。ページが読み込まれると、選択リストは完全に入力されます。

error_log( var_export( $args, true ), 0 );を使用することで、関数に渡される引数がページロードとAjax呼び出しの両方で同じであることを確認し、error_log( var_export( $addons, true ), 0 );でページロードの結果とAjax呼び出しで空の配列を確認しました。これはまたAjaxを介した正しい関数の実行を確認します。

/**
 * Retrieve all addons.
 *
 * @since   1.4
 * @param   arr         $args   Array of arguments. See @get_posts.
 * @return  arr|bool    Addons.
 */
function mh_get_addons( $args = array() )   {

    $defaults = array(
        'posts_per_page' => -1,
        'orderby'        => 'post_title',
        'order'          => 'DESC',
        'post_type'      => 'mh-addon',
        'post_status'    => 'publish'
    );

    $args = wp_parse_args( $args, $defaults );
    error_log( var_export( $args, true ), 0 );
    $addons = get_posts( $args );
    error_log( var_export( $addons, true ), 0 );
    return apply_filters( 'mh_get_addons', $addons );

} // mh_get_addons

これがAjax関数です。ご覧のとおり、テスト中に引数を渡していないので、最初のページの読み込み時と同じ結果になるはずです。

function mh_update_form_addon_options() {

    $addons = mh_get_addons();

    if ( ! empty( $addons ) )   {
        $result['type']   = 'success';
        $result['addons'] = $addons;
    } else  {
        $result['type']   = 'success';
        $result['addons'] = 'No addons';
    }

    echo json_encode( $result );

    die();
} // mh_update_form_addon_options
add_action( 'wp_ajax_mh_update_form_addon_options', 'mh_update_form_addon_options' );
add_action( 'wp_ajax_nopriv_mh_update_form_addon_options', 'mh_update_form_addon_options' );

`

_ update _ ユーザーがログインしているときに、この関数はAjax呼び出しを介して結果を返すようになりました。ただし、ログインしていない場合は結果が返されません。奇妙なことに、ページ読み込み/ withoutajaxなしで開始されたmh_get_addons()関数の最初の呼び出しは、ユーザーがログインしているかどうかにかかわらず結果を返すということです。

2
Mike

WP AJAX AP​​Iを使用する代わりに、RESTエンドポイントを登録してみましたか。これは少なくともWP 4.5を想定しています。

add_action( 'rest_api_init', function () {
    register_rest_route( 'mike/v1', '/addons/', array(
        'methods' => 'GET',
        'callback' => 'mh_update_form_addon_options',
    ) );
} );


function mh_update_form_addon_options( WP_REST_Request $data ) {

    $defaults = array(
        'posts_per_page'   => 200,
        'orderby'          => 'post_title',
        'order'            => 'DESC',
        'post_type'        => 'mh-addon',
        'post_status'      => 'publish',
        'suppress_filters' => false
    );

    $addons = get_posts( $args );
    $result = array();    
    if ( empty( $addons ) )   {
        return new WP_Error("No addons");
    }

    return $addons;
}

私はまた、機能を単純化し、フィルタを削除することによっていくつかの不確実性を排除しました。また、suppress_filtersをfalseに設定してget_posts呼び出しを高速化し、結果がキャッシュされるようにしました。あなたがどうにかしてこの要求がいつも失敗する100万アドオンで終わったならば、私は最大数も加えました、それであなたがそれが決して届かないことを知っているばかげた数であっても

RESTエンドポイントに注意してください。送信しているものを返します。エコーはしません。問題にはWP_Errorを使用します。引数を記述するためにregister_rest_route呼び出しを調整することができます。方法についてはWP AP​​Iドキュメントを参照してください。

これに必要なのはWPコアのみで、WP AP​​Iプラグインは不要

1
Tom J Nowell

AJAXからデータを取得するには、echoまたはprintを呼び出す必要があります。 WordPressでは、呼び出しに対する応答としてデータを送信するために wp_send_json() functionを使用する必要があります。

function mh_get_addons( $args = array() )   {

    $defaults = array(
        'posts_per_page' => -1,
        'orderby'        => 'post_title',
        'order'          => 'DESC',
        'post_type'      => 'mh-addon',
        'post_status'    => 'publish'
    );

    $args = wp_parse_args( $args, $defaults );
    $addons = get_posts( $args );
    wp_send_json( apply_filters( 'mh_get_addons', $addons ) );

} // mh_get_addons
1

mh_get_addons()関数の先頭にあるグローバル$postオブジェクトを呼んでみましたか?

function mh_get_addons( $args = array() )   {

  global $post;

  $defaults = array(
      'posts_per_page' => -1,
      'orderby'        => 'post_title',
      'order'          => 'DESC',
      'post_type'      => 'mh-addon',
      'post_status'    => 'publish'
  );

  $args = wp_parse_args( $args, $defaults );
  error_log( var_export( $args, true ), 0 );
  $addons = get_posts( $args );
  error_log( var_export( $addons, true ), 0 );
  return apply_filters( 'mh_get_addons', $addons );

  }

私はまだワードプレスのエキスパートではありませんが、wp-ajaxを介して呼び出される関数内でget_posts($args)を呼び出す方法で同様の問題を抱えていたので、それが解決されました。そうでなければget_posts()は投稿情報を取得することができませんでした。

0
Christian