I have built a wordpress site that uses magic fields almost exclusively (rather than default posts etc).
However, I am now trying to implement search functionality and finding that wordpress is not able to find any content that is created by Magic Fields.
I have altered my search to create a custom WP_Query, but am still not having any luck. For example, I have a post_type of 'project':
$searchValue = $_GET['s'];
$args = array(
'post_type' => 'project',
'posts_per_page' => -1,
'meta_value' => $searchValue,
'meta_key' => 'title'
);
$query = new WP_Query($args);
This returns no results. Where am I going wrong?
Many thanks in advance!
I too have had problems with magic field and the wordpress search. The standard wordpress search only searches the post box content. The way to handle searching through magic field content is to search the postmeta.
$add_value = true;
$query_array = array();
$query_for_posts = "page_id=";
$search_guery = $_GET['s'];
$search_results = $wpdb->get_results("SELECT * FROM ".$wpdb->prefix."postmeta WHERE meta_value LIKE '%" . $search_guery ."%' ORDER BY post_id");
if(!empty($search_results))
{
foreach ($search_results as $search_result)
{
//loop through results
for($i=0;$i<sizeof($query_array);$i++)
{
//check if post id in the array
if($search_result->post_id == $query_array[$i])
$add_value = false;
}
if($add_value)
{
//add the post id to the array if not a duplicate
array_push($query_array, $search_result->post_id);
//also add id for WP_Query
$query_for_posts .= $search_result->post_id . ",";
}
$add_value = true;
}
}
then to display the results.
if(!empty($query_array))
{
for($i=0;$i<sizeof($query_array);$i++)
{
//get post from array of ids
$post = get_page($query_array[$i]);
//make sure the post is published
if($post->post_status == 'publish')
echo '<h3>'.$post->post_title.'</h3>';
}
}
else
{
//tell the user there are no results
}
you can also use the $query_for_posts variable in a WP_query. It should have the value page_id=1,3,7,9,23... all the post ids from the search results.
Related
I have an app for wordpress blog site. this app getting wordpress articles with php api call.
I am using this code for get article list.
function api_posts()
{
$args = [
'numberposts' => 99999,
'post_type' => 'post',
];
$posts = get_posts($args);
$data = [];
$i = 0;
foreach ($posts as $post) {
$data[$i]['id'] = $post->ID;
$data[$i]['title'] = $post->post_title;
$data[$i]['excerpt'] = $post->post_excerpt;
$data[$i]['content'] = $post->post_content;
$data[$i]['slug'] = $post->post_name;
$data[$i]['thumbnailImage'] = get_the_post_thumbnail_url($post->ID, 'thumbnail');
$data[$i]['mediumImage'] = get_the_post_thumbnail_url($post->ID, 'medium');
$data[$i]['largeImage'] = get_the_post_thumbnail_url($post->ID, 'large');
$data[$i]['date'] = $post->post_date;;
$data[$i]['post_url'] = get_permalink($post->ID);
$i++;
}
return $data;
}
I am getting ID, post_excerpt, post_content and others. So I am getting 10 information about one article. But I want to get more than 10 information about one artice. But I don' know the keys to get informations. For example I want to get article category. How can I do this. Where can I learn keys like post_title, post_excerpt. I know developers.wordpress but I don't understand it.
This is my custom wordpress api result
https://meshcurrent.online/wp/wp-json/api/v1/posts/
EDIT
Here's 1 more re-write but with a query as for some strange reason get_post_meta was not giving all the meta data as it used to before:
function api_posts(){
global $wpdb;
$posts_with_meta = $wpdb->get_results(
"SELECT *
FROM $wpdb->posts INNER JOIN $wpdb->postmeta
on $wpdb->posts.`ID` = $wpdb->postmeta.`post_id` where $wpdb->posts.`post_type` = 'post'
"
);
return $posts_with_meta;
}
OLD ANSWER
Here's how you can get all the meta keys and their values of all the posts:
function api_posts()
{
$args = [
'numberposts' => 99999,
'post_type' => 'post',
];
$posts = get_posts($args);
$data = [];
$i = 0;
foreach ($posts as $post) {
$allPostMeta = get_post_meta($post->ID);
foreach($allPostMeta as $key => $value) {
$data[$i][$key] = $value[0];
}
$i++;
}
return $data;
}
I've just done a re-write of your code to get you all the keys with their data. I can't test or replicate it as it's specific to your environment but I'm sure it'll work just fine for you.
Some keys might differ for your blog app and the website WordPress it's called post_title but your app reads it as the title. You'll need to work around that. But this will pretty much give you a list of all meta keys applicable to a post and you can then play around with your code and add only those keys which you need.
Once you know the fields you want in the API, You must also checkout WP_QUERY as that is more powerful and has a fields filter which can give you only those fields that you need for the app and not push all the data. Thus, saving API response time.
I hope this will help you.
I don't think there is any function available to return all data. You'll have to collect all the data manually.
If you're interested in getting categories and tags then you'll have to use wp_get_post_terms function to get the terms objects array and then loop through values and get the names/slugs/term_id etc.
If you're interested in metadata, then you'll have to use get_post_meta function to get meta data using meta keys.
I will try to explain my question as best for the community as I can.
I have a custom post type in WordPress named "people" (which is the slug).
Each post type belonging to "people" has an Advanced Custom Field associated with it, simply named "number". The field type is a number.
Here is what I want to achieve:
I want to get the values for number for all the posts, on a foreach for example, that carries on for as many posts there are.
I then want to add all of these values up to produce a total.
I know how to handle the calculations in PHP, that's not an issue.
Can you please advice on the best way to collect all the numbers in the custom fields for all posts, and how to store them in order to calculate the total.
Thank you.
You can use the get_posts() (wordpress builtin method) to get all posts from that post type like this:
$args = array( 'post_type' => 'people',
'posts_per_page' => -1
);
$posts = get_posts($args);
Then you can do a foreach loop through all of the posts like this:
if(!empty($posts))
{
$total = 0;
foreach($posts as $p)
{
$total += get_field('number', $p->ID);
}
}
One way that I can think of is to get all posts for people post type and then get the field data.
The approach for that will be some thing like:
$peoplePosts = get_posts(
array(
'post_type' => 'people',
'posts_per_page' => -1
));
$sum = 0;
print_r(peoplePosts);
if (is_array($peoplePosts)) {
foreach ( $peoplePosts as $peoplePost) {
$currentVal = get_field('number', $peoplePost->ID);
$sum = (float) $sum + (float) $currentVal;
}
}
echo $sum;
I have a custom post type called reservation. In it I get the reservation for event/room you name it (not important).
When I go to my custom post type page, I get all the posts nicely displayed. The first column is the reservation date. Now the reservation date can be one - 28.11.2015, but it can also be multiple dates - 28.11.2015, 29.11.2015, 02.12.2015.
I would like to enable the sorting of that column. The problem is, this is a string, not a number so I cannot just create a simple sortable column query like described here.
So far I tried this:
add_filter( 'manage_edit-reservation_sortable_columns', 'reservation_sortable_column' );
if (!function_exists('reservation_sortable_column')) {
function reservation_sortable_column( $columns ) {
$columns['reservation_date'] = 'reservation_date';
return $columns;
}
}
add_filter( 'posts_clauses', 'manage_wp_posts_be_qe_pre_get_posts', 1, 2 );
if (!function_exists('manage_wp_posts_be_qe_pre_get_posts')) {
function manage_wp_posts_be_qe_pre_get_posts( $pieces, $query ) {
global $wpdb;
if ($query->is_main_query() && ( $orderby = $query->get('orderby') ) ) {
$order = strtoupper( $query->get('order') );
if ( !in_array( $order, array('ASC', 'DESC') ) ) {
$order = 'ASC';
switch ($orderby) {
case 'reservation_date':
$pieces[ 'join' ] .= " LEFT JOIN $wpdb->postmeta wp_rd ON wp_rd.post_id = {$wpdb->posts}.ID AND wp_rd.meta_key = 'reservation_date'";
$pieces[ 'orderby' ] = "STR_TO_DATE( wp_rd.meta_value,'%d.%m.%Y' ) $order, " . $pieces[ 'orderby' ];
break;
}
}
return $pieces;
}
}
}
This doesn't work, because I'm working with strings.
Luckily, my dates (when a person picks them), are already sorted lowest to highest date. They are stored in $custom['reservation_date'] array, where $custom = get_post_custom($post->ID). So I can get them like $custom['reservation_date'][0].
I can also separate the first date
preg_match('/^(.+?),/', $custom['reservation_date'][0], $matches);
If it's only one date, without the comma, I can then get them out like:
$first_date = (!empty($matches)) ? $matches[0] : $custom['reservation_date'][0];
Now what's bothering me is how to use this in my custom query? Currently the sorting is done on meta_value reservation_date (string). How do I make it so that I can sort based on these first dates?
Say I have dates like:
19.11.2015, 20.11.2015
28.11.2015
14.11.2015, 15.11.2015
13.11.2015
When I click to sort them in ascending order I'd like to get
13.11.2015
14.11.2015, 15.11.2015
19.11.2015, 20.11.2015
28.11.2015
And another click on the column will order them descending
28.11.2015
19.11.2015, 20.11.2015
14.11.2015, 15.11.2015
13.11.2015
Any help is appreciated.
You will not be able to sort in the WP Query as you have not stored the values in a way WordPress understands.
https://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters
You should store dates as YYYY-mm-dd.
Either change how the dates are stored or use PHP after the database request to sort.
// 1. if you change how "reservation_date" is stored in the db
$posts = get_posts(array(
'posts_per_page' => -1,
'post_type' => 'reservation',
'meta_key' => 'reservation_date',
'orderby' => 'meta_value',
'order' => 'ASC'
));
// 2. if you choose to sort with PHP after pulling the data
$posts = get_posts(array(
'posts_per_page' => -1,
'post_type' => 'reservation'
));
usort($posts, function ($post_a, $post_b) {
$post_a_custom = get_post_custom($post_a->ID);
$post_b_custom = get_post_custom($post_b->ID);
$post_a_date = DateTime::createFromFormat('d.m.Y', $post_a_custom['reservation_date'][0]);
$post_b_date = DateTime::createFromFormat('d.m.Y', $post_b_custom['reservation_date'][0]);
if ($post_a_date == $post_b_date) {
return 0;
} else if ($post_a_date > $post_b_date) {
return -1;
} else {
return 1;
}
});
I've set up a custom search to use the s GET variable on a URL. I want it to fetch certain results but I've come across an odd problem. First, here's my code:
$search_term = $_GET['s'];
if($search_term!=''){
$s = new WP_Query(array('s' => $search_term));
$search_array = array();
if($s->have_posts()){
while($s->have_posts()){
$s->the_post();
$title = get_the_title();
$permalink = get_permalink();
$search_identifier = $title.$permalink;
array_push($search_array,$search_identifier);
}
}
}
Essentially, I'm creating an array of unique values for each post because I need to use them for a function immediately after that.
I have a post titled 'Kitchen Assistant.' When I search 'kitchen', it shows up. When I search 'assistant' it does not show up.
I have other posts with the word 'assistant' in the title and content and those show up when I search 'assistant'. I'm curious as to why it would show up with one search term and not the other?
I've used var_dump($s) and the post is in the dump when I search 'assistant' but not when I search 'kitchen.'
Any help would be greatly appreciated. Thanks!
Try this.
$search_term = $_GET['s'];
if(!empty($search_term)){
$args = array(
'post_type' => 'post',
'meta_query' => array(
'key' => 'title',
'value' => $search_term,
'compare' => 'LIKE'
)
);
$s = new WP_Query($args);
$search_array = array();
if($s->have_posts()){
while($s->have_posts()){
$s->the_post();
$title = get_the_title();
$permalink = get_permalink();
$search_identifier = $title.$permalink;
array_push($search_array,$search_identifier);
}
}
}
I figured out the answer to my own question (finally!). I'm using the NineToFive template and I guess by default there's a limit on the number of search results that's returned (I'm not sure if that's a WordPress default; maybe someone can clarify that).
I changed my query to this:
$s = new WP_Query(array('s' => $search_term, 'posts_per_page' => -1));
To not put a limit on the search results and that changed it. I needed to find every possible search term on page 1 in order to cross reference it with the location but it was 'paginating' the search results in search query end of it.
Thanks for the help!
I am using Wordpress auto suggests using this snippet of code
and currently it is searching all tags, I want it to search only post titles. Any help is appreciated.
This is sql query calling all the tags which needs to be modified for all posts.
<?php global $wpdb;
$search_tags = $wpdb->get_results("SELECT name from wp_terms WHERE name LIKE '$search%'");
foreach ($search_tags as $mytag)
{
echo $mytag->name. " ";
}
?>
These days i had to do some request in a wordpress theme.
In your case ( getting title can be done easier than getting tags, as in your example link ) the stuff can be done easier (i guess).
Firstly you have to make a php page to get posts. As you maybe know you won't be able to use wp stuff in standalone php files, so your file ( let call it get_posts.php ) will look like
<?php
// Include the file above for being able to use php stuff
// In my case this file was in a folder inside my theme ( my_theme/custom_stuff/get_posts.php ).
// According to this file position you can modify below path to achieve wp-blog-header.php from wp root folder
include( '../../../../wp-blog-header.php' );
// Get all published posts.
$list_posts = get_posts( array( 'numberposts' => -1 ) );
// Get "q" parameter from plugin
$typing = strtolower( $_GET["q"] );
//Save all titles
$list_titles = array();
foreach( $list_posts as $post ) { $list_titles[] = $post->post_title; }
// To see more about this part check search.php from example
foreach( $list_titles as $title ) {
if( strpos( strtolower( $title ), $typing ) ){
echo $title;
}
}
?>
I added some comments trying to help you better.
Now stuff get easy, you only have to call your page through jQuery plugin like
$('#yourInput').autocomplete( "path_to/get_posts.php" );
You can directly use wordpress in-build feature to get all post titles
// The Query
query_posts( 'posts_per_page=-1' );
// The Loop
while ( have_posts() ) : the_post();
echo '<li>';
the_title();
echo '</li>';
endwhile;
None of the answers here answer your real question:
How to query JUST post titles
The "raw SQL" way:
Few important things:
escape search for SQL! (also do that for the tags search!) use $GLOBALS['wpdb']->esc_like()
if you only need 1 column, you can use $GLOBALS['wpdb']->get_col()$GLOBALS['wpdb']->get_results() is if you want to fetch more columns in one row
use $GLOBALS['wpdb']->tableBaseName to make your code portable - takes care of the prefixe.g. $GLOBALS['wpdb']->posts
When querying posts you must also think about which post_type and post_status you want to query=> usually the post_status you want ispublish, but post_type may vary based on what you want
WordPress table "posts" contains ALL post types - post, page, custom, but also navigation, contact forms etc. could be there! => I strongly advice to use explicit post_type condition(s) in WHERE ! :)
...$GLOBALS is same as globalizing variabl -today performance difference is little
<?php
// to get ALL published post titles of ALL post types (posts, pages, custom post types, ...
$search_post_titles = $GLOBALS['wpdb']->get_col(
"SELECT post_title from {$GLOBALS['wpdb']->posts}
WHERE (
(post_status = 'publish')
AND
(post_title LIKE '{$GLOBALS['wpdb']->esc_like($search)}%')
)
ORDER BY post_title ASC
"); // I also added ordering by title (ascending)
// to only get post titles of Posts(Blog)
// you would add this to conditions inside the WHERE()
// AND (post_type = 'post')
// for Posts&Pages
// AND ((post_type = 'post') OR (post_type = 'page'))
// test output:
foreach ($search_post_titles as $my_title) {
echo $my_title . " ";
}
?>
The WP_Query way
This is more wordpress but has a little overhead, because although there is a fields param for new WP_Query()/get_posts(), it only has options:
'all' - all fields (also default), 'ids' - just ids, 'id=>parent' - ... if you pass anything else, you still get all, so you still need to add "all" BUT - WP however has filters for altering fields in SELECT.
I tried to make it the same as the raw SQL version, but it depends on how does WP does it's "search" - which I think is %search% for 1 word + some more logic if there are more words. You could leverage the $clauses filter used for fields to also add your custom where INSTEAD of adding the 's' into $args (remember to append to not-lose existing WHEREs $clauses['where' .= "AND ...;). Also post_type => 'any' does not produce always the same results as the raw query in cases like Navigation, Contact forms etc...
Also WP_Query sanitizes the input variables so actually don't escape $args!
<?php
$args = [
'fields' => 'all', // must give all here and filter SELECT(fields) clause later!
'posts_per_page' => -1, // -1 == get all
'post_status' => 'publish',
's' => $search,
// I also added ordering by title (ascending):
'orderby' => 'title',
'order' => 'ASC',
'post_type' => 'any', // all "normal" post types
// 'post_type' => 'post', // only "blog" Posts
// 'post_type' => ['post', 'page'], // only blog Posts & Pages
];
$onlyTitlesFilter = function($clauses, $query) {
// "fields" overrides the column list after "SELECT" in query
$clauses['fields'] = "{$GLOBALS['wpdb']->posts}.post_title";
return $clauses; // !FILTER! MUST RETURN!
};
$onlyTitlesFilterPriority = 999;
// add filter only for this query
add_filter('posts_clauses', $onlyTitlesFilter, $onlyTitlesFilterPriority, 2);
// Pro-tip: don't use variable names like $post, $posts - they conflict with WP globals!
$my_posts = (new WP_Query($args))->get_posts();
// !IMPORTANT!
// !remove the filter right after so we don't affect other queries!
remove_filter('posts_clauses', $onlyTitlesFilter, $onlyTitlesFilterPriority);
// test output:
// note that I used "my"_post NOT just $post (that's a global!)
foreach($my_posts as $my_post) {
echo $my_post->post_title . " ";
}
?>
Don't be confused - you will still get the array of WP_Posts - WP will throw some default properties&values into it, but in reality it will only query and fill-in with real values the fields you specify in the filter.
PS: I've tested these - they are working codes (at least on WP 5.4 and PHP7 :) )