web-dev-qa-db-fra.com

Rendre les futurs messages visibles au public, pas seulement dans WP_Query

Je sais que je peux afficher publiquement les publications futures dans une boucle en utilisant 'post_status' => 'future' dans WP_Query. Mais si vous cliquez sur le lien permanent d'un article futur, vous obtiendrez un 404 si vous n'êtes pas un utilisateur connecté.

Supposons que j'ai un post appelé Apocalypse dans le post_type 'event', prévu pour le 12-12-2099. Le permalien est mysite.com/event/apocalypse . Est-il possible de faire mysite.com/event/apocalypse et d’autres futures publications 'event' visitables maintenant par le public?

Idéalement, je serais en mesure de limiter la disponibilité des publications futures au type de publication "événement", mais je choisirais une solution qui rend toutes les publications futures disponibles, quel que soit le type de post_type.

3
supertrue

En bref, vous pouvez rendre les publications futures visibles en indiquant à Wordpress de les marquer en tant que 'published' au lieu de 'scheduled'. Pour ce faire, vous utilisez un hook future_post qui est appelé lorsqu'un post change de statut. Chaque type de message reçoit automatiquement son propre crochet futur; étant donné que le type de publication personnalisé que j'utilise est event, je peux utiliser le hook future_event. Voici le code:

function setup_future_hook() {
// Replace native future_post function with replacement
    remove_action('future_event','_future_post_hook');
    add_action('future_event','publish_future_post_now');
}

function publish_future_post_now($id) {
// Set new post's post_status to "publish" rather than "future."
    wp_publish_post($id);
}

add_action('init', 'setup_future_hook');

Cette solution est issue de cette question SE: Marquer le post post daté comme publié

Une mise en garde avec cette approche

La mise en garde que je vais ajouter est que cela rend plus difficile d'obtenir une boucle de messages à venir. Avant, je pouvais simplement utiliser 'post_status' => 'future'; mais maintenant, puisque nous avons défini post_status dans les publications futures sur published, cela ne fonctionne pas.

Pour contourner ce problème, vous pouvez utiliser un filtre posts_where sur votre boucle (par exemple, voir les exemples de plage de dates sur le codex ici: http://codex.wordpress.org/Class_Reference/WP_Query#Time_Parameters ), ou vous peut comparer la date actuelle à la date de publication, quelque chose comme ceci:

    // get the event time
    $event_time = get_the_time('U', $post->ID);

    // get the current time
    $server_time = date('U');

    // if the event time is older than (less than)
    // the current time, do something
    if ( $server_time > $event_time ){
       // do something
    }

Cependant, aucune de ces techniques n’est aussi simple que d’avoir un post_status séparé pour les publications futures. Peut-être qu'un post_status personnalisé serait une bonne solution ici.

3
supertrue

Je voudrais donner ma réponse tout ce temps plus tard. Dans le cas de rendre tous les posts "futurs" pour le type de posts "événements" visibles au public, j'ai trouvé cette solution:

add_filter('get_post_status', function($post_status, $post) {
    if ($post->post_type == 'events' && $post_status == 'future') {
        return "publish";
    }
    return $post_status;
}, 10, 2);
1
Samuel Reid

Pour moi l'extrait donné n'a pas fonctionné, il y a eu des erreurs dans le fichier post-edit.php, mais je suppose que $ postatt est maintenant nul dans la version 4.6.1.

Quoi qu'il en soit, c'est la solution finale qui a fonctionné pour moi comme un charme.

add_filter('the_posts', 'show_all_future_posts');

function show_all_future_posts($posts)
{
   global $wp_query, $wpdb;

   if(is_single() && $wp_query->post_count == 0)
   {
      $posts = $wpdb->get_results($wp_query->request);
   }

   return $posts;
}
0
knif3r