My custom wp search query in
$args = array(
'post_type' => 'post',
'taxonomy' => 'location',
'field' => 'name',
'posts_per_page' => 10,
'term' => $keyword,
);
$wp_query = new WP_Query($args);
I have 2 post which location is London and oxford,london .Now when i search london then it show only 1 post**(1st one)** .Also when i search oxford then it show no result found.
When i search oxford london then its working fine.
Befor WP_Query Run write this code
function advance_search_where($where){
global $wpdb;
if (is_search())
$where .= "OR (t.name LIKE '%".get_search_query()."%' AND {$wpdb->posts}.post_status = 'publish')";
return $where;
}
function advance_search_join($join){
global $wpdb;
if (is_search())
$join .= "LEFT JOIN {$wpdb->term_relationships} tr ON {$wpdb->posts}.ID = tr.object_id INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_taxonomy_id=tr.term_taxonomy_id INNER JOIN {$wpdb->terms} t ON t.term_id = tt.term_id";
return $join;
}
function advance_search_groupby($groupby){
global $wpdb;
// we need to group on post ID
$groupby_id = "{$wpdb->posts}.ID";
if(!is_search() || strpos($groupby, $groupby_id) !== false) return $groupby;
// groupby was empty, use ours
if(!strlen(trim($groupby))) return $groupby_id;
// wasn't empty, append ours
return $groupby.", ".$groupby_id;
}
add_filter('posts_where','advance_search_where');
add_filter('posts_join', 'advance_search_join');
add_filter('posts_groupby', 'advance_search_groupby');
Now Run Your WP_Query Like this
$args = array(
'post_type' => 'post',
'posts_per_page' => 10,
's' => $keyword,
);
$wp_query = new WP_Query($args);
After all your result and that you want you have to just remove the above filter coz if you not remove that then it will apply in other wp_query of that page.
remove_filter('posts_where','advance_search_where');
remove_filter('posts_join', 'advance_search_join');
remove_filter('posts_groupby', 'advance_search_groupby');
Related
I am using the following code to get a yearly archive of my posts with a post type of 'foi'.
Here is my code:
wp_get_archives(
array(
'post_type' => 'foi',
'type' => 'yearly',
'limit' => '10',
'show_post_count' => 'true'
)
);
I have a taxonomy set-up for the post type foi and I would like to use that in the wp_get_archives() function somehow. An example would be to show the yearly archive for all posts with a post type of foi but also with a taxonomy of document.
How can this be achieved?
You get it using filter like below:
In templates/custom-archive-template.php
add_filter( 'getarchives_where', 'custom_archive_by_category_where' );
add_filter( 'getarchives_join', 'custom_archive_by_category_join' );
$args = array();
wp_get_archives(
array(
'type' => 'yearly',
'format' => 'option',
'post_type' => 'news',
)
);
remove_filter( 'getarchives_where', 'custom_archive_by_category_where' );
remove_filter( 'getarchives_join', 'custom_archive_by_category_join' );
In functions.php:
function custom_archive_by_category_join( $x ) {
global $wpdb;
return $x . " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
}
function custom_archive_by_category_where($x) {
global $wpdb;
$current_term_slug = get_query_var( 'news_category' );
if (!empty($current_term_slug)) {
$current_term = get_term_by('slug', $current_term_slug, 'news_category');
if (is_wp_error($current_term) ) {
return $x;
}
$current_term_id = $current_term->term_id;
return $x . " AND $wpdb->term_taxonomy.taxonomy = 'news_category' AND $wpdb->term_taxonomy.term_id IN ($current_term_id)";
}
return $x;
}
Please change news_category to your desire category slug.
Originally posted on: https://developer.wordpress.org/reference/functions/wp_get_archives/#div-comment-3182
I have multiple products, whose sku names are like AL-888, A-2323, AL-etrere.
I want to find products on basis of this sku name's first two words.
I am creating shortcode for this purpose, but can't able to get it work.
Any help should be appreciated.
Code for this shortcode:
function all_state_list_function(){
$name = $_GET['sku']; //this give sku value from url like Al:2323
echo $name;
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'orderby' => 'name',
'order' => 'DESC',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'free_form',
'value' => '1',
),
array(
'key' => '_sku',
'value' => $name.'-%',
'compare' => 'LIKE',
),
),
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$product_id = get_the_ID();
echo $product_id;
endwhile;
wp_reset_query();
}
add_shortcode( 'all_state_list_shortcode', 'all_state_list_function' );
Based on your first version code that had an SQL query, here is the correct way to get product IDs from first SKU characters value using GET method from an URL:
add_shortcode( 'all_state_list_shortcode', 'all_state_list_function' );
function all_state_list_function(){
if ( isset($_GET['sku']) && ! empty($_GET['sku']) ) {
ob_start();
$sku = esc_attr( $_GET['sku'] ) .'%';
global $wpdb;
$results = $wpdb->get_col( "
SELECT p.ID FROM {$wpdb->prefix}posts as p
JOIN {$wpdb->prefix}postmeta as pm ON p.ID = pm.post_id
WHERE p.post_type LIKE 'product' AND p.post_status LIKE 'publish'
AND meta_key LIKE '_sku' AND meta_value LIKE '$sku'
" );
if( count($results) > 0 ) {
echo implode(',', $results);
} else {
echo 'Nothing found';
}
return ob_get_clean();
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
SELECT
IF (POSITION('Villa' IN p.post_title )>=1,
SUBSTRING(p.post_title, 7), post_title) AS 'Title',
p.post_title,
p.ID,
p.post_content
FROM wp_posts p INNER JOIN wp_term_relationships tr
ON p.ID=tr.object_id where tr.term_taxonomy_id=4
and p.post_status='publish'
ORDER BY Title ASC;
I can run above query to get data with "wpdb" function like
$wpdb->get_results($query);
But I need the above results to be returned as a Wp_query object as I want to use functions like get_the_excerpt()
The orderby parameter accepts the post__in sorting value as a possible way to sort posts returned. With orderby set to post__in, the posts will be returned in the order they are entered into the post__in parameter.
The following code
args = [
'post__in' =>[3, 1, 2],
'orderby' => 'post__in'
];
$q = new WP_Query( $args );
will return posts 1,2, and 3 in the following order
3,1,2
Try this code,
$args = array(
'post_type' => $post_type,
'posts_per_page' => -1,
'post_status'=>'publish',
'orderby'=>'title',
'order' => 'ASC',
'tax_query' => array(
array(
'taxonomy' => $taxonomy,
'field' => 'id',
'terms' => 4
)
)
);
$query = new WP_Query($args);
$query_posts = $query->posts;
var_dump($query_posts);
You can take your WPDB results and use the post functions like this...
global $wpdb;
global $post;
$query = "SELECT
IF (POSITION('Villa' IN p.post_title )>=1,
SUBSTRING(p.post_title, 7), post_title) AS 'Title',
p.post_title,
p.ID,
p.post_content
FROM wp_posts p INNER JOIN wp_term_relationships tr
ON p.ID=tr.object_id where tr.term_taxonomy_id=4
and p.post_status='publish'
ORDER BY Title ASC;"
$result = $wpdb->get_results( $query );
foreach( $result as $post )
{
setup_postdata( $post );
echo "<div>" . get_the_excerpt() . "</div>";
}
Make sure you set the $post global.
Is it possible to use a wildcard in the get_posts() function?
I have made the query I wanted in SQL already:
select * from wp_posts p
left join wp_postmeta pm on p.id = pm.post_id
where pm.meta_key like 'additional_downloads%' and pm.meta_value = 81 and p.post_status = "publish"
Which gives me the results I want.
Then I tried using to do that with the built-in get_posts() function in WordPress:
get_posts(array('meta_key' => 'additional_downloads%', 'meta_value' => 81))
But that gives me 0 results. The reason I need this wildcard is because a post can have more than 1 additional download, and those are stored in the wp_postmeta table with the meta_keys 'additional_downloads_0', 'additional_downloads_1' etc etc
Any idea how to do this using the wordpress functions?
We can filter the WHERE clause of the query.
THE FILTER
add_filter( 'posts_where', function ( $where, \WP_Query $q )
{
// Check for our custom query var
if ( true !== $q->get( 'wildcard_on_key' ) )
return $where;
// Lets filter the clause
$where = str_replace( 'meta_key =', 'meta_key LIKE', $where );
return $where;
}, 10, 2 );
THE QUERY
$args = [
'suppress_filters' => false,
'wildcard_on_key' => true,
'meta_query' = [
[
'key' => 'additional_downloads_%',
'value' => 81
]
]
];
$q = get_posts( $args );
I only want to show posts which do not have the term 'brand-slug' for the taxonomy 'product-brand'.
My current query doesn't apply the filter:
SELECT DISTINCT * FROM $wpdb->posts AS p
LEFT JOIN $wpdb->postmeta AS meta ON p.ID = meta.post_id
LEFT JOIN $wpdb->term_relationships AS rel ON rel.object_id = p.ID
LEFT JOIN $wpdb->term_taxonomy AS tax ON tax.term_taxonomy_id = rel.term_taxonomy_id
LEFT JOIN $wpdb->terms AS term ON tax.term_id = term.term_id
WHERE 1=1
AND p.post_type = 'product'
AND p.post_status = 'publish'
AND p.post_title LIKE '%$trimmed%' OR (meta.meta_key = 'product_model' AND meta.meta_value LIKE '%$trimmed%')
AND (tax.taxonomy = 'product-brand' AND term.slug NOT IN ('$protected'))
Neither taxonomy or slug conditionals seem to be working in the above query.
Any help is appreciated!
Notes:
It looks like you're not using $wpdb->prepare(), so you risk SQL injections.
I also think you're missing parentheses around the relevant OR parts, so you don't end up displaying drafts, for example.
Alternative:
Instead of writing an hardcoded SQL query, we should be able to use the WP_Query class, with some modifications through hooks/filters.
Here's an example (PHP 5.4+):
$args = [
'_meta_or_like_title' => $trimmed, // Our new custom argument!
'post_type' => 'product',
'post_status' => 'publish',
'meta_query' => [
[
'key' => 'product_model',
'value' => $trimmed, // Your meta value
'compare' => 'LIKE'
]
],
'tax_query' => [
[
'taxonomy' => 'product-brand',
'field' => 'slug',
'terms' => $protected, // Your terms array
'operator' => 'NOT IN'
]
]
];
where the custom _meta_or_like_title argument is supported by a slightly modified plugin I wrote for another question here.
Plugin:
<?php
/**
* Plugin Name: Meta OR LIKE Title query in WP_Query
* Description: Activated through the '_meta_or_like_title' argument of WP_Query
* Plugin URI: http://stackoverflow.com/a/31241416/2078474
* Plugin Author: Birgir Erlendsson (birgire)
* Version: 0.0.1
*/
add_action( 'pre_get_posts', function( $q )
{
if( $title = $q->get( '_meta_or_like_title' ) )
{
add_filter( 'get_meta_sql', function( $sql ) use ( $title )
{
global $wpdb;
// Only run once:
static $nr = 0;
if( 0 != $nr++ ) return $sql;
// Modify WHERE part:
$sql['where'] = sprintf(
" AND ( %s OR %s ) ",
$wpdb->prepare(
"{$wpdb->posts}.post_title LIKE '%%%s%%'",
$wpdb->esc_like( $title )
),
mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) )
);
return $sql;
});
}
}, PHP_INT_MAX );