Custom Field Search in Wordpress - php

I am looking for a way to filter my posts by custom fields,
for example this link:
mywebsite.com/?color:red
looks for all the post that has custom field named color and the value red
I will be appreciate it if you can help me, I searched all over internet and I got nothing.

I don't know if it's a typo but the example link you provided will not work. Query format is like this, ?property=value&another_property=another_value.
If your query is mywebsite.com/?color=red you can use the $_GET to get the value from the query and use it for what ever you need.
// check if we have a query property of color and that property has a value
if (isset($_GET['color']) && !empty($_GET['color'])) {
// filter the result and remove any spaces
$color = trim(filter_input(INPUT_GET, 'color', FILTER_SANITIZE_STRING));
// Create the arguments for the get_posts function
$args = [
'posts_per_page' => -1, // or how many you need
'post_type' => 'YOUR_POST_TYPE', // if the post type is 'post' you don't need this line
'post_status' => 'publish', // get only the published posts
'meta_query' => [ // Here we use our $_GET data to find all posts that have the value of red in a meta field named color
[
'key' => 'color',
'value' => $color,
'compare' => '='
]
]
];
$posts = get_posts($args);
}
if (!empty($posts)) {
// Now you can loop $posts and do what ever you want
}
Hope this helps =].
EDIT
Answering your question about getting posts with multiple meta values.
if ((isset($_GET['color']) && !empty($_GET['color'])) && (isset($_GET['size']) && !empty($_GET['size']))) {
// filter the result and remove any spaces
$color = trim(filter_input(INPUT_GET, 'color', FILTER_SANITIZE_STRING));
$size = trim(filter_input(INPUT_GET, 'size', FILTER_SANITIZE_STRING));
// Create the arguments for the get_posts function
$args = [
'posts_per_page' => -1, // or how many you need
'post_type' => 'YOUR_POST_TYPE', // if the post type is 'post' you don't need this line
'post_status' => 'publish', // get only the published posts
'meta_query' => [ // now we are using multiple meta querys, you can use as many as you want
'relation' => 'OR', // Optional, defaults to "AND" (taken from the wordpress codex)
[
'key' => 'color',
'value' => $color,
'compare' => '='
],
[
'key' => 'size',
'value' => $size,
'compare' => '='
]
]
];
$posts = get_posts($args);
}
if (!empty($posts)) {
// Now you can loop $posts and do what ever you want
}

You can use the ACF-fields in a Meta Query like this:
$posts = get_posts(array(
'numberposts' => -1,
'post_type' => 'post',
'meta_key' => 'color',
'meta_value' => 'red'
));
There are more examples in the ACF documentation:
https://www.advancedcustomfields.com/resources/query-posts-custom-fields/#custom-field%20parameters

Related

WordPress - WP_QUERY limit findings to posts with exact same values

I am facing some issues with my custom taxonomies in one of my custom post types : I have a page that retrieves my custom posts that have the same taxonomy fields as the page.
For example, one of the custom taxonomies shared between the page and the CPT is 'categorie'. Using a tax_query field in a WP_QUERY, I am able to retrieve the posts that do have the same categorie fields checked as my page's, but I can't seem to find how to get posts that have the EXACT same values.
Here are some visuals in case you're confused :
Page taxonomy with values checked
CPT taxonomy with values checked
So they both have the 'chauffage' value checked and no other one.
Let's say now that I have an other custom post that has 'chauffage' checked, but also 'sanitaire'. How do I tell my WP_QUERY not to retrieve it ?
I've tried to use the operator 'AND' inside of my tax_query array (since it is 'IN' by default) but it didn't work.
The idea I had now was to retrieve all of the taxonomy values and say that the unchecked ones use the operator 'NOT IN', which would work I guess if only I managed to do so. I am only able to get the checked ones, even when using wp_get_post_terms with 'hide_empty' set to 0.
Here's my code :
$page_id = $wp_query->get_queried_object()->ID;
$page_category = wp_get_post_terms($page_id, 'categorie', array(
'hide_empty' => 0
));
// var_dump($page_category);
$page_client = wp_get_post_terms($page_id, 'client', array(
'hide_empty' => 0
));
if($page_category) {
$buffer = array();
foreach ($page_category as $category) {
array_push($buffer, $category->slug);
}
$page_category = $buffer;
}
// var_dump($page_client);
if($page_client) {
$buffer = array();
foreach ($page_client as $client) {
array_push($buffer, $client->slug);
}
$page_client = $buffer;
}
$tax_query = array(
'relation' => 'AND'
);
array_push($tax_query, array(
'taxonomy' => 'categ_article_activite',
'field' => 'slug',
'terms' => $page_category,
'operator' => 'AND'
));
// var_dump($page_client);
array_push($tax_query, array(
'taxonomy' => 'client_article_activite',
'field' => 'slug',
'terms' => $page_client,
'operator' => 'AND'
));
// var_dump($tax_query);
$args = array(
'post_type' => 'article_activite',
'meta_key' => '_article_principal',
'posts_per_page' => 1,
'meta_value' => 'on',
'tax_query' => $tax_query,
'order' => 'ASC'
);
$query = new WP_Query($args);
EDIT : I forgot to mention, I also thought about using the operator 'NOT IN' for the values I do not want to retrieve but since the people that are going to use the website may add taxonomy values, it would require to go in the code add this specific value which is not an option

Wordpress posts count with comman tags within specific category

i have two categories 'A' and 'B'. Both have 5 posts(each) with tag 'C'. How i can display the number of posts as 5 in Category 'A' or 'B' page. It showing total number of post with tag 'C' as 10. I need to show it as 5. How i can pass category variable to display exact count with tag within specific category. Here is my current code:
$tag = get_term_by('name', $tags,'post_tag');
$count = $tag->count;
reference: https://codex.wordpress.org/Function_Reference/get_term_by
This is not possible with the get_term_by() method.
Try this:
$args = array(
'posts_per_page' => -1,
'tax_query' => array(
'relation' => 'AND', // only posts that have both taxonomies will return.
array(
'taxonomy' => 'post_tag',
'field' => 'name',
'terms' => 'TAG_C', // you can also use an array with tags.
),
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'CATEGORY_B', // you can also use an array with categories.
),
),
);
$posts = get_posts($args);
$count = count($posts);
I haven't tested this code, but it should work. Ofcourse you do have
to set the correct terms.
UPDATE
When dealing with many posts I would create a $wpdb sql query that counts the rows, so only a number is returned and not all the posts. You can find an sql count example here.
You can use "found_posts" property of the WP_Query class object.
$args = array(
'posts_per_page' => 10,
'category_name' => 'aaa', // category slug
'tag' => 'ccc' // tag slug
);
$wp_query = new WP_Query( $args );
echo "Total posts count: ".$wp_query->found_posts;

$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.

Use ACF checkbox value array to find "More like this"

I'm using an ACF checkbox to designate categories (called "aims") for Psychology apps/sites. So values would be, say, "Mindfulness", "Well-Being" and "Depression".
Since it's possible to select multiple values, what I'd like to do is have a More Like This where any single post could show other posts that match one or more of the categories of the post.
UPDATE: Here's the code I'm using now, which I'm still not having any luck with:
the_field( 'aims'); /* since I'm on the page for a single post, this gives me the aims for the current post and is currently returning values from the checkbox with multiple selections (as an array, I believe) */
$args = array(
'numberposts' => -1,
'post_type' => 'program',
'post_status' => 'publish',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'aims',
'value' => 'Well-Being', /* I'd actually like this to use the aims for the current post, but I've hard-coded for testing, and am not seeing any results */
'compare' => 'IN')
));
$more_like_this = new WP_Query ($args);
while ($more_like_this->have_posts()) : $more_like_this->the_post();
$star_rating = get_field('overall_score');
?>
<?php the_title(); ?>
<?php echo $star_rating ?>
<?php endwhile;
wp_reset_query();
?>
If you need a wp query to select some posts where multiple ACF checkbox options must be checked you can do like this:
// Get the array with selected options
$fields = get_field('somefield');
// First create the meta_query variable (AND can also be OR)
$meta_query = array('relation' => 'AND');
foreach( $fields as $field ){
$meta_query[] = array(
'key' => 'name_of_acf_checkbox_here',
'value' => $aim,
'compare' => 'LIKE',
);
}
// args
$args = array(
'numberposts' => -1,
'post_type' => 'postype_here',
'meta_query' => $meta_query,
);
$the_query = new WP_Query( $args );

Display "Related Posts" based on ACF Relationship Field

I want to display "Related posts" of a single post page with custom post type named 'property' which is using the ACF Relationship Field for another custom post type.
That other post type is 'contact' and in the Single Properties post type, the relationship field is calling out for that. I have been trying to understand ACF's documentation here, but I was not able to really comprehend why my code isn't working.
I need to show related properties based on the brokers. I don't fully understand SQL statements and table joining.
$properties = get_posts(array(
'post_type' => 'property', // Page Custom Post Type
'posts_per_page' => 6,
'meta_query' => array(
// 'relation' => 'AND',
// array(
'key' => 'contact', // Field name with 2nd custom post type, 'contact'
'value' => '"' . get_the_ID() . '"',
'compare' => 'LIKE'
// )
)
));
Turns out the reason that this was messed up was due to the way ACF stored the array. Their documentation, while it works for their case, was off in mine due to a nester array.
This is what worked for me.
// This is the start of figuring out the array issue
$contact = get_field( 'contact' );
// This showed me the first array
$contact_array = $contact[0];
// This showed me the ACF array and allowed me to return the ID
$contact_ID = $contact_array->ID;
$properties = get_posts(array(
'post_type' => 'property',
'posts_per_page' => 6,
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'contact',
// Had to call the value like this as the array was nested like
// a:2:{i:0;s:3:"123";i:1;s:3:"321";} or something.
'value' => '"' . $contact_ID . '"',
'compare' => 'LIKE'
)
)
));
A more complex query with an additional taxonomy called medienform
// Shortcode for ACF - Add Relationship ACF field [sc_acf_fields]
//
add_shortcode( 'sc_acf_fields', 'related_relationship' ); // Add your shortcode here
function related_relationship() {
// get the taxonomy medienform
$cat_taxonomies = get_terms( 'medienform', $args );
$count = count($cat_taxonomies); // wird nicht verwendet
//
/// foreach category as $form_category - medienform
//
foreach ( $cat_taxonomies as $form_category ):
// check the arguments of the post_type, orderby
$args =array(
'posts_per_page' => -1,
'post_type' => 'materialien', // the CPT
'orderby' => 'title', // menu_order
'order' => 'ASC', // DESC
'tax_query' => array( // the tax_query is important to list the posttypes to its taxonomies
'relation' => 'AND',
array(
'taxonomy' => 'medienform',
'field' => 'slug',
'terms' => $form_category->slug
)
),
'meta_query' => array( // the meta_query is important to list only the related posts of the key
array(
'key' => 'post-relationship', // name of custom field Relationship in: https://qualitaetsoffensive-teilhabe.de/wp-admin/post.php?post=12067&action=edit&classic-editor=1
'value' => '"' . get_the_ID() . '"', // matches exactly "123", not just 123. This prevents a match for "1234"
'compare' => 'LIKE'
)
),
);
//
// make an own WP_Query from the $args
$materials = new WP_Query( $args );
//
// let´s give the category ->name here and the term_link().
// actually a category should only be displayed when it has some child // here we build the accordeon
//
if ($materials->have_posts() ) {
echo '<h4>' . $form_category->name . '</h4>';
};
//
// while schleife
while ( $materials->have_posts() ) {
//
//// use variable as the_post() query
$materials->the_post();
?>
<div class="post-loop-single">
<div class="thumbnail-img"><span><?php the_post_thumbnail('post-thumb'); ?> </span></div>
<div class="post-loop">
<div class="post-loop-title"><?php the_title(); ?></div>
</div>
</div>
<?php } wp_reset_query();
endforeach;

Categories