web-dev-qa-db-fra.com

Le changement de requête var dans pre_get_posts n'est pas maintenu

Je crée un plugin qui ajoute un flux personnalisé. J'utilise un filtre pre_get_posts pour remplacer la variable posts_per_page par var (-1) (pour obtenir tous les éléments d'un type d'article personnalisé). Cependant, si je vide le $wp_query dans la fonction de rendu, posts_per_page reste la valeur par défaut. J'ai aussi essayé de changer posts_per_rss en -1, et je fais voir cela modifié dans la requête (même si, bien entendu, cela n'a aucun effet sur les publications résultantes). J'ai également essayé de changer mon thème pour un thème par défaut et de le tester, mais j'ai eu les mêmes résultats. Quelqu'un peut-il expliquer pourquoi je ne peux pas changer la variable posts_per_page query?

defined( 'ABSPATH' ) OR exit;

if(!class_exists('My_Custom_Feeds'))
{

    class My_Custom_Feeds { 

        protected $feed_slug = 'theslug';

        function __construct() {

            add_action( 'init', array($this, 'mcf_add_feed'));
            add_filter( 'pre_get_posts', array($this, 'mcf_pre_get_posts'));
        }

        function mcf_add_feed() {
            add_feed($this->feed_slug, array($this, 'mcf_render'));
        }

        function mcf_render(){

            //just output query to ensure it is as expected - but it's not
            global $wp_query;
            var_dump($wp_query);
            exit();
        }

        function mcf_pre_get_posts( $query ) {

            if ( $query->is_main_query() && $query->is_feed( $this->feed_slug ) ) {

                // modify query here to show all posts
                $query->set( 'posts_per_page', -1);
                $query->set( 'posts_per_rss', -1);
            }
        }
    }
}
if ( class_exists('My_Custom_Feeds') ){

    $my_custom_feeds = new My_Custom_Feeds();
}

Mise à jour un: réalisé que j'utilisais add_filter au lieu de add_action pour pre_get_posts. J'ai mis à jour cela, même si je vois toujours le même problème.

add_action( 'pre_get_posts', array($this, 'mcf_pre_get_posts'));

Mise à jour deux (et dernière): Pour la réponse de @ ialocin, j'ai réalisé que changer la requête posts_per_page était inutile car il était écrasé par l'option posts_per_rss dans un flux. requête (mon scénario). La solution consiste donc à utiliser un filtre pour modifier cette option. (-1 n'est pas une valeur posts_per_rss valide, donc l'arbitraire utilisée ci-dessous.)

function mcf_posts_per_rss( $option_name ) {
    global $wp_query;
    if ( $wp_query->is_main_query() && $wp_query->is_feed( $this->feed_slug ) ) {
            return 100; //arbitrarily large value that, while not ideal, works for me
    }
    return $option_name;
}

Ensuite, dans mon constructeur de classe de plug-in, j'ai ajouté le texte suivant (et supprimé l'action pre_get_posts):

add_filter( 'pre_option_posts_per_rss', array( $this, 'mcf_posts_per_rss') );
2
Nicole

Selon la discussion/aide dans ce fil, vous trouverez ci-dessous le code de base qui a fini par fonctionner pour mes besoins. La définition de la requête posts_per_page var était un exercice futile, car elle est écrasée par l'option posts_per_rss dans une requête de fil (mon scénario). posts_per_rss n'est pas une requête et doit être défini différemment. Le filtre pre_option_posts_per_rss a donc été ajouté. (-1 n'est pas une valeur posts_per_rss valide, donc l'arbitraire utilisée ci-dessous.)

defined( 'ABSPATH' ) OR exit;

if(!class_exists('My_Custom_Feeds'))
{

    class My_Custom_Feeds { 

        protected $feed_slug = 'theslug';

        function __construct() {

            add_filter( 'pre_option_posts_per_rss', array( $this, 'mcf_posts_per_rss') );
            add_action( 'init', array($this, 'mcf_add_feed'));
        }

        function mcf_add_feed() {

            add_feed($this->feed_slug, array($this, 'mcf_render'));
        }

        function mcf_render(){

            //put rendering stuff here
            exit();
        }

        function mcf_posts_per_rss( $option_name ) {

            global $wp_query;
            if ( $wp_query->is_main_query() && $wp_query->is_feed( $this->feed_slug ) ) {
                return 100; //arbitrarily large value that, while not ideal, worked for my purposes
            }
            return $option_name;
        }
    }
}
if ( class_exists('My_Custom_Feeds') ) {

    //instantiate class
    $my_custom_feeds = new My_Custom_Feeds();
}
1
Nicole

Le hook init s'exécute bien avant le pre_get_posts , de sorte que le vidage de la requête à ce stade-- sur init-- ne reflétera pas ce qui sera fait beaucoup plus tard. Je ne pense pas qu'il y ait quelque chose qui cloche dans votre code, vous comprenez mal la séquence d'actions. Ce que vous attendez ne se produit pas réellement.

2
s_ha_dum

posts_per_rss est pas un paramètre WP_Query . C'est le nom de la option qui est enregistrée dans la base de données. Il peut s'agir d'adresses via le pre_option_{$option_name} :

function wpse191824_posts_per_rss( $option_name ) {
    return 999;
}
add_filter( 'pre_option_posts_per_rss', 'wpse191824_posts_per_rss' );
1
Nicolai