Building a WordPress search query that ignores punctuation? - php

I've set up a search query like this:
<?php
$s = get_search_query();
$args = array(
'post_type' => array('post'),
'posts_per_page' => '10',
'order' => 'DESC',
'orderby' => 'date',
's' => $s,
'paged' => $paged
);
$query_search = new WP_Query($args);
if ($query_search->have_posts())
{
while ($query_search->have_posts())
{
$query_search->the_post();
}
}
wp_reset_postdata();
?>
It works great, except when I'm searching for a post that contains punctuation in the title. For example, if the title is "Mark's Book" using "mark's" and "marks" both return no results.
If I just search "mark" it will come up, but I want either of the above keywords to also retrieve the post.
Is there something simple I'm missing as far as making this compatible with punctuation?

default get_search_query() pass through data on esc_attr() to ensure that it is safe for placing in an html attribute. if you want to off esc_attr() then try this code,
$s = get_search_query( false );
may be it'll help you

You can try this in this way:
$s = get_query_var('s');
$s = addslashes($s); //<-- even if you remove this the query will work
$args = array(
'post_type' => array('post'),
'posts_per_page' => '10',
'order' => 'DESC',
'orderby' => 'date',
's' => $s,
'paged' => $paged
);
$query_search = new WP_Query($args);
print_r($query_search->posts);
Please Note: I have assumed the query string is accessed by s.
Code is tested and works.
Hope this helps!

Related

Adding together results of numbers from a WP_Query

I've got a custom post type in Wordpress, each post within it has a custom Number field (through Advanced Custom Posts).
When the page loads, I'm performing a query to find all the records that match these args:
$args = array(
'post_type' => 'hunters',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC' ,
'meta_key'=> 'full_ name',
'meta_value'=> $email,
'meta_key'=> 'w3w_location_hit',
'meta_value'=> $w3w
);
$loop = new WP_Query( $args );
I'd like to get the value of code_checks from each record returned in the query and add them all together as a total number - i.e. "there were N code checks made in total" on the page. Is there a way to get each separate value into an array and them add them together, please?
Thank you.
You don't even need to put them into an array - Something like this should work:
// set code checks back to 0
$code_checks = 0;
$args = array(
'post_type' => 'hunters',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC' ,
'meta_key'=> 'full_ name',
'meta_value'=> $email,
'meta_key'=> 'w3w_location_hit',
'meta_value'=> $w3w
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) {
// get code checks in this iteration
$number = get_field('code_checks');
// add this iteration to total
$code_checks = $code_checks + $number;
}
// echo total
echo 'There were ' . $code_checks . ' checks made in total';
/* Restore original Post Data */
wp_reset_postdata();

Ordering by multiple parameters in a custom WordPress query loop

I've implemented an infinite scroll and in search results upon ordering by price or any custom value it doesn't work.
Here inside my enqueued script:-
isset($_GET['orderby'])?$ga_order_by = $_GET['orderby']: $ga_order_by = '';//grabbing the orderby value
if( gettype($result) == 'object') {
$ga_wp_query = new \WP_Query([ 'post_type'=> ['product_variation', 'product'], 'post__in' => $includes, 'orderby' => ['post__in',$ga_order_by], 'order' => 'ASC' ]);//so i'm ordering by search results and dynamically grabbed value.
} else {
$ga_wp_query = new \WP_Query([ 'post_type'=> 'product', 'post__in' => $includes, 'orderby' => ['post__in',$ga_order_by], 'order' => 'ASC']);
}
$args['ga_search_posts'] = json_encode($ga_wp_query->query_vars);
Inside my ajax handling function call upon search:-
$search_query = json_decode( stripslashes( $_POST['search_posts'] ), true );//this is the $args['ga_search_posts'] i'm posting via my javascript
$search_query['post_status'] = 'publish';
$search_query['posts_per_page'] = get_option('posts_per_page');
$search_query['paged'] = $_POST['page'] + 1;
wc_set_loop_prop( 'total', $_POST['search_count'] );
add_filter( 'woocommerce_get_price_html', 'labtag_show_price' );
ob_start();
query_posts( $search_query);
if ( have_posts() ) {//product loop
if ( wc_get_loop_prop( 'total' ) ) {
while ( have_posts() ) {
the_post();
wc_get_template_part( 'content', 'product' );
}
}
}
$data = ob_get_clean();
die($data);
exit;
This works except if I try to order by any parameter say price etc. Can't 'orderby' => ['post__in',$ga_order_by] declared like an array?If not should I be passing all my posts ids to the ajax handler iterate them and sort them (if this is the case, how to handle my custom order_by params)?
https://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters
So, with WordPress' OrderBy, you have a couple of different options.
If you want both parameters to be sorted in the same direction of ASC or DESC, then the argument anticipates a single string, with the parameters separated by a space.
Multiple 'orderby' values Display pages ordered by 'title' and
'menu_order'. (title is dominant):
$args = array(
'post_type' => 'page',
'orderby' => 'title menu_order',
'order' => 'ASC',
);
$query = new WP_Query( $args );
You use an array when you are sorting each parameter differently:
Multiple 'orderby' values using an array
> Display pages ordered by 'title' and 'menu_order' with different sort
> orders (ASC/DESC) (available since Version 4.0):
$args = array(
'orderby' => array( 'title' => 'DESC', 'menu_order' => 'ASC' )
);
$query = new WP_Query( $args );
In your case, since you are using a variable, consider building the string and then using this within your arguments array, i.e.:
//start with a space, then .= to concatenate the $_GET parameter with the space if it's set, or clear the string if it's not.
$ga_order_by = " ";
isset($_GET['orderby'])?$ga_order_by .= $_GET['orderby']: $ga_order_by = '';
//grabbing the orderby value and building our complete string.
$orderBy = 'post__in'.$ga_order_by;
if (gettype($result) == 'object') {
$ga_wp_query = new \WP_Query([ 'post_type'=> ['product_variation', 'product'], 'post__in' => $includes, 'orderby' => $orderBy , 'order' => 'ASC' ]);//so i'm ordering by search results and dynamically grabbed value.
} else {
$ga_wp_query = new \WP_Query([ 'post_type'=> 'product', 'post__in' => $includes, 'orderby' => $orderBy, 'order' => 'ASC']);
}

$wpdb get_results - loop from specific category

I have this code, its working good, but its gets posts from all categories. I need to get posts only from category ID 2. I tried to add "AND term_taxonomy_id = 2" to my code, but this didint work. Can somebody help me with this, my code:
<?php //loops all posts
$my_query = $wpdb->get_results
("SELECT * FROM `{$table_prefix}posts`, {$table_prefix}postmeta
WHERE {$table_prefix}posts.post_status = 'publish'
AND {$table_prefix}posts.id = {$table_prefix}postmeta.post_id
AND {$table_prefix}postmeta.`meta_key` = 'wpcf-data-nuo' ORDER BY if({$table_prefix}postmeta.`meta_value` = '' or {$table_prefix}postmeta.`meta_value` is null,1,0), {$table_prefix}postmeta.`meta_value` ASC LIMIT 12");
foreach($my_query as $post) {
setup_postdata($post);
?>
Please follow below code, Hope! its working
You can define the meta key for orderby parameter using the old method (I tested on WP 3.1.1)...
query_posts(
array( 'post_type' => 'services',
'order' => 'ASC',
'meta_key' => 'some_key',
'orderby' => 'meta_value', //or 'meta_value_num'
'meta_query' => array(
array('key' => 'order_in_archive',
'value' => 'some_value'
)
)
)
);
OR
For me, I wanted to order by a numeric field and I had to use 'type' => 'NUMERIC' inside the meta query.
This issue in general is cleared up in WordPress 4.2 by using named queries. e.g.
$args = array(
'post_type' => 'services',
'orderby' => 'order_clause',
'meta_query' => array(
'order_clause' => array(
'key' => 'order_in_archive',
'value' => 'some_value',
'type' => 'NUMERIC' // unless the field is not a number
)));
Reference link for set the meta value in query: https://rudrastyh.com/wordpress/meta_query.html
You can do it by WP_QUERY instead writing custom Query.
The query to get the results and then your custom sort order by altering the WP_QUERY if default order parameters not work as expected.
$args = array(
'post_type' => 'post',
'posts_per_page' => 8,
'cat' => 2,
'meta_key' => 'wpcf-data-nuo',
'orderby' => 'meta_value_num',
'order' => 'ASC'
);
add_filter('posts_orderby', 'filter_query');
$q = new WP_Query($args);
remove_filter('posts_orderby', 'filter_query');
function filter_query( $orderby_statement ) {
global $table_prefix;
$orderby_statement .= " if({$table_prefix}postmeta.`meta_value` = '' ";
$orderby_statement .= " or {$table_prefix}postmeta.`meta_value` is null,1,0), {$table_prefix}postmeta.`meta_value`";
return $orderby_statement;
}
Note: Do not remove spaces from $orderby_statement .= because it require spaces while running query.
If it still doesn't work, then add var_dump($orderby_statement); before return $orderby_statement; then copy the SQL and add it in your question so it will help us to understand what is the issue.

How to render formatted post content in widget in Wordpress

I am new on wordpress and try to make a widget which will only show the last post of particuler category.
TO do this I have given some settings in admin to select category for which admin wants to display last post (post of last ID).
I am using the below code to in widget to display post content:
$query_arguments = array(
'posts_per_page' => (int) 1,
'post_type' => 'post',
'post_status' => 'publish',
'cat' => (int) $settings['category'],
'order' => 'DESC',
'orderby' => (($settings['display_by'] == 0) ? 'ID' : 'date')
);
$posts_query = new WP_Query( $query_arguments );
if ($posts_query->have_posts()) {
$posts = $posts_query->get_posts();
$post = $posts[0];
echo $post->post_content;
}
But the above code is showing content in one paragraph or you can say that without format. I have done lot of search and found that, I need to apply "the_content" filter to format the content. So I have done the same as below code:
if ($posts_query->have_posts()) {
$posts = $posts_query->get_posts();
$post = $posts[0];
$content = apply_filters('the_content', $post->post_content);
echo $content;
}
Now the above changes is returning the null string. I have google lot of things but everyone is saying that to use apply filter or use the_content() function. I have tried both solutions but nothing happening.
Can anyone please share the solution for this problem?
please check whether you are getting any text in $post->post_content
by echo $post->post_content
All you need to do is,
$query_arguments = array(
'posts_per_page' => (int) 1,
'post_type' => 'post',
'post_status' => 'publish',
'cat' => (int) $settings['category'],
'order' => 'DESC',
'orderby' => (($settings['display_by'] == 0) ? 'ID' : 'date')
);
$posts_query = new WP_Query( $query_arguments );
while ($posts_query->have_posts()) {
$posts_query->the_post();
echo get_the_content();
}

Why is WordPress showing query results from an empty post__in array?

I have the following WP_Query arguments:
$posts = new WP_Query(array(
'post__in' => $postids,
'meta_key' =>'ratings_average',
'orderby'=>'meta_value_num',
'order' =>'DESC',
));
$postids is an array of ids which is retrieved from another WP_Query. My problem here is that even if $postids is empty, Wordpress loop shows posts. How can I manage this that it shouldn't show any post if $postids is empty.
This isn't directly fixing the issue with post__in but I don't see why this wouldn't work..
if(!empty($postids)){
$posts = new WP_Query(array(
'post__in' => $postids,
'meta_key' =>'ratings_average',
'orderby'=>'meta_value_num',
'order' =>'DESC',
));
} else {
//Do something else or nothing at all..
}
as you can see the WP_Query call will only happen if $postids has value/s in it. if it doesn't, then no call is made to WP_Query and the loop will just never happen, same as if your query returned 0 posts.
As noted, wp devs don't want to fix this. Having said that, you could pass a non-empty array of invalid IDs, like this:
if(empty($postids)) {
$postids = ['issue#28099'];
}
$posts = new WP_Query(array(
'post__in' => $postids,
'meta_key' =>'ratings_average',
'orderby'=>'meta_value_num',
'order' =>'DESC',
));
Bad practice you say ? Yeah, I am not sure from whose side though ...
To keep the flow correct with the WP_Query. Use it like this:
$postIdArray = array(
1, 2, 3
);
$queryArgs = array(
'post_type' => 'any',
'post_status' => 'published',
'post__in' => ((!isset($postIdArray) || empty($postIdArray)) ? array(-1) : $postIdArray)
);
This way you will still be able to code against the WP_Query object.
For example:
$postIdArray = array(
1, 2, 3
);
$queryArgs = array(
'post_type' => 'any',
'post_status' => 'published',
'post__in' => ((!isset($postIdArray) || empty($postIdArray)) ? array(-1) : $postIdArray)
);
$postQuery = new \WP_Query($queryArgs);
$postCount = $postQuery->post_count;
$totalCount = $postQuery->found_posts;
Just got the same problem, best thing is to check if the array is empty then pass invalid ID to it:
if(empty($postids)){
$postids[]= 0;
}
Add that before the query and the problem is solved.
Maybe you have some sticky posts. In this case WordPress will add those posts to your query.
The solution is to set 'ignore_sticky_posts' => 1. Applying that to your code:
$posts = new WP_Query(array(
'post__in' => $postids,
'ignore_sticky_posts' => 1,
'meta_key' =>'ratings_average',
'orderby'=>'meta_value_num',
'order' =>'DESC',
));

Categories