build_query_vars_from_query_block

The timeline below displays how wordpress function build_query_vars_from_query_block has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.3

/**
 * Helper function that constructs a WP_Query args array from
 * a `Query` block properties.
 *
 * It's used in Query Loop, Query Pagination Numbers and Query Pagination Next blocks.
 *
 * @since 5.8.0
 * @since 6.1.0 Added `query_loop_block_query_vars` filter and `parents` support in query.
 *
 * @param WP_Block $block Block instance.
 * @param int      $page  Current query's page.
 *
 * @return array Returns the constructed WP_Query arguments.
 */
function build_query_vars_from_query_block($block, $page)
{
    $query = array('post_type' => 'post', 'order' => 'DESC', 'orderby' => 'date', 'post__not_in' => array());
    if (isset($block->context['query'])) {
        if (!empty($block->context['query']['postType'])) {
            $post_type_param = $block->context['query']['postType'];
            if (is_post_type_viewable($post_type_param)) {
                $query['post_type'] = $post_type_param;
            }
        }
        if (isset($block->context['query']['sticky']) && !empty($block->context['query']['sticky'])) {
            $sticky = get_option('sticky_posts');
            if ('only' === $block->context['query']['sticky']) {
                /*
                 * Passing an empty array to post__in will return have_posts() as true (and all posts will be returned).
                 * Logic should be used before hand to determine if WP_Query should be used in the event that the array
                 * being passed to post__in is empty.
                 *
                 * @see https://core.trac.wordpress.org/ticket/28099
                 */
                $query['post__in'] = (!empty($sticky)) ? $sticky : array(0);
                $query['ignore_sticky_posts'] = 1;
            } else {
                $query['post__not_in'] = array_merge($query['post__not_in'], $sticky);
            }
        }
        if (!empty($block->context['query']['exclude'])) {
            $excluded_post_ids = array_map('intval', $block->context['query']['exclude']);
            $excluded_post_ids = array_filter($excluded_post_ids);
            $query['post__not_in'] = array_merge($query['post__not_in'], $excluded_post_ids);
        }
        if (isset($block->context['query']['perPage']) && is_numeric($block->context['query']['perPage'])) {
            $per_page = absint($block->context['query']['perPage']);
            $offset = 0;
            if (isset($block->context['query']['offset']) && is_numeric($block->context['query']['offset'])) {
                $offset = absint($block->context['query']['offset']);
            }
            $query['offset'] = $per_page * ($page - 1) + $offset;
            $query['posts_per_page'] = $per_page;
        }
        // Migrate `categoryIds` and `tagIds` to `tax_query` for backwards compatibility.
        if (!empty($block->context['query']['categoryIds']) || !empty($block->context['query']['tagIds'])) {
            $tax_query = array();
            if (!empty($block->context['query']['categoryIds'])) {
                $tax_query[] = array('taxonomy' => 'category', 'terms' => array_filter(array_map('intval', $block->context['query']['categoryIds'])), 'include_children' => false);
            }
            if (!empty($block->context['query']['tagIds'])) {
                $tax_query[] = array('taxonomy' => 'post_tag', 'terms' => array_filter(array_map('intval', $block->context['query']['tagIds'])), 'include_children' => false);
            }
            $query['tax_query'] = $tax_query;
        }
        if (!empty($block->context['query']['taxQuery'])) {
            $query['tax_query'] = array();
            foreach ($block->context['query']['taxQuery'] as $taxonomy => $terms) {
                if (is_taxonomy_viewable($taxonomy) && !empty($terms)) {
                    $query['tax_query'][] = array('taxonomy' => $taxonomy, 'terms' => array_filter(array_map('intval', $terms)), 'include_children' => false);
                }
            }
        }
        if (isset($block->context['query']['order']) && in_array(strtoupper($block->context['query']['order']), array('ASC', 'DESC'), true)) {
            $query['order'] = strtoupper($block->context['query']['order']);
        }
        if (isset($block->context['query']['orderBy'])) {
            $query['orderby'] = $block->context['query']['orderBy'];
        }
        if (isset($block->context['query']['author'])) {
            if (is_array($block->context['query']['author'])) {
                $query['author__in'] = array_filter(array_map('intval', $block->context['query']['author']));
            } elseif (is_string($block->context['query']['author'])) {
                $query['author__in'] = array_filter(array_map('intval', explode(',', $block->context['query']['author'])));
            } elseif (is_int($block->context['query']['author']) && $block->context['query']['author'] > 0) {
                $query['author'] = $block->context['query']['author'];
            }
        }
        if (!empty($block->context['query']['search'])) {
            $query['s'] = $block->context['query']['search'];
        }
        if (!empty($block->context['query']['parents']) && is_post_type_hierarchical($query['post_type'])) {
            $query['post_parent__in'] = array_filter(array_map('intval', $block->context['query']['parents']));
        }
    }
    /**
     * Filters the arguments which will be passed to `WP_Query` for the Query Loop Block.
     *
     * Anything to this filter should be compatible with the `WP_Query` API to form
     * the query context which will be passed down to the Query Loop Block's children.
     * This can help, for example, to include additional settings or meta queries not
     * directly supported by the core Query Loop Block, and extend its capabilities.
     *
     * Please note that this will only influence the query that will be rendered on the
     * front-end. The editor preview is not affected by this filter. Also, worth noting
     * that the editor preview uses the REST API, so, ideally, one should aim to provide
     * attributes which are also compatible with the REST API, in order to be able to
     * implement identical queries on both sides.
     *
     * @since 6.1.0
     *
     * @param array    $query Array containing parameters for `WP_Query` as parsed by the block context.
     * @param WP_Block $block Block instance.
     * @param int      $page  Current query's page.
     */
    return apply_filters('query_loop_block_query_vars', $query, $block, $page);
}

WordPress Version: 6.2

/**
 * Helper function that constructs a WP_Query args array from
 * a `Query` block properties.
 *
 * It's used in Query Loop, Query Pagination Numbers and Query Pagination Next blocks.
 *
 * @since 5.8.0
 * @since 6.1.0 Added `query_loop_block_query_vars` filter and `parents` support in query.
 *
 * @param WP_Block $block Block instance.
 * @param int      $page  Current query's page.
 *
 * @return array Returns the constructed WP_Query arguments.
 */
function build_query_vars_from_query_block($block, $page)
{
    $query = array('post_type' => 'post', 'order' => 'DESC', 'orderby' => 'date', 'post__not_in' => array());
    if (isset($block->context['query'])) {
        if (!empty($block->context['query']['postType'])) {
            $post_type_param = $block->context['query']['postType'];
            if (is_post_type_viewable($post_type_param)) {
                $query['post_type'] = $post_type_param;
            }
        }
        if (isset($block->context['query']['sticky']) && !empty($block->context['query']['sticky'])) {
            $sticky = get_option('sticky_posts');
            if ('only' === $block->context['query']['sticky']) {
                /*
                 * Passing an empty array to post__in will return have_posts() as true (and all posts will be returned).
                 * Logic should be used before hand to determine if WP_Query should be used in the event that the array
                 * being passed to post__in is empty.
                 *
                 * @see https://core.trac.wordpress.org/ticket/28099
                 */
                $query['post__in'] = (!empty($sticky)) ? $sticky : array(0);
                $query['ignore_sticky_posts'] = 1;
            } else {
                $query['post__not_in'] = array_merge($query['post__not_in'], $sticky);
            }
        }
        if (!empty($block->context['query']['exclude'])) {
            $excluded_post_ids = array_map('intval', $block->context['query']['exclude']);
            $excluded_post_ids = array_filter($excluded_post_ids);
            $query['post__not_in'] = array_merge($query['post__not_in'], $excluded_post_ids);
        }
        if (isset($block->context['query']['perPage']) && is_numeric($block->context['query']['perPage'])) {
            $per_page = absint($block->context['query']['perPage']);
            $offset = 0;
            if (isset($block->context['query']['offset']) && is_numeric($block->context['query']['offset'])) {
                $offset = absint($block->context['query']['offset']);
            }
            $query['offset'] = $per_page * ($page - 1) + $offset;
            $query['posts_per_page'] = $per_page;
        }
        // Migrate `categoryIds` and `tagIds` to `tax_query` for backwards compatibility.
        if (!empty($block->context['query']['categoryIds']) || !empty($block->context['query']['tagIds'])) {
            $tax_query = array();
            if (!empty($block->context['query']['categoryIds'])) {
                $tax_query[] = array('taxonomy' => 'category', 'terms' => array_filter(array_map('intval', $block->context['query']['categoryIds'])), 'include_children' => false);
            }
            if (!empty($block->context['query']['tagIds'])) {
                $tax_query[] = array('taxonomy' => 'post_tag', 'terms' => array_filter(array_map('intval', $block->context['query']['tagIds'])), 'include_children' => false);
            }
            $query['tax_query'] = $tax_query;
        }
        if (!empty($block->context['query']['taxQuery'])) {
            $query['tax_query'] = array();
            foreach ($block->context['query']['taxQuery'] as $taxonomy => $terms) {
                if (is_taxonomy_viewable($taxonomy) && !empty($terms)) {
                    $query['tax_query'][] = array('taxonomy' => $taxonomy, 'terms' => array_filter(array_map('intval', $terms)), 'include_children' => false);
                }
            }
        }
        if (isset($block->context['query']['order']) && in_array(strtoupper($block->context['query']['order']), array('ASC', 'DESC'), true)) {
            $query['order'] = strtoupper($block->context['query']['order']);
        }
        if (isset($block->context['query']['orderBy'])) {
            $query['orderby'] = $block->context['query']['orderBy'];
        }
        if (isset($block->context['query']['author']) && (int) $block->context['query']['author'] > 0) {
            $query['author'] = (int) $block->context['query']['author'];
        }
        if (!empty($block->context['query']['search'])) {
            $query['s'] = $block->context['query']['search'];
        }
        if (!empty($block->context['query']['parents']) && is_post_type_hierarchical($query['post_type'])) {
            $query['post_parent__in'] = array_filter(array_map('intval', $block->context['query']['parents']));
        }
    }
    /**
     * Filters the arguments which will be passed to `WP_Query` for the Query Loop Block.
     *
     * Anything to this filter should be compatible with the `WP_Query` API to form
     * the query context which will be passed down to the Query Loop Block's children.
     * This can help, for example, to include additional settings or meta queries not
     * directly supported by the core Query Loop Block, and extend its capabilities.
     *
     * Please note that this will only influence the query that will be rendered on the
     * front-end. The editor preview is not affected by this filter. Also, worth noting
     * that the editor preview uses the REST API, so, ideally, one should aim to provide
     * attributes which are also compatible with the REST API, in order to be able to
     * implement identical queries on both sides.
     *
     * @since 6.1.0
     *
     * @param array    $query Array containing parameters for `WP_Query` as parsed by the block context.
     * @param WP_Block $block Block instance.
     * @param int      $page  Current query's page.
     */
    return apply_filters('query_loop_block_query_vars', $query, $block, $page);
}

WordPress Version: 6.1

/**
 * Helper function that constructs a WP_Query args array from
 * a `Query` block properties.
 *
 * It's used in Query Loop, Query Pagination Numbers and Query Pagination Next blocks.
 *
 * @since 5.8.0
 * @since 6.1.0 Added `query_loop_block_query_vars` filter and `parents` support in query.
 *
 * @param WP_Block $block Block instance.
 * @param int      $page  Current query's page.
 *
 * @return array Returns the constructed WP_Query arguments.
 */
function build_query_vars_from_query_block($block, $page)
{
    $query = array('post_type' => 'post', 'order' => 'DESC', 'orderby' => 'date', 'post__not_in' => array());
    if (isset($block->context['query'])) {
        if (!empty($block->context['query']['postType'])) {
            $post_type_param = $block->context['query']['postType'];
            if (is_post_type_viewable($post_type_param)) {
                $query['post_type'] = $post_type_param;
            }
        }
        if (isset($block->context['query']['sticky']) && !empty($block->context['query']['sticky'])) {
            $sticky = get_option('sticky_posts');
            if ('only' === $block->context['query']['sticky']) {
                $query['post__in'] = $sticky;
            } else {
                $query['post__not_in'] = array_merge($query['post__not_in'], $sticky);
            }
        }
        if (!empty($block->context['query']['exclude'])) {
            $excluded_post_ids = array_map('intval', $block->context['query']['exclude']);
            $excluded_post_ids = array_filter($excluded_post_ids);
            $query['post__not_in'] = array_merge($query['post__not_in'], $excluded_post_ids);
        }
        if (isset($block->context['query']['perPage']) && is_numeric($block->context['query']['perPage'])) {
            $per_page = absint($block->context['query']['perPage']);
            $offset = 0;
            if (isset($block->context['query']['offset']) && is_numeric($block->context['query']['offset'])) {
                $offset = absint($block->context['query']['offset']);
            }
            $query['offset'] = $per_page * ($page - 1) + $offset;
            $query['posts_per_page'] = $per_page;
        }
        // Migrate `categoryIds` and `tagIds` to `tax_query` for backwards compatibility.
        if (!empty($block->context['query']['categoryIds']) || !empty($block->context['query']['tagIds'])) {
            $tax_query = array();
            if (!empty($block->context['query']['categoryIds'])) {
                $tax_query[] = array('taxonomy' => 'category', 'terms' => array_filter(array_map('intval', $block->context['query']['categoryIds'])), 'include_children' => false);
            }
            if (!empty($block->context['query']['tagIds'])) {
                $tax_query[] = array('taxonomy' => 'post_tag', 'terms' => array_filter(array_map('intval', $block->context['query']['tagIds'])), 'include_children' => false);
            }
            $query['tax_query'] = $tax_query;
        }
        if (!empty($block->context['query']['taxQuery'])) {
            $query['tax_query'] = array();
            foreach ($block->context['query']['taxQuery'] as $taxonomy => $terms) {
                if (is_taxonomy_viewable($taxonomy) && !empty($terms)) {
                    $query['tax_query'][] = array('taxonomy' => $taxonomy, 'terms' => array_filter(array_map('intval', $terms)), 'include_children' => false);
                }
            }
        }
        if (isset($block->context['query']['order']) && in_array(strtoupper($block->context['query']['order']), array('ASC', 'DESC'), true)) {
            $query['order'] = strtoupper($block->context['query']['order']);
        }
        if (isset($block->context['query']['orderBy'])) {
            $query['orderby'] = $block->context['query']['orderBy'];
        }
        if (isset($block->context['query']['author']) && (int) $block->context['query']['author'] > 0) {
            $query['author'] = (int) $block->context['query']['author'];
        }
        if (!empty($block->context['query']['search'])) {
            $query['s'] = $block->context['query']['search'];
        }
        if (!empty($block->context['query']['parents']) && is_post_type_hierarchical($query['post_type'])) {
            $query['post_parent__in'] = array_filter(array_map('intval', $block->context['query']['parents']));
        }
    }
    /**
     * Filters the arguments which will be passed to `WP_Query` for the Query Loop Block.
     *
     * Anything to this filter should be compatible with the `WP_Query` API to form
     * the query context which will be passed down to the Query Loop Block's children.
     * This can help, for example, to include additional settings or meta queries not
     * directly supported by the core Query Loop Block, and extend its capabilities.
     *
     * Please note that this will only influence the query that will be rendered on the
     * front-end. The editor preview is not affected by this filter. Also, worth noting
     * that the editor preview uses the REST API, so, ideally, one should aim to provide
     * attributes which are also compatible with the REST API, in order to be able to
     * implement identical queries on both sides.
     *
     * @since 6.1.0
     *
     * @param array    $query Array containing parameters for `WP_Query` as parsed by the block context.
     * @param WP_Block $block Block instance.
     * @param int      $page  Current query's page.
     */
    return apply_filters('query_loop_block_query_vars', $query, $block, $page);
}

WordPress Version: 5.8

/**
 * Helper function that constructs a WP_Query args array from
 * a `Query` block properties.
 *
 * It's used in Query Loop, Query Pagination Numbers and Query Pagination Next blocks.
 *
 * @since 5.8.0
 *
 * @param WP_Block $block Block instance.
 * @param int      $page  Current query's page.
 *
 * @return array Returns the constructed WP_Query arguments.
 */
function build_query_vars_from_query_block($block, $page)
{
    $query = array('post_type' => 'post', 'order' => 'DESC', 'orderby' => 'date', 'post__not_in' => array());
    if (isset($block->context['query'])) {
        if (!empty($block->context['query']['postType'])) {
            $post_type_param = $block->context['query']['postType'];
            if (is_post_type_viewable($post_type_param)) {
                $query['post_type'] = $post_type_param;
            }
        }
        if (isset($block->context['query']['sticky']) && !empty($block->context['query']['sticky'])) {
            $sticky = get_option('sticky_posts');
            if ('only' === $block->context['query']['sticky']) {
                $query['post__in'] = $sticky;
            } else {
                $query['post__not_in'] = array_merge($query['post__not_in'], $sticky);
            }
        }
        if (!empty($block->context['query']['exclude'])) {
            $excluded_post_ids = array_map('intval', $block->context['query']['exclude']);
            $excluded_post_ids = array_filter($excluded_post_ids);
            $query['post__not_in'] = array_merge($query['post__not_in'], $excluded_post_ids);
        }
        if (isset($block->context['query']['perPage']) && is_numeric($block->context['query']['perPage'])) {
            $per_page = absint($block->context['query']['perPage']);
            $offset = 0;
            if (isset($block->context['query']['offset']) && is_numeric($block->context['query']['offset'])) {
                $offset = absint($block->context['query']['offset']);
            }
            $query['offset'] = $per_page * ($page - 1) + $offset;
            $query['posts_per_page'] = $per_page;
        }
        if (!empty($block->context['query']['categoryIds'])) {
            $term_ids = array_map('intval', $block->context['query']['categoryIds']);
            $term_ids = array_filter($term_ids);
            $query['category__in'] = $term_ids;
        }
        if (!empty($block->context['query']['tagIds'])) {
            $term_ids = array_map('intval', $block->context['query']['tagIds']);
            $term_ids = array_filter($term_ids);
            $query['tag__in'] = $term_ids;
        }
        if (isset($block->context['query']['order']) && in_array(strtoupper($block->context['query']['order']), array('ASC', 'DESC'), true)) {
            $query['order'] = strtoupper($block->context['query']['order']);
        }
        if (isset($block->context['query']['orderBy'])) {
            $query['orderby'] = $block->context['query']['orderBy'];
        }
        if (isset($block->context['query']['author']) && (int) $block->context['query']['author'] > 0) {
            $query['author'] = (int) $block->context['query']['author'];
        }
        if (!empty($block->context['query']['search'])) {
            $query['s'] = $block->context['query']['search'];
        }
    }
    return $query;
}