Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

array_merge overwrites $query_args['tax_query'] after it's added in aql_query_vars filter #82

Open
robistek opened this issue Sep 6, 2024 · 3 comments
Assignees
Labels
bug Something isn't working Needs More Information

Comments

@robistek
Copy link

robistek commented Sep 6, 2024

When modifying the $query_args using the aql_query_vars filter, the array_merge in the query_loop_block_query_vars callback function overwrites the tax_query in $query_args. This causes issues when custom tax queries are added via filters, as demonstrated in the code below

function remove_pasta_recipes_from_aql_block( array $query_args, array $block_query, bool $inherited ): array {

        $query_args['tax_query'] = array(
            array(
                'taxonomy'         => 'recipe_category',
                'field'            => 'slug',
                'terms'            => 'pasta',
                'operator'         => 'NOT IN',
                'include_children' => false,
            ),
        );

    return $query_args;
}
add_filter( 'aql_query_vars', 'remove_pasta_recipes_from_aql_block', 10, 3 );

The line for reference:

return array_merge(

$default_query contains taxonomy filters set via 'Filters' in the 'Block' settings/tab.

In this example the array key tax_query replaces the previous one when array_merge is used, losing any previous taxonomies defined in $default_query.

A possible fix could be to use array_merge_recursive instead of array_merge

@ryanwelcher ryanwelcher added the bug Something isn't working label Oct 7, 2024
@ryanwelcher ryanwelcher self-assigned this Oct 7, 2024
@ryanwelcher
Copy link
Owner

Thanks for opening this issues. I'll look at it and get some unit tests wrapped around this.

@ryanwelcher
Copy link
Owner

@robistek looking at your code again, it looks like you are actually replacing the key in the hook by assigning tax_query to an array rather than adding to it.

You should check to see that it's defined first but the code below is going to add to the existing tax_query array.

function remove_pasta_recipes_from_aql_block( array $query_args, array $block_query, bool $inherited ): array {

        $query_args['tax_query'][] = 
            array(
                'taxonomy'         => 'recipe_category',
                'field'            => 'slug',
                'terms'            => 'pasta',
                'operator'         => 'NOT IN',
                'include_children' => false,
            );

    return $query_args;
}
add_filter( 'aql_query_vars', 'remove_pasta_recipes_from_aql_block', 10, 3 );

@robistek
Copy link
Author

Thanks for the reply and the patience, @ryanwelcher.

I have modified the code, tested it and written a more complete example.

I have updated my filter function to make it more robust - thanks for your input:

function remove_pasta_recipes_from_aql_block( array $query_args, array $block_query, bool $inherited ): array {

    if ( ! $inherited ) {
		$additional_query_args =  array(
                      'taxonomy'         => 'recipe_category',
                      'field'            => 'slug',
                      'terms'            => 'pasta',
                      'operator'         => 'NOT IN',
                      'include_children' => false,
                  );

		// Exclude posts where the taxonomy 'recipe_category' has the slug 'pasta'.
		if ( isset( $query_args['tax_query'] ) && is_array( $query_args['tax_query'] ) ) {
			$query_args['tax_query'][] = $additional_query_args;
		} else {
			$query_args['tax_query'] = array(
				$additional_query_args,
			);
		}
    }

    return $query_args;
}
add_filter( 'aql_query_vars', 'remove_pasta_recipes_from_aql_block', 10, 3 );

When this filter returns $query_args in query-loop.php, $default_query and $filtered_query_args are merged.

During debugging I found out that even if $default_query has a 'tax_query' key is doesn't mean that $query_args (which is passed to the aql_query_vars filter) has a 'tax_query' key.

$default_query = array (
  'post_type' => 'recipe',
  'order' => 'DESC',
  'orderby' => 'date',
  'tax_query' => 
  array (
    0 => 
    array (
      'taxonomy' => 'recipe_ingredient',
      'terms' => 
      array (
        0 => 123,
      ),
      'include_children' => false,
    ),
  ),
  'offset' => 0,
  'posts_per_page' => 4,
  'author__in' => 
  array (
  ),
);

$filtered_query_args = array (
  'post__not_in' => 
  array (
    0 => 1000,
  ),
  'tax_query' => 
  array (
    0 => 
    array (
      'taxonomy' => 'recipe_category',
      'field' => 'slug',
      'terms' => 'pasta',
      'operator' => 'NOT IN',
      'include_children' => false,
    ),
  ),
);

The result of print_r( array_merge( $default_query, $filtered_query_args ) ) will be an array with the key 'recipe_ingredient' missing:

Array
(
    [post_type] => sd_recipe
    [order] => DESC
    [orderby] => date
    [tax_query] => Array
        (
            [0] => Array
                (
                    [taxonomy] => recipe_category
                    [field] => slug
                    [terms] => pasta
                    [operator] => NOT IN
                    [include_children] => 
                )

        )

    [offset] => 0
    [posts_per_page] => 4
    [author__in] => Array
        (
        )

    [post__not_in] => Array
        (
            [0] => 1000
        )

)

Am I using the aql_query_vars filter as intended?
Should I be using the $block_query parameter as a base to build a the query array before it is returned?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Needs More Information
Projects
None yet
Development

No branches or pull requests

2 participants