GithubHelp home page GithubHelp logo

birgire / wp-combine-queries Goto Github PK

View Code? Open in Web Editor NEW
69.0 5.0 11.0 150 KB

WordPress: Combine multiple WP_Query() queries into a single one, through the custom 'combined_query' attribute of the WP_Query class.

License: MIT License

PHP 85.89% Shell 14.11%
wp-query wordpress combine-queries wordpress-plugin

wp-combine-queries's People

Contributors

birgire avatar darcmattr avatar pdufour avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

wp-combine-queries's Issues

Recently combined queries started including ACF field groups

I've been combining 3 sub queries on a site with no problems until recently. Sometimes one or two of the sub queries are empty arrays, but that hasn't posted a problem until recently. In the last week or so we've had issues with the queries returning ACF field group posts. I still have no idea why, as I'm specifying a particular post type in the sub queries. To fix this I needed to not include the empty arrays in the 'combined_query' argument array.

Previously my code looked like this:

$query = new WP_Query( array(
	'combined_query' => array(
		'args' 				=> array( $sub_query1, $sub_query2, $sub_query3 ),
		'orderby' 			=> 'none',
		'posts_per_page' 	=> $per_page,
		'paged' 			=> $cur_page,
	),
) );

And now it looks like this:

$combined_queries = [];
if ( ! empty( $sub_query1 ) ) {
	array_push( $combined_queries, $sub_query1 );
}
if ( ! empty( $sub_query2 ) ) {
	array_push( $combined_queries, $sub_query2 );
}
if ( ! empty( $sub_query3 ) ) {
	array_push( $combined_queries, $sub_query3 );
}

$query = new WP_Query( array(
	'combined_query' => array(
		'args' 				=> $combined_queries,
		'orderby' 			=> 'none',
		'posts_per_page' 	=> $per_page,
		'paged' 			=> $cur_page,
	),
) );

Hopefully this helps anyone facing the same issue.

Extra Blank Page

Hey there using the latest classes on ver 4 of WP and I'm getting a extra empty page,
My two args look like this:

                                           $meta_query =  array('relation' => 'AND',
                                        array(
                                            'key' => 'property_status',
                                            'value' => 'Sold',
                                            'compare' => '!='
                                        )

                            );

        $args1 = array(
                        'post_type' => 'property', 

                        'orderby'         => 'date',
                        'meta_key'      => 'property_status',
                        'order' => 'DESC',

                        'post_status'      => 'publish',
                        'meta_query' => $meta_query,
                    );  

        //$listings = new WP_Query( $args );

        $meta_query_sold =  array('relation' => 'AND',
                                        array(
                                            'key' => 'property_status',
                                            'value' => 'Sold',
                                            'compare' => '='
                                        )

                            );

        $args2 = array(
                        'post_type'         => 'property', 

                        'orderby'           => 'date',
                        'meta_key'          => 'property_status',
                        'order'             => 'DESC',

                        'post_status'       => 'publish',
                        'meta_query'        => $meta_query_sold,
                    );  

        $args = array( 
                                 'posts_per_page' => $posts_per_page,
                                 'paged'          =>    $paged,
                                'sublimit'       => 1000,
                                  'args'           => array( $args1, $args2 ),
                    );
        $wp_query = new  WP_Combine_Queries( $args );

Not working with custom post type

I've tried to used this a custom post type and it doesn't seem to work. It still shows the normal posts. Not sure what's wrong.

my code looks like this:

$args1 = [
    'post_type' => 'products',
    'post_status' => 'publish',
    'meta_query'     => [
        [
            'key'      => 'product_id',
            'compare'  => 'EXISTS',
        ],
    ],    
    'orderby' => 'date',
    'order' => 'DESC',
];

//-----------------
// Sub query #2:
//-----------------
$args2 = [
    'post_type' => 'products',
    'post_status' => 'publish',
    'meta_query'     => [
        [
            'key'      => 'product_id',
            'compare'  => 'NOT EXISTS',
        ],
    ],    
    'orderby' => 'date',
    'order' => 'DESC',
];

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
//---------------------------
// Combined queries #1 + #2:
//---------------------------
$args3 = [
    'posts_per_page' => 12,
    'pagination' => true,
       'combined_query' => [        
        'args'   => [ $args1, $args2 ],
        'union'  => 'UNION',
    ],
   'paged'=>$paged,  
];


//---------
// Output:
//---------
$q = new WP_Query( $args3 );

Subsequent queries after a query with combine_queries are broken

The following lines broke subsequent queries which are not use combined_query (after a query with combined_query was used) because the filter are now always applied. The filter posts_request and posts_orderby should only be added by pre_get_posts,

add_filter( 'posts_request', [ $this, 'posts_request' ], PHP_INT_MAX, 2 );
add_filter( 'posts_orderby', [ $this, 'posts_orderby' ], PHP_INT_MAX );

Archive View on Page 2

Upon setting this up when I hit page/2 for any loop I get a 404 page.

Does this work when using multipage archives and am I missing something or does this feature not exist?

Suggestion: Preserving unique sorting in subqueries

First โ€“ thanks for this plugin! One of my uses is on an event listing page to first show upcoming events in ASC order and then show past events in DESC order. But I was having a hell of a time getting them to actually sort correctly! The dates within each query were always jumbled.

I took some guidance from this StackOverflow posts: https://stackoverflow.com/questions/30192885/how-to-sort-data-in-mysql-union-subquery

Essentially, it claimed that the outer query would negate any sorting of inner queries. It was useful to assign an ID to the records in each subquery, to preserve that order, and then reiterate the sorting with the outer query. This is messy, but it worked:

// Needed a global variable here to increment.
$cq_sortfield_count = 0;

// Modify sub fields:
add_filter( 'cq_sub_fields', $callback = function( $fields ) {
	global $cq_sortfield_count;
	$cq_sortfield_count++;
	// Create a new field with an ID for each query.
	return $fields . ', meta_value,  "' . $cq_sortfield_count . '" AS sortfield';
});

// Modify combined ordering:
add_filter( 'cq_orderby', function( $orderby ) {
	$current_time = time() - ( 5 * 60 * 60 );
	//  Here we first sort by the new field which then allows a second layer of sorting within the two groups.
	return 'sortfield ASC, IF( combined.meta_value > ' . $current_time . ', combined.meta_value, 0) ASC, IF( combined.meta_value <= ' . $current_time . ', combined.meta_value, null) DESC';
});

Just sharing in case this helps at all!

Original query being discarded

I'm using pre_get_posts to inserted a combined query but it's removing the original query completely.

SELECT SQL_CALC_FOUND_ROWS *
FROM ( (SELECT wp_posts.*
FROM wp_posts 
INNER JOIN wp_term_relationships
ON (wp_posts.ID = wp_term_relationships.object_id)
WHERE 1=1 
AND ( wp_term_relationships.term_taxonomy_id IN (5) )
AND wp_posts.post_type = 'document_cpt'
AND (wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'acf-disabled'
OR wp_posts.post_status = 'private')
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC
LIMIT 0, 20 ) ) as combined 
ORDER BY post_title DESC
LIMIT 0, 20

Isn't there supposed to be a UNION in there or something?

Search issue

After apply this plugin to search, the results are not filter based on the search keyword. Kindly help us.

Thanks!

Does not work when querying events and posts - Maybe event plugin issue?

Hi!

This is an awesome plugin. I've used it and it works great. This time, I'm trying something different and was wondering if you could perhaps shed some light.

I'm using Event Organiser for event management.

Using Combine Queries, I'm trying to query posts and events. I know Combine Queries is working because it works just fine when I'm not querying events.

`
// -----------------
// Sub query #1:
// -----------------
$args1 = [
'post_type' => array( 'news' ),
// 'fields' => 'ids',
'posts_per_page' => 100,
];

// -----------------
// Sub query #2:
// -----------------
$args2 = [
	'post_type'        => 'event',
	 'suppress_filters' => false,
	// 'fields'           => 'ids',
	'posts_per_page'      => 100,
];

// ---------------------------
// Combined queries #1 + #2:
// ---------------------------
$args = [
	'combined_query' => [
		'args'           => [ $args1, $args2 ],
		'union'          => 'UNION',
		'posts_per_page' => 12,
		'post_status'      => 'publish',
		// 'orderby'        => 'none',
	],
];

// ---------
// Output:
// ---------
$query = new WP_Query( $args );`

This is a very basic query for starting out. Once I get this working, I plan to make the event's query a bit more advanced. That's why I'm using this and not simply post_type => array( 'news', 'event' ).

When the above runs, there are no posts. When I change 'event' to another post type, it works just fine. It's definitely something related to the event post type but I'm not sure what. Have any ideas off the top of your head?

Thanks for any assistance!

query arg order

Hello!

Thanks for the plugin :)
I'd like to order the posts from $arg1 first then $arg2, but the post is mixed. Am I doing anything wrong? Please see the codes below. (It is to show posts before "end_date" first" and then after "end date", which means expired) Thank you!


$today = date('Ymd');

$args1 = [
	'category_name' => $term_slug,
	'posts_per_page' => 100000,
	'meta_query'     => [
                [
			'key'      => 'end_date',
			 'value'    => $today,
			'compare'  => '>=',
		],
	 ],
	 'orderby' => 'modified',
	 'order' => 'DESC',

	];
				
$args2 = [
	 'category_name' => $term_slug,
	'posts_per_page' => 100000,
	'meta_query'     => [
		 [
			'key'      => 'end_date',
			'value'    => $today,
			'compare'  => '<',
		],
	 ],
	 'orderby' => 'modified',
	'order' => 'DESC',
	];

$final_query_args = [
	 'posts_per_page'      => 12,
	 'ignore_sticky_posts' => 1,
	 'combined_query' => [
		'args'   => [ $args1,$args2 ],
		'union'  => 'UNION',
	 ]
	];

$final_query_args['paged'] = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
$final_query = new WP_Query( $final_query_args );

Indicate when subsequent queries are made

Hi, is there a way to indicate which query the posts have come from? For example if I run two queries combined I want to know when the posts from the first query ends and when the posts from the second query begins.

I am trying to create an events calendar which fetches events from a user defined date and orders them according to a priority field. Then it runs another query for the next day and returns those posts also sorted by priority (Eventually it will do this for up to five subsequent days).

So both the queries are the same, except the date changes:

$day1_args = array(
        'post_type'              => 'events',
        'post_status'            => 'publish',
        'posts_per_archive_page' => 100,
        'tax_query'              => array(
            array(
                'taxonomy'         => 'event_location',
                'field'            => 'slug',
                'terms'            => $county_terms,
                'include_children' => true
            ),
            array(
                'taxonomy'         => 'event_category',
                'field'            => 'slug',
                'terms'            => $category_terms,
                'include_children' => true
            )
        ),
        'meta_query'             => array(
            'relation' => 'AND',
            array(
                'key'     => 'start_date',
                'value'   => $post_vars['date'],
                'compare' => '<=',
                'type'    => 'DATE',
            ),
            array(
                'key'     => 'end_date',
                'value'   => $post_vars['date'],
                'compare' => '>=',
                'type'    => 'DATE',
            )
        ),
        'meta_key'               => 'priority',
        'orderby'                => 'priority',
        'order'                  => 'ASC',
    );

    $day2_args = array(
        'post_type'              => 'events',
        'post_status'            => 'publish',
        'tax_query'              => array(
            array(
                'taxonomy'         => 'event_location',
                'field'            => 'slug',
                'terms'            => $county_terms,
                'include_children' => true
            ),
            array(
                'taxonomy'         => 'event_category',
                'field'            => 'slug',
                'terms'            => $category_terms,
                'include_children' => true
            )
        ),
        'meta_query'             => array(
            'relation' => 'AND',
            array(
                'key'     => 'start_date',
                'value'   => add_day_to_date($post_vars['date']),
                'compare' => '<=',
                'type'    => 'DATE',
            ),
            array(
                'key'     => 'end_date',
                'value'   => add_day_to_date($post_vars['date']),
                'compare' => '>=',
                'type'    => 'DATE',
            )
        ),
        'meta_key'               => 'start_date',
        'orderby'                => 'start_date',
        'order'                  => 'DESC',
    );

    // Modify combined ordering:
    add_filter( 'cq_orderby', function ( $orderby ) {
        return '"meta value" ASC';
    } );

    // Modify sub fields:
    add_filter( 'cq_sub_fields', function ( $fields ) {
        return $fields . ', "meta value"';
    } );

    $args = [
        'posts_per_page' => $posts_per_page,
        'paged'                  => $paged,
        'combined_query' => [
            'orderby' => [ 'priority' => 'asc', 'priority' => 'asc' ],
            'args'    => [ $day1_args, $day2_args ],
            'union'   => 'UNION ALL',
        ]
    ];

And this works, except I need to know when the posts from the second query come through so I can add a bit of html with the date ahead of the posts. I'm not sure how to do that.

Sub query order not really respected...

Hello,

I want to display my posts with different sizes on my homepage (with a pagination)

  • 2 little news
  • 1 big article
  • 2 little news
  • 1 big article

In order to achieve this, I added a custom field "news_or_big" which equals "news" for little news, and "big" for big articles.

The problem is that at the end, the order of my queries is not respected and I get :

  • 2 little news
  • 2 little news
  • 1 big article
  • 1 big article

I don't know if I did it the right way, here's my code :

//-----------------
            // Sub query #1:
            //-----------------
            $args1 = [
                // get field news
                'post_type' => 'post',
                'category__not_in' => 31,
                'posts_per_page' => 2,
                'meta_key' => 'news_or_big',
                'meta_value' => 'news'
            ];

            //-----------------
            // Sub query #2:
            //-----------------
            $args2 = [
                // get big news
                'post_type' => 'post',
                'category__not_in' => 31,
                'posts_per_page' => 1,
                'meta_key' => 'news_or_big',
                'meta_value' => 'big'
            ];

            //-----------------
            // Sub query #3:
            //-----------------
            $args3 = [
                // get field news
                'post_type' => 'post',
                'category__not_in' => 31,
                'posts_per_page' => 2,
                'meta_key' => 'news_or_big',
                'meta_value' => 'news',
                'offset' => 2,
            ];

            //-----------------
            // Sub query #4:
            //-----------------
            $args4 = [
                // get big news
                'post_type' => 'post',
                'category__not_in' => 31,
                'posts_per_page' => 1,
                'meta_key' => 'news_or_big',
                'meta_value' => 'big',
                'offset' => 1,
            ];

            //---------------------------
            // Combined queries #1 + #2 + #3 + #4:
            //---------------------------
            $args = [
                'posts_per_page' => 6,
                'orderby' => 'meta_value',
                'paged' => $paged,
                'combined_query' => [
                    'args' => [$args1, $args2, $args3, $args4],
                    'union' => 'UNION',
                ]
            ];

Thank you for your help!

Add a WP_Query input argument for the multiple queries

I think it would be more flexible to add a support for a custom argument, like combine_queries, in WP_Query for the multiple queries, instead of using the extended WP_Combine_Query class.

Then we could easily adjust the main query via the pre_get_posts hook:

add_action( 'pre_get_posts', function( $q )
{
    if( ! is_admin() && $q->is_main_query() )
    {
        // Sub query #1:
        // Sub query #2:
        // ...etc

       // Combine subqueries #1 + #2 + ... etc
        $q->set( 'combine_queries', [ $args1, $args2 ] )  
    }
} );

or secondary queries with:

$args = [
    'posts_per_page'    => 5,
    'orderby'           => 'meta_value',
    'order'             => 'DESC',
    'combine_queries'   => [ $args1, $args2 ],
];
WP_Query( $args );

Too few arguments

I'm trying to add on to the main search but getting the warning PHP Warning: sprintf(): Too few arguments in /var/www/wp-content/plugins/wp-combine-queries-master/includes/Generator.php on line 98

In my 'pre_get_posts' handler I have:

function document_posts_search_filter( $query ) {
  if ( !is_admin() && $query->is_main_query() ) {
    if ($query->is_search) {
      if ( isset( $_GET['doctype'] ) && $_GET['doctype'] != "" ) {
        $sub_query_args = array( 'args' => array( create_document_type_args() ), 'union' => 'UNION' );
        $query->set( 'combined_query', $sub_query_args);
      }
    }
    $query->set( 'post_type', array( 'document_cpt' ) );
  }
  return $query;
}
add_filter( 'pre_get_posts', 'document_posts_search_filter' );

where create_document_typs_args returns query args:

function create_document_type_args() {
  $tax_args = array( 'relation' => 'OR' );
  // document types taxonomy
  $doctypes = explode(",", get_query_var( 'doctype' ) );
  $tax_args[] = array(
    'taxonomy' => 'document_type',
    'field' => 'slug',
    'terms' => $doctypes,
    'operator' => 'IN',
  );
  // create the query arguments
  $args = array(
    'post_type' => array( 'document_cpt' ),
    'tax_query'  => $tax_args,
  );
  return $args;
}

What am I doing wrong here?

Fatal error on Install

Hello,

I have been trying to install your plugin on my wordpress install (4.7) and I cannot activate it (Parse error: syntax error, unexpected T_STRING in /home/gmemzeuq/new/wp-content/plugins/wp-combine-queries-master/combined-query.php on line 13).

Is there any way you could help?
Thanks for your great work.

Header has wrong plugin URI

The plugin header has the following URI: https://github.com/birgire/wp-combined-queries
instead of the new one: https://github.com/birgire/wp-combine-queries

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.