2

I'm trying to display in a sidebar php widget, all posts with same post_title in a specific category. I find this code on internet but don't how to use it Thanks for your help.

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 : Here is actual code that i use.

<?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;
});
7
  • Do you need to test post names against a given value, or just get posts in general which have the same post name regardless Commented Mar 10, 2016 at 8:36
  • I juste need to get posts in general which have the same post_title in the category.
    – Guenfood
    Commented Mar 10, 2016 at 8:52
  • ok then the code you have is not useful for this, it will give you a single post according to a specified title, and does not account for category.
    – majick
    Commented Mar 10, 2016 at 8:55
  • another question is, are you just wanting matches to the current post's title and category?
    – majick
    Commented Mar 10, 2016 at 8:59
  • Sorry. I had put the wrong php code. Just update it. Yes, i want to mach to the current post's title, but not for the category. Category will be another of current post.
    – Guenfood
    Commented Mar 10, 2016 at 8:59

1 Answer 1

3

Lets use the build in features WordPress has to offer. It is almost always not adviced to use custom SQL whenever WordPress offers native functions to perform the specific duty.

To query our posts, we will make use of WP_Query. The only problem is, WP_Query does not support the feature where we look for posts with certain post titles. Luckily, we can filter the build SQL query just before it queries the db. For this, we will use the posts_where filter to introduce our own custom parameter, wpse_title_match (and no, this has nothing to do with wrestling).

We need to add the following in a plugin (recommended) or in your themes functions file

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

At this point, it will be better to build yourself a proper widget than to drop everything inside a php widget

Here is a modified widget plugin I recently done here

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

What I also like to do is to always completely remove a widget when it is is totally out of context to avoid the sidebar from rendering a blank space when no other widgets are displayed

We can try the same approach as I have described here. You can just add this at the bottom of the 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;
});

FEW NOTES

  • All the above code is untested and requires PHP 5.4+

  • You should adjust the WP_Query arguments in the widget to suit your needs. Everywhere where I added values in capital letters, you should fill in appropriate values

  • Both of the filter functions can be added in the same plugin, so the complete plugin will look like this

FINAL CODE

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

EDIT

You can extend the code inside the loop by looking at the source code of the content.php template parts in one of the bundled themes.

7
  • Thanks. I had install your code as a plugin, but can't activate it. Parse error: syntax error, unexpected ')' on line 31
    – Guenfood
    Commented Mar 10, 2016 at 12:10
  • Thank you for your feedback. I thought there might be bugs. As I said, it is untested (I'm coding from a mobile device). I'm leaving work soon within the next hour or so, will test my code when I get home and I'm back at my PC. In the mean time, I have corrected the syntax error. Please retest and let me know if there are any other issues. If there is, I will sort them out as soon as I get home. Good luck ;-) Commented Mar 10, 2016 at 12:31
  • I succeed to activate it. I had change 'post_typ', 'taxonomy' and 'terms' in the code, but when i add the widget in sidebar, nothing display.
    – Guenfood
    Commented Mar 10, 2016 at 12:47
  • Can you add your current code in your question so I can have a look at it. Commented Mar 10, 2016 at 13:17
  • I update the initial post with current code.
    – Guenfood
    Commented Mar 10, 2016 at 14:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.