web-dev-qa-db-fra.com

get_posts vide lorsqu'il est appelé via Ajax

Qu'est-ce qui ferait qu'une requête get_posts() de base retourne un tableau vide pendant une fonction Ajax?

J'ai une page d'accueil qui charge un formulaire. Une liste déroulante est renseignée lorsque la page est chargée avec certains titres de publication. La même fonction qui remplit les valeurs de la liste de sélection est appelée via Ajax lorsque la valeur d’une autre liste de sélection change.

Lorsque la fonction est appelée via Ajax, le résultat est un tableau vide. Lorsque la page est chargée, la liste de sélection est entièrement remplie.

En utilisanterror_log( var_export( $args, true ), 0 );, j'ai confirmé que les arguments transmis à la fonction sont les mêmes pour le chargement de page et l'appel Ajax. Avec error_log( var_export( $addons, true ), 0 );, j'ai confirmé les résultats au chargement de page et un tableau vide à l'appel Ajax. Cela confirme également l'exécution de la fonction correcte via 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

Voici la fonction Ajax. Comme vous pouvez le constater, je ne passe aucun argument ici lors des tests; je m'attendrais donc à voir les mêmes résultats que lors du chargement initial de la page.

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' );

`

UPDATELa fonction renvoie maintenant les résultats via l'appel Ajax lorsqu'un utilisateur est connecté. Toutefois, s'il n'est pas connecté, aucun résultat. Chose étrange, l'appel initial à la fonction mh_get_addons() qui est lancé au chargement de la page without ajax renvoie les résultats, qu'un utilisateur soit connecté ou non ...

2
Mike

Au lieu d'utiliser l'API WP AJAX, avez-vous essayé d'enregistrer un noeud final REST? Cela suppose au moins 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;
}

J'ai également simplifié la fonction et éliminé certaines incertitudes en supprimant les filtres. J'ai également accéléré l'appel get_posts en définissant suppress_filters sur false afin qu'il mette en cache le résultat. J'ai également ajouté un nombre maximal. Si vous obtenez en quelque sorte un million d'addons, cette demande échouera toujours. Vous devez donc toujours définir une limite supérieure, même si c'est un nombre ridicule, vous savez qu'elle ne sera jamais atteinte.

Gardez à l'esprit dans un noeud final REST, nous retournons ce que nous envoyons, nous ne le renvoyons pas à l'écho et utilisons WP_Error pour les problèmes. Vous pouvez ajuster l'appel register_rest_route pour mentionner des arguments, voir la documentation de l'API WP pour savoir comment.

Seul WP Core est requis pour cela, aucun plug-in WP API n'est nécessaire.

1
Tom J Nowell

Pour obtenir des données de AJAX appel, vous devez echo ou print le. Dans WordPress, vous devez utiliser wp_send_json() function pour envoyer des données en réponse à un appel.

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
Krzysztof Grabania

Avez-vous essayé d'appeler l'objet global $post en haut de votre fonction mh_get_addons()?

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 );

  }

Je ne suis pas encore tout à fait expert en wordpress, mais je rencontrais un problème similaire lors de l'utilisation de get_posts($args) dans une fonction appelée via wp-ajax, comme vous l'appelez, et cela a résolu le problème pour moi. Sinon, get_posts() n'a pas pu récupérer les informations de publication, d'où le tableau vide que vous voyez.

0
Christian