web-dev-qa-db-fra.com

Afficher tous les articles avec le même titre

J'essaie d'afficher dans un widget php de la barre latérale, tous les messages avec le même post_title dans une catégorie spécifique. Je trouve ce code sur Internet mais je ne sais pas comment l'utiliser. Merci pour votre aide.

function get_multiple_posts_by_title($title) {
    global $wpdb;
    $posts_ids = array();

    $posts = $wpdb->get_results( $wpdb->prepare( “SELECT ID FROM $wpdb->posts WHERE post_title = %s AND     post_type=’post_type’”, $title), OBJECT );
    foreach ($posts as $post) {
         $posts_ids[] = $post->ID;
    }

    return $posts_ids;
}

Edit: Voici le code actuel que j'utilise.

<?php
/*
Plugin Name: WPSE Get Duplicate Post Titles
Plugin URI:  http://wordpress.stackexchange.com/q/220279/31545
Description: Displays posts with the same title in the sidear
Version:     1.0.0
Author:      Pieter Goosen
Author URI:  http://wordpress.stackexchange.com/users/31545/pieter-goosen
License:     GPL2
License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

add_filter( 'posts_where', function ( $where, $q ) use ( &$wpdb )
{
    // Get the value from our new wpse_title_match query var
    $title_match = $q->get( 'wpse_title_match' );

    // Make sure we have a value, if not, bail
    if ( !$title_match )
        return $where;

    /**
     * Lets alter the SQL WHERE clause
     *
     * Note, this will be an exact 1 to 1 match, adjust as necessary
     */
    $where .= $wpdb->prepare(
        " AND {$wpdb->posts}.post_title = %s ",
        $title_match
    );

    return $where;
}, 10, 2 );

class WPSE_Get_Duplicate_Post_titles extends WP_Widget 
{

    public function __construct() 
    {
        parent::__construct(
            'widget_get_duplicate_post_titles', 
            _x( 'Post Title duplicates', 'Post Title duplicates' ), 
            [ 'description' => __( 'Displays posts which share the same post title.' ) ] 
        );
        $this->alt_option_name = 'widget_get_duplicate_post_titles';

        add_action( 'save_post',    [$this, 'flush_widget_cache'] );
        add_action( 'deleted_post', [$this, 'flush_widget_cache'] );
        add_action( 'switch_theme', [$this, 'flush_widget_cache'] );
    }

    public function widget( $args, $instance ) 
    {
        $cache = [];
        if ( ! $this->is_preview() ) {
            $cache = wp_cache_get( 'widget_bpfi', 'widget' );
        }

        if ( ! is_array( $cache ) ) {
            $cache = [];
        }

        if ( ! isset( $args['widget_id'] ) ) {
            $args['widget_id'] = $this->id;
        }

        if ( isset( $cache[ $args['widget_id'] ] ) ) {
            echo $cache[ $args['widget_id'] ];
            return;
        }

        ob_start();

        $title          = ( ! empty( $instance['title'] ) ) ? $instance['title'] : __( 'Post Title Duplicates' );
        /** This filter is documented in wp-includes/default-widgets.php */
        $title          = apply_filters( 'widget_title', $title, $instance, $this->id_base );

        // ADD YOUR CUSTOM PHP CODE HERE FOR EXECUTION TO DISPLAY ON FRONT END
        // First make sure this a single post page
        if ( is_single() ) { // We are on a single page
            // Get the current post object
            $post_object = $GLOBALS['wp_the_query']->get_queried_object();

            // Run our query to get the posts with duplicate titles
            $args = [
                'posts_per_page'   => -1, // Get all posts
                'post_type'        => 'post',
                'wpse_title_match' => $post_object->post_title,
                'post__not_in'     => [$post_object->ID], // Exclude current post
                'tax_query'        => [
                    [
                        'taxonomy' => 'category',
                        'terms'    => 'chroniques'
                    ]
                ],
                // Any other arguments
            ];
            $loop = new WP_Query( $args );

            // Run the loop
            if ( $loop->have_posts() ) {
                while ( $loop->have_posts ) {
                    $loop->the_post();

                    // Display your posts
                    the_title() . "\n";

                }
                wp_reset_postdata();
            }
        }

        echo $args['after_widget']; 

        if ( ! $this->is_preview() ) {
            $cache[ $args['widget_id'] ] = ob_get_flush();
            wp_cache_set( 'widget_bpfi', $cache, 'widget' );
        } else {
            ob_end_flush();
        }
    }

    public function update( $new_instance, $old_instance ) 
    {
        $instance                   = $old_instance;
        $instance['title']          = strip_tags( $new_instance['title'] );
        $this->flush_widget_cache();

        $alloptions = wp_cache_get( 'alloptions', 'options' );
        if ( isset($alloptions['widget_get_duplicate_post_titles']) )
            delete_option('widget_get_duplicate_post_titles');

        return $instance;
    }

    public function flush_widget_cache() 
    {
        wp_cache_delete('widget_bpfi', 'widget');
    }

    public function form( $instance ) 
    {

        $title      = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
        ?>

        <p>
            <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" />
        </p>

    <?php
    }

}

add_action( 'widgets_init', function () 
{
    register_widget( 'WPSE_Get_Duplicate_Post_titles' );
});

add_filter( 'sidebars_widgets', function ( $sidebars_widgets )
{
    // Return our filter when we are on admin screen
    if ( is_admin() )
        return $sidebars_widgets;

    // Make sure we are not on the blog page, if we are, bail
    if ( is_single() )
        return $sidebars_widgets;

    /**
     * Widget we need to target. This should be the name/id we used to register it
     *
     * EXAMPLE
     *   parent::__construct(
            'widget_get_duplicate_post_titles', 
            _x( 'Blog Page Featured Image', 'Blog page featured image' ), 
            [ 'description' => __( 'Displays the featured image for the pge set as blog page.' ) ] 
        );
     *
     */
    $custom_widget  = 'widget_get_duplicate_post_titles';

    // See if our custom widget exists is any sidebar, if so, get the array index
    foreach ( $sidebars_widgets as $sidebars_key=>$sidebars_widget ) {
        // Skip the wp_inactive_widgets set, we do not need them
        if ( $sidebars_key == 'wp_inactive_widgets' )
        continue;

        // Only continue our operation if $sidebars_widget are not an empty array
        if ( $sidebars_widget ) {
            foreach ( $sidebars_widget as $k=>$v ) {

                /**
                 * Look for our custom widget, if found, unset it from the $sidebars_widgets array
                 * @see stripos()
                 */
                if ( stripos( $v, $custom_widget ) !== false ) 
                    unset( $sidebars_widgets[$sidebars_key][$k] );
            } // endforeach $sidebars_widget
        } // endif $sidebars_widget
    } // endforeach $sidebars_widgets

    return $sidebars_widgets;
});
3
Guenfood

Permet d’utiliser les fonctionnalités intégrées que WordPress a à offrir. Il n'est presque toujours pas conseillé d'utiliser du SQL personnalisé chaque fois que WordPress propose des fonctions natives pour effectuer le travail spécifique.

Pour interroger nos publications, nous utiliserons WP_Query. Le seul problème est que WP_Query ne prend pas en charge la fonctionnalité permettant de rechercher des publications avec certains titres. Heureusement, nous pouvons filtrer la requête SQL de construction juste avant qu'elle interroge la base de données. Pour cela, nous allons utiliser le filtre posts_where pour introduire notre propre paramètre personnalisé, wpse_title_match ( et non, cela n’a rien à voir avec la lutte ).

Nous devons ajouter les éléments suivants dans un plugin ( recommandé ) ou dans votre fichier de fonctions de thèmes.

add_filter( 'posts_where', function ( $where, $q ) use ( &$wpdb )
{
    // Get the value from our new wpse_title_match query var
    $title_match = $q->get( 'wpse_title_match' );

    // Make sure we have a value, if not, bail
    if ( !$title_match )
        return $where;

    /**
     * Lets alter the SQL WHERE clause
     *
     * Note, this will be an exact 1 to 1 match, adjust as necessary
     */
    $where .= $wpdb->prepare(
        " AND {$wpdb->posts}.post_title = %s ",
        $title_match 
    );

    return $where;
}, 10, 2 );

À ce stade, il sera préférable de vous construire un widget approprié que de tout laisser tomber dans un widget php

Voici un plugin de widget modifié que j'ai récemment fait ici

class WPSE_Get_Duplicate_Post_titles extends WP_Widget 
{

    public function __construct() 
    {
        parent::__construct(
            'widget_get_duplicate_post_titles', 
            _x( 'Post Title duplicates', 'Post Title duplicates' ), 
            [ 'description' => __( 'Displays posts which share the same post title.' ) ] 
        );
        $this->alt_option_name = 'widget_get_duplicate_post_titles';

        add_action( 'save_post',    [$this, 'flush_widget_cache'] );
        add_action( 'deleted_post', [$this, 'flush_widget_cache'] );
        add_action( 'switch_theme', [$this, 'flush_widget_cache'] );
    }

    public function widget( $args, $instance ) 
    {
        $cache = [];
        if ( ! $this->is_preview() ) {
            $cache = wp_cache_get( 'widget_bpfi', 'widget' );
        }

        if ( ! is_array( $cache ) ) {
            $cache = [];
        }

        if ( ! isset( $args['widget_id'] ) ) {
            $args['widget_id'] = $this->id;
        }

        if ( isset( $cache[ $args['widget_id'] ] ) ) {
            echo $cache[ $args['widget_id'] ];
            return;
        }

        ob_start();

        $title          = ( ! empty( $instance['title'] ) ) ? $instance['title'] : __( 'Post Title Duplicates' );
        /** This filter is documented in wp-includes/default-widgets.php */
        $title          = apply_filters( 'widget_title', $title, $instance, $this->id_base );

        // ADD YOUR CUSTOM PHP CODE HERE FOR EXECUTION TO DISPLAY ON FRONT END
        // First make sure this a single post page
        if ( is_single() ) { // We are on a single page
            // Get the current post object
            $post_object = $GLOBALS['wp_the_query']->get_queried_object();

            // Run our query to get the posts with duplicate titles
            $args = [
                'posts_per_page'   => -1, // Get all posts
                'post_type'        => 'post',
                'wpse_title_match' => $post_object->post_title,
                'post__not_in'     => [$post_object->ID], // Exclude current post
                'tax_query'        => [
                    [
                        'taxonomy' => 'category',
                        'field'    => 'slug',
                        'terms'    => 'chroniques'
                    ]
                ],
                // Any other arguments
            ];
            $loop = new WP_Query( $args );

            // Run the loop
            if ( $loop->have_posts() ) {
                while ( $loop->have_posts() ) {
                    $loop->the_post();

                    // Display your posts
                    the_title() . "\n";

                }
                wp_reset_postdata();
            }
        }

        echo $args['after_widget']; 

        if ( ! $this->is_preview() ) {
            $cache[ $args['widget_id'] ] = ob_get_flush();
            wp_cache_set( 'widget_bpfi', $cache, 'widget' );
        } else {
            ob_end_flush();
        }
    }

    public function update( $new_instance, $old_instance ) 
    {
        $instance                   = $old_instance;
        $instance['title']          = strip_tags( $new_instance['title'] );
        $this->flush_widget_cache();

        $alloptions = wp_cache_get( 'alloptions', 'options' );
        if ( isset($alloptions['widget_get_duplicate_post_titles']) )
            delete_option('widget_get_duplicate_post_titles');

        return $instance;
    }

    public function flush_widget_cache() 
    {
        wp_cache_delete('widget_bpfi', 'widget');
    }

    public function form( $instance ) 
    {

        $title      = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
        ?>

        <p>
            <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" />
        </p>

    <?php
    }

}

add_action( 'widgets_init', function () 
{
    register_widget( 'WPSE_Get_Duplicate_Post_titles' );
});

Ce que j'aime aussi faire est de toujours supprimer complètement un widget lorsqu'il est totalement hors contexte pour éviter que la barre latérale ne restitue un espace vide lorsqu'aucun autre widget n'est affiché.

Nous pouvons essayer la même approche que celle que j'ai décrite ici . Vous pouvez simplement ajouter ceci au bas du plugin

add_filter( 'sidebars_widgets', function ( $sidebars_widgets )
{
    // Return our filter when we are on admin screen
    if ( is_admin() )
        return $sidebars_widgets;

    // Make sure we are not on the blog page, if we are, bail
    if ( is_single() )
        return $sidebars_widgets;

    /**
     * Widget we need to target. This should be the name/id we used to register it
     *
     * EXAMPLE
     *   parent::__construct(
            'widget_get_duplicate_post_titles', 
            _x( 'Blog Page Featured Image', 'Blog page featured image' ), 
            [ 'description' => __( 'Displays the featured image for the page set as blog page.' ) ] 
        );
     *
     */
    $custom_widget  = 'widget_get_duplicate_post_titles';

    // See if our custom widget exists is any sidebar, if so, get the array index
    foreach ( $sidebars_widgets as $sidebars_key=>$sidebars_widget ) {
        // Skip the wp_inactive_widgets set, we do not need them
        if ( $sidebars_key == 'wp_inactive_widgets' )
        continue;

        // Only continue our operation if $sidebars_widget are not an empty array
        if ( $sidebars_widget ) {
            foreach ( $sidebars_widget as $k=>$v ) {

                /**
                 * Look for our custom widget, if found, unset it from the $sidebars_widgets array
                 * @see stripos()
                 */
                if ( stripos( $v, $custom_widget ) !== false ) 
                    unset( $sidebars_widgets[$sidebars_key][$k] );
            } // endforeach $sidebars_widget
        } // endif $sidebars_widget
    } // endforeach $sidebars_widgets

    return $sidebars_widgets;
});

Quelques notes

  • Tout le code ci-dessus est non testé et nécessite PHP 5.4+

  • Vous devez ajuster les arguments WP_Query du widget en fonction de vos besoins. Partout où j'ai ajouté des valeurs en majuscules, vous devez renseigner les valeurs appropriées

  • Les deux fonctions de filtre peuvent être ajoutées dans le même plugin, ainsi le plugin complet ressemblera à ceci

CODE FINAL

<?php
/*
Plugin Name: WPSE Get Duplicate Post Titles
Plugin URI:  https://wordpress.stackexchange.com/q/220279/31545
Description: Displays posts with the same title in the sidear
Version:     1.0.0
Author:      Pieter Goosen
Author URI:  https://wordpress.stackexchange.com/users/31545/pieter-goosen
License:     GPL2
License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

add_filter( 'posts_where', function ( $where, $q ) use ( &$wpdb )
{
    // Get the value from our new wpse_title_match query var
    $title_match = $q->get( 'wpse_title_match' );

    // Make sure we have a value, if not, bail
    if ( !$title_match )
        return $where;

    /**
     * Lets alter the SQL WHERE clause
     *
     * Note, this will be an exact 1 to 1 match, adjust as necessary
     */
    $where .= $wpdb->prepare(
        " AND {$wpdb->posts}.post_title = %s ",
        $title_match
    );

    return $where;
}, 10, 2 );

class WPSE_Get_Duplicate_Post_titles extends WP_Widget 
{

    public function __construct() 
    {
        parent::__construct(
            'widget_get_duplicate_post_titles', 
            _x( 'Post Title duplicates', 'Post Title duplicates' ), 
            [ 'description' => __( 'Displays posts which share the same post title.' ) ] 
        );
        $this->alt_option_name = 'widget_get_duplicate_post_titles';

        add_action( 'save_post',    [$this, 'flush_widget_cache'] );
        add_action( 'deleted_post', [$this, 'flush_widget_cache'] );
        add_action( 'switch_theme', [$this, 'flush_widget_cache'] );
    }

    public function widget( $args, $instance ) 
    {
        $cache = [];
        if ( ! $this->is_preview() ) {
            $cache = wp_cache_get( 'widget_bpfi', 'widget' );
        }

        if ( ! is_array( $cache ) ) {
            $cache = [];
        }

        if ( ! isset( $args['widget_id'] ) ) {
            $args['widget_id'] = $this->id;
        }

        if ( isset( $cache[ $args['widget_id'] ] ) ) {
            echo $cache[ $args['widget_id'] ];
            return;
        }

        ob_start();

        $title          = ( ! empty( $instance['title'] ) ) ? $instance['title'] : __( 'Post Title Duplicates' );
        /** This filter is documented in wp-includes/default-widgets.php */
        $title          = apply_filters( 'widget_title', $title, $instance, $this->id_base );

        // ADD YOUR CUSTOM PHP CODE HERE FOR EXECUTION TO DISPLAY ON FRONT END
        // First make sure this a single post page
        if ( is_single() ) { // We are on a single page
            // Get the current post object
            $post_object = $GLOBALS['wp_the_query']->get_queried_object();

            // Run our query to get the posts with duplicate titles
            $args = [
                'posts_per_page'   => -1, // Get all posts
                'post_type'        => 'post',
                'wpse_title_match' => $post_object->post_title,
                'post__not_in'     => [$post_object->ID], // Exclude current post
                'tax_query'        => [
                    [
                        'taxonomy' => 'category',
                        'field'    => 'slug',
                        'terms'    => 'chroniques'
                    ]
                ],
                // Any other arguments
            ];
            $loop = new WP_Query( $args );

            // Run the loop
            if ( $loop->have_posts() ) {
                while ( $loop->have_posts() ) {
                    $loop->the_post();

                    // Display your posts
                    the_title() . "\n";

                }
                wp_reset_postdata();
            }
        }

        echo $args['after_widget']; 

        if ( ! $this->is_preview() ) {
            $cache[ $args['widget_id'] ] = ob_get_flush();
            wp_cache_set( 'widget_bpfi', $cache, 'widget' );
        } else {
            ob_end_flush();
        }
    }

    public function update( $new_instance, $old_instance ) 
    {
        $instance                   = $old_instance;
        $instance['title']          = strip_tags( $new_instance['title'] );
        $this->flush_widget_cache();

        $alloptions = wp_cache_get( 'alloptions', 'options' );
        if ( isset($alloptions['widget_get_duplicate_post_titles']) )
            delete_option('widget_get_duplicate_post_titles');

        return $instance;
    }

    public function flush_widget_cache() 
    {
        wp_cache_delete('widget_bpfi', 'widget');
    }

    public function form( $instance ) 
    {

        $title      = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
        ?>

        <p>
            <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" />
        </p>

    <?php
    }

}

add_action( 'widgets_init', function () 
{
    register_widget( 'WPSE_Get_Duplicate_Post_titles' );
});

add_filter( 'sidebars_widgets', function ( $sidebars_widgets )
{
    // Return our filter when we are on admin screen
    if ( is_admin() )
        return $sidebars_widgets;

    // Make sure we are not on the blog page, if we are, bail
    if ( is_single() )
        return $sidebars_widgets;

    /**
     * Widget we need to target. This should be the name/id we used to register it
     *
     * EXAMPLE
     *   parent::__construct(
            'widget_get_duplicate_post_titles', 
            _x( 'Blog Page Featured Image', 'Blog page featured image' ), 
            [ 'description' => __( 'Displays the featured image for the pge set as blog page.' ) ] 
        );
     *
     */
    $custom_widget  = 'widget_get_duplicate_post_titles';

    // See if our custom widget exists is any sidebar, if so, get the array index
    foreach ( $sidebars_widgets as $sidebars_key=>$sidebars_widget ) {
        // Skip the wp_inactive_widgets set, we do not need them
        if ( $sidebars_key == 'wp_inactive_widgets' )
        continue;

        // Only continue our operation if $sidebars_widget are not an empty array
        if ( $sidebars_widget ) {
            foreach ( $sidebars_widget as $k=>$v ) {

                /**
                 * Look for our custom widget, if found, unset it from the $sidebars_widgets array
                 * @see stripos()
                 */
                if ( stripos( $v, $custom_widget ) !== false ) 
                    unset( $sidebars_widgets[$sidebars_key][$k] );
            } // endforeach $sidebars_widget
        } // endif $sidebars_widget
    } // endforeach $sidebars_widgets

    return $sidebars_widgets;
});

MODIFIER

Vous pouvez étendre le code dans la boucle en consultant le code source des parties du modèle content.php dans l'un des thèmes fournis.

3
Pieter Goosen