I am using the pagenavi plugin and mutiple search by taxonomy and acf custom field. However pagenavi is not working on the query search.
add_filter( 'pre_get_posts','nt_custom_search_filter');
function nt_custom_search_filter( $query ) {
if( $query->is_search && !is_admin() ) {
if( isset($_GET['s'] ) ) {
$query->set( 'post_type', array( 'product' ) );// box text search
}
if( $query->is_main_query() ) {
$args[] = array( 'relation' => 'AND' );
if( isset( $_GET[ 'product_cat' ] ) && $_GET[ 'product_cat' ] != 'all' ) {
$args[] =
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $_GET['product_cat']
);
}$query->set( 'tax_query', $args );
$meta_query = array( 'relation' => 'AND' );
if( isset( $_GET[ 'status' ] ) && $_GET[ 'status' ] != 'all' ) {
$meta_query[] = array(
'key' => 'status',
'value' => $_GET['status'],
'compare' => '='
);
}
$query->set( 'meta_query', $meta_query );
}
}
return $query;}
To solve possible problems with an incorrect calculation of the pagination in WP_Query, you need three additional arguments: posts_per_page, paged and offset
In $count we save the number of posts per page, or just use the default which you have set in your wordpress backend under the settings.
$paged tells us which page the user is currently on.
With $offset you calculate how many contributions the loop should be moved.
So you can adjust the $args[] in your $query. Code can look like:
$count = get_option('posts_per_page', 25); // get 25 posts
$paged = get_query_var('paged') ? get_query_var('paged') : 1;
$offset = ($paged - 1) * $count;
$args = array (
'posts_per_page' => $count,
'paged' => $paged,
'offset' => $offset,
'relation' => 'AND'
.
. /* other arguments */
:
);
Edit:
so your code can look like the following. Please notice, that the code is not tested.
add_filter( 'pre_get_posts','nt_custom_search_filter');
function nt_custom_search_filter( $query ) {
if( $query->is_search && !is_admin() ) {
if( isset($_GET['s'] ) ) {
$query->set( 'post_type', array( 'product' ) );// box text search
}
if( $query->is_main_query() ) {
$count = get_option('posts_per_page', 25); // get 25 posts
$paged = get_query_var('paged') ? get_query_var('paged') : 1;
$offset = ($paged - 1) * $count;
$args[] = array( 'posts_per_page' => $count, 'paged' => $paged, 'offset' => $offset, 'relation' => 'AND' );
if( isset( $_GET[ 'product_cat' ] ) && $_GET[ 'product_cat' ] != 'all' ) {
$args[] =
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $_GET['product_cat']
);
}$query->set( 'tax_query', $args );
$meta_query = array( 'relation' => 'AND' );
if( isset( $_GET[ 'status' ] ) && $_GET[ 'status' ] != 'all' ) {
$meta_query[] = array(
'key' => 'status',
'value' => $_GET['status'],
'compare' => '='
);
}
$query->set( 'meta_query', $meta_query );
}
}
return $query;}
Related
I have some code that creates pages with child pages in WordPress. What i would like to do is have each child have its own page template.
As you see below, i am creating child pages of Script and Assets. Currently the child page is created with one page_Full.php added to everything but i would like to have Script and Assets have their own page template. Ideas would be helpful.
Thanks in advance.
function CreatePage(){
$post_title = $_POST['ProjectName'];
$post_excerpt = $_POST['ProjectDiscript'];
$tags = $_POST['TypeOption'];
$pages = array(
array(
'name' => $post_title,
'title' => $post_title,
'child' => array(
'script' => $post_title.'_Script',
'assets' => $post_title.'_Assets'
)
)
);
$template = array(
'post_type' => 'page',
'post_status' => 'publish',
'post_author' => $user_id,
'post_excerpt' => $post_excerpt,
'tags_input' => array($tags),
);
foreach( $pages as $page ) {
$exists = get_page_by_title( $page['title'] );
$my_page = array(
'post_name' => $page['name'],
'post_title' => $page['title'],
'page_template' => 'page_Full.php'
);
$my_page = array_merge( $my_page, $template );
$id = ( $exists ? $exists->ID : wp_insert_post( $my_page ) );
if( isset( $page['child'] ) ) {
foreach( $page['child'] as $key => $value ) {
$child_id = get_page_by_title( $value );
$child_page = array(
'post_name' => $key,
'post_title' => $value,
'post_parent' => $id,
'page_template' => 'page_Full.php'
);
$child_page = array_merge( $child_page, $template );
if( !isset( $child_id ) ) wp_insert_post( $child_page );
}
}
}
wp_die();
}
add_action( 'wp_ajax_CreatePage','CreatePage' );
Had the idea to create an array for every child page - and it seams to work. Perhaps there is still a better way but for the time being - This does the trick!
$pages = array(
array(
'name' => $post_title,
'title' => $post_title,
'child' => array(
'script' => array(
'Pname' => $post_title.'_Script',
'Ptemplate' => 'page_Full_Script.php'
),
'assets' => array(
'Pname' => $post_title.'_Assets',
'Ptemplate' => 'page_Full_Assets.php'
),
'settings' => array(
'Pname' => $post_title.'_Settings',
'Ptemplate' => 'page_Full_Settings.php'
)
)
)
);
Here is the child with sub arrays.
if( isset( $page['child'] ) ) {
foreach( $page['child'] as $key[] => $value ) {
$child_id = get_page_by_title( $value );
$child_page = array(
'post_name' => $value['Pname'],
'post_title' => $value['Pname'],
'post_parent' => $id,
'page_template' => $value['Ptemplate'],
);
$child_page = array_merge( $child_page, $template );
if( !isset( $child_id ) ) wp_insert_post( $child_page );
}
}
And here is where the child array is set as var to be iterated through so that the info can be inserted into the child_page var to be merged and the post inserted.
Thanks to any who took the time to review.
Cheers
I have a custom post type 'product' that returns quite a lot of data in the API response, up to 400 posts with a lot of nodes. Almost all the data is coming from advanced custom fields (I'm using ACF to API plugin to expose it).
On the 'products' page, I only need to show the title & image of the product. Is there a way to remove all other fields when requesting all products with https://example.com/wp-json/wp/v2/product, but leave that data in place when requesting a specific product with https://example.com/wp-json/wp/v2/product/123 ?
You better create a custom endpoint for all products. Add the code below in your custom plugin or add it in functions.php of theme (I will recommend the custom plugin approach though)
You can then access it using https://example.com/wp-json/custom/v1/all-products
add_action( 'rest_api_init', 'rest_api_get_all_products' );
function rest_api_get_all_products() {
register_rest_route( 'custom/v1', '/all-products', array(
'methods' => WP_REST_Server::READABLE,
'callback' => 'rest_api_get_all_products_callback',
'args' => array(
'page' => array(
'sanitize_callback' => 'absint'
),
'posts_per_page' => array(
'sanitize_callback' => 'absint'
)
)
));
}
function rest_api_get_all_products_callback( $request ) {
$posts_data = array();
$paged = $request->get_param( 'page' );
$posts_per_page = $request->get_param( 'posts_per_page' );
$paged = ( isset( $paged ) || ! ( empty( $paged ) ) ) ? $paged : 1;
$posts_per_page = ( isset( $posts_per_page ) || ! ( empty( $posts_per_page ) ) ) ? $posts_per_page : 10;
$query = new WP_Query( array(
'paged' => $paged,
'posts_per_page' => $posts_per_page,
'post_status' => 'publish',
'ignore_sticky_posts' => true,
'post_type' => array( 'product' )
)
);
$posts = $query->posts;
if( empty( $posts ) ){
return new WP_Error( 'no_post_found', 'No Products Found.', array( 'status' => 404 ) );
}
foreach( $posts as $post ) {
$id = $post->ID;
$post_thumbnail = ( has_post_thumbnail( $id ) ) ? get_the_post_thumbnail_url( $id ) : null;
$posts_data[] = (object) array(
'id' => intval($id),
'title' => $post->post_title,
'featured_img' => $post_thumbnail
);
}
$response = rest_ensure_response( $posts_data );
return $response;
}
I need help to make a query to customize the default wordpress searching. I don't want to include title or content or excerpt in wordpress searching but want to search based on meta value of that post.
In default wordpress search wordpress add meta query in "AND" Condition. If there is a way if meta query add in or condition it will also be fine.
Please Help
If you're referring to changing the main query on search results pages (e.g. http://example.com/?s=hello), then try one of these options:
Option #1
This is for:
I don't want to include title or content or excerpt in wordpress
searching
Hook to pre_get_posts and empty the s parameter.
add_action( 'pre_get_posts', function( $wp_query ){
if ( $wp_query->is_main_query() && $wp_query->is_search() ) {
$wp_query->set( 's', '' );
}
});
Option #2
This is for:
In default wordpress search wordpress add meta query in "AND"
Condition. If there is a way if meta query add in or condition it will
also be fine.
Hook to get_meta_sql and substitute the AND with OR.
add_filter( 'get_meta_sql', function( $sql, $meta_query, $type, $primary_table ){
global $wpdb;
if (
'post' === $type &&
$wpdb->posts === $primary_table &&
is_main_query() && is_search()
) {
if ( $sql['where'] && ' AND (' === substr( $sql['where'], 0, 6 ) ) {
$sql['where'] = ' OR ' . substr( $sql['where'], 5 );
}
}
return $sql;
}, 10, 4 );
Option #3
Create a custom search page and use a custom WP_Query instance for querying the posts.
$q = new WP_Query([
'meta_key' => 'some_key',
'meta_value' => 'some_value',
// Or use meta_query
]);
Options #1 and #2 are both tricky and may conflict with plugins on your site, or any custom code which modifies the search-related parameters/queries. Or even standard queries. So use the code at your very own risks.
Hope that helps..
I create a ajax from where I send the input text as "search_text" and check the text is feature or not from meta_key "job_is_featured" value which is store in postmeta. and also check into custom post type category id.
$catids = '22';
$args = array(
'post_type' => 'job', 'order' => 'DESC','posts_per_page' => '-1','s' => 'search_text' ,'orderby' => 'meta_value',
'tax_query' => array(
array(
'taxonomy' => 'job-category',
'field' => 'term_id',
'terms' => $catids,
),
),
'meta_query' => array(
'relation' => 'AND',
array(
'relation' => 'OR',
array(
'key' => 'job_is_featured',
'value' => 1,
'compare' => '=',
),
array(
'key' => 'job_is_featured',
'value' => 0,
'compare' => '=',
),
),
array(
'key' => 'job_location',
'value' => 'search_text',
'compare' => 'LIKE',
),
),
);
$the_query = new WP_Query( $args );
Here is the code which you need to add in functions.php
This code will work with Post Meta and Taxonomy both
if(!function_exists('custom_wp_meta_and_tax_search')){
function custom_wp_meta_and_tax_search($search_args){
/* taxonomy query and meta query arrays */
$tax_query = array();
$meta_query = array();
/* Keyword Based Search */
if( isset ( $_GET['keyword'] ) ) {
$keyword = trim( $_GET['keyword'] );
if ( ! empty( $keyword ) ) {
$search_args['s'] = $keyword;
}
}
/* Custom Meta Key Parameter */
if( isset($_GET['meta_input']) && ($_GET['meta_input'] != 'any')){
$meta_query[] = array(
'key' => 'custom_meta_key',
'value' => $_GET['meta_input'],
'compare' => 'like',
);
}
$min_value = '';
$max_value = '';
if(isset($_GET['min-value']) && $_GET['min-value'] <> 'any'){
$min_value = $_GET['min-value'];
}
if(isset($_GET['max-value']) && $_GET['max-value'] <> 'any'){
$max_value = $_GET['max-value'];
}
/* Logic for Min and Max value Parameters */
/* You need to replace custom_tax with custom taxonomy */
if( isset($min_value) && ($min_value != 'any') && isset($max_value) && ($max_value != 'any') ){
$min_value = doubleval($min_value);
$max_value = doubleval($max_value);
if( $min_value >= 0 && $max_value > $min_value ){
$meta_query[] = array(
'key' => 'custom_tax',
'value' => array( $min_value, $max_value ),
'type' => 'NUMERIC',
'compare' => 'BETWEEN'
);
}
}else if( isset($min_value) && ($min_value != 'any') ){
$min_value = doubleval($min_value);
if( $min_value > 0 ){
$meta_query[] = array(
'key' => 'custom_tax',
'value' => $min_value,
'type' => 'NUMERIC',
'compare' => '>='
);
}
}else if( isset($max_value) && ($max_value != 'any') ){
$max_value = doubleval($max_value);
if( $max_value > 0 ){
$meta_query[] = array(
'key' => 'custom_tax',
'value' => $max_value,
'type' => 'NUMERIC',
'compare' => '<='
);
}
}
// /* if more than one taxonomies exist then specify the relation */
$tax_count = count( $tax_query );
if( $tax_count > 1 ){
$tax_query['relation'] = 'AND';
}
/* if more than one meta query elements exist then specify the relation */
$meta_count = count( $meta_query );
if( $meta_count > 1 ){
$meta_query['relation'] = 'AND';
}
if( $tax_count > 0 ){
$search_args['tax_query'] = $tax_query;
}
/* if meta query has some values then add it to base home page query */
$search_args['meta_query'] = $meta_query;
/* Sort By meta value */
/* You need to replace "custom_meta_key" with the key of custom field you created with post. */
if( (isset($min_value) && ($min_value != 'any')) || ( isset($max_value) && ($max_value != 'any') ) ){
$search_args['orderby'] = 'meta_value_num';
$search_args['meta_key'] = 'custom_meta_key';
$search_args['order'] = 'ASC';
}
return $search_args;
}
}
add_filter('custom_search_parameters','custom_wp_meta_and_tax_search');
Now Run the Query and Filter your posts with Post Meta and taxonomy
$custom_search_args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'paged' => $paged,
);
$custom_search_args = apply_filters('custom_search_parameters',$custom_search_args);
$search_query = new WP_Query( $custom_search_args );
Add this in function.php
add_action( 'pre_get_posts', function( $q )
{
if( $title = $q->get( '_meta_or_title' ) )
{
add_filter( 'get_meta_sql', function( $sql ) use ( $title )
{
global $wpdb;
// Only run once:
static $nr = 0;
if( 0 != $nr++ ) return $sql;
// Modified WHERE
$sql['where'] = sprintf(
" AND ( %s OR %s ) ",
$wpdb->prepare( "{$wpdb->posts}.post_title like '%%%s%%'", $title),
mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) )
);
return $sql;
});
}
});
Usage
$meta_query = array();
$args = array();
$search_string = "test";
$meta_query[] = array(
'key' => 'staff_name',
'value' => $search_string,
'compare' => 'LIKE'
);
$meta_query[] = array(
'key' => 'staff_email',
'value' => $search_string,
'compare' => 'LIKE'
);
//if there is more than one meta query 'or' them
if(count($meta_query) > 1) {
$meta_query['relation'] = 'OR';
}
// The Query
$args['post_type'] = "staff";
$args['_meta_or_title'] = $search_string; //not using 's' anymore
$args['meta_query'] = $meta_query;
$the_query = new WP_Query($args)
if ( $query->is_search())
{
$meta_query = $query->get( 'meta_query' );
//print_r($meta_query);
$meta_query[] = array('key' => '_product_attributes', /* Product Attribute Meta key Here example (_sku, _stock, _stock_status, height, width ) */
'value' => $city,
'compare' => 'LIKE');
$query->set( 'meta_query', $meta_query );
}
}
}
add_action( 'woocommerce_product_query' , 'Add_custom_search2' );
I'm trying to display only products between two dates. When I only put 1 array and one date it works, but when I put other arrays and my second date it doesn't work anymore, it shows all the products. Any idea ?
function custom_meta_query( $meta_query ){
$today = current_time('Ymd');
$args = array (
'meta_query' => array(
'relation' => 'AND',
array(
'key'=>'flash_sale_start',
'value' => $today,
'compare'=>'<=',
'type' => 'DATE'
),
array(
'key'=>'flash_sale_end',
'value' => $today,
'compare'=>'>=',
'type' => 'DATE'
)),);
$date_query = new WP_Query( $args );
//return $meta_query;
}
// The main shop and archives meta query
add_filter( 'woocommerce_product_query_meta_query', 'custom_product_query_meta_query', 10, 2 );
function custom_product_query_meta_query( $meta_query, $query ) {
if( ! is_admin() )
return custom_meta_query( $meta_query );
}
// The shortcode products query
add_filter( 'woocommerce_shortcode_products_query', 'custom__shortcode_products_query', 10, 3 );
function custom__shortcode_products_query( $query_args, $atts, $loop_name ) {
if( ! is_admin() )
$query_args['meta_query'] = custom_meta_query( $query_args['meta_query'] );
return $query_args;
}
// The widget products query
add_filter( 'woocommerce_products_widget_query_args', 'custom_products_widget_query_arg', 10, 1 );
function custom_products_widget_query_arg( $query_args ) {
if( ! is_admin() )
$query_args['meta_query'] = custom_meta_query( $query_args['meta_query'] );
return $query_args;
}
Thank you
I've found the solution, it was an array() problem
function custom_meta_query( $meta_query ){
$today = current_time('Ymd');
$args = array (
'numberposts' => -1,
'meta_query' => array(
'relation' => 'AND',
'start_clause' => array(
'key'=>'flash_sale_start',
'value' => $today,
'compare'=> '<=',
'type' => 'DATE'
),
'end_clause' => array(
'key' => 'flash_sale_end',
'value' => $today,
'compare' => '>=',
'type' => 'DATE'
),
));
return $args;
}
// The main shop and archives meta query
add_filter( 'woocommerce_product_query_meta_query', 'custom_product_query_meta_query', 10, 2 );
function custom_product_query_meta_query( $meta_query, $query ) {
if( ! is_admin() )
return custom_meta_query( $meta_query );
}
// The shortcode products query
add_filter( 'woocommerce_shortcode_products_query', 'custom__shortcode_products_query', 10, 3 );
function custom__shortcode_products_query( $query_args, $atts, $loop_name ) {
if( ! is_admin() )
$query_args['meta_query'] = custom_meta_query( $query_args['meta_query'] );
return $query_args;
}
// The widget products query
add_filter( 'woocommerce_products_widget_query_args', 'custom_products_widget_query_arg', 10, 1 );
function custom_products_widget_query_arg( $query_args ) {
if( ! is_admin() )
$query_args['meta_query'] = custom_meta_query( $query_args['meta_query'] );
return $query_args;
}
I want to find all posts from same categories and same tags like a specific post in a plugin. So I do it actually separately by querying for tags and categories:
$taxonomy_arr = wp_get_post_tags( $this->post->ID, array( "fields" => "ids" ) );
add_filter( 'posts_where', array( $this, 'additional_filter' ) );
foreach ( $taxonomy_arr as $tag_id ) {
$posts_arr = get_posts( array(
'posts_per_page' => $this->max_results,
'tag_id' => (int) $tag_id,
'post_type' => array( $this->included_post_types ),
'orderby' => 'rand',
'suppress_filters' => false
) );
// add to categories selection
if ( is_array( $posts_arr ) ) {
foreach ( $posts_arr as $post_obj ) {
if ( is_object( $post_obj ) ) {
$local_taxonomy_selection[] = (int) $post_obj->ID;
}
}
}
}
// get post categories
$category_array = get_the_category( $this->post->ID );
foreach ( $category_array as $category ) {
$posts_arr = get_posts( array(
'posts_per_page' => $this->max_results*2,
'category' => $category->cat_ID,
'post_type' => array( $this->included_post_types ),
'orderby' => 'rand',
'suppress_filters' => false
));
// add to categories selection
if ( is_array( $posts_arr ) ) {
foreach ( $posts_arr as $post_obj ) {
if ( is_object( $post_obj ) ) {
$local_category_selection[] = (int) $post_obj->ID;
}
}
}
}
// combine post id's arrays
$all_posts = $local_taxonomy_selection + $local_category_selection;
It's working but is there a way to do it in one query?
This question already has answer on wordpress.stackexchange. So copying same code here.
https://wordpress.stackexchange.com/questions/4201/how-to-query-posts-by-category-and-tag
global $wp_query;
$args = array(
'category__and' => 'category',
'tag__in' => 'post_tag', //must use tag id for this field
'posts_per_page' => -1
$posts = get_posts($args);
foreach ($posts as $post) :
//do stuff
endforeach;