How to get posts by content?

You have to extend the db query to search in the post_content column. There is a filter: 'posts_where' you can use.

I would write a simple wrapper for get_posts() to extends its arguments an run the filter once. Example:

class T5_Posts_By_Content
{
    protected static $content="";

    protected static $like    = TRUE;

    /**
     * Mapper for get_posts() with extra arguments 'content' and 'like'
     *
     * 'content' must be a string with optional '%' for free values.
     * 'like' must be TRUE or FALSE.
     *
     * @param array $args See get_posts.
     * @return array
     */
    public static function get( $args )
    {
        if ( isset ( $args['content'] ) )
        {
            // This is TRUE by default for get_posts().
            // We need FALSE to let the WHERE filter do its work.
            $args['suppress_filters'] = FALSE;
            self::$content            = $args['content'];
            add_filter( 'posts_where', array ( __CLASS__, 'where_filter' ) );
        }

        isset ( $args['like'] ) and self::$like = (bool) $like;

        return get_posts( $args );
    }

    /**
     * Changes the WHERE clause.
     *
     * @param string $where
     * @return string
     */
    public static function where_filter( $where )
    {
        // Make sure we run this just once.
        remove_filter( 'posts_where', array ( __CLASS__, 'where_filter' ) );

        global $wpdb;
        $like  = self::$like ? 'LIKE' : 'NOT LIKE';
        // Escape the searched text.
        $extra = $wpdb->prepare( '%s', self::$content );

        // Reset vars for the next use.
        self::$content="";
        self::$like    = TRUE;

        return "$where AND post_content $like $extra";
    }
}

To find the last five posts containing the string resized write:

$args = array(
    'content' => '%resized%'
);
$posts = T5_Posts_By_Content::get( $args );

To get the last five posts not containing resized:

$args = array(
    'content' => '%resized%',
    'like'    => FALSE
);
$posts = T5_Posts_By_Content::get( $args );

Leave a Comment