Custom wordpress PHP Api - php

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.

Related

Is it logical to get Wordpress article id with PHP API

I have a custom wordpress php rest api. The API has 2 functions. The first function is returning all posts from the wordpress website. Second function is returning posts by slug.
I have developing mobile app for the website(blog website). I am getting datas for the app.
And I have some anxiety here. I am getting a lot of datas about articles and one of these is article Id.
The question: Is it logical to get wordpress article id with php api. I am asking for security.
1-The api is my custom api for get datas about article.
2-If I don't use the custom php api, I will use the mysql database for save the article informations. And I will get the article datas with php api. But I will set my own id for article(I won't use the wordpress article id).
Which one is the best way to use. Please think for security.
This is my custom PHP API function.
function api_posts()
{
$args = [
'numberposts' => 99999,
'post_type' => 'post',
];
$posts = get_posts($args);
$data = [];
$i = 0;
foreach ($posts as $post) {
$category = get_the_category( $post->ID )[0]->name;
$data[$i]['category'] = $category;
$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]['featured_image']['thumbnail'] = get_the_post_thumbnail_url($post->ID, 'thumbnail');
$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');
setlocale(LC_TIME, array('tr_TR.UTF-8','tr_TR.UTF-8','tr_TR.UTF-8','tr_TR.UTF-8'));//tarihi esas alan locali seçer
$gelen_date = $post->post_date;
$data[$i]['date'] = strftime("%e %B %Y",strtotime($gelen_date));
$data[$i]['post_url'] = get_permalink($post->ID);
$i++;
}
return $data;
}
add_action('rest_api_init', function () {
register_rest_route('api/v1', 'posts', [
'methods' => 'GET',
'callback' => 'api_posts',
]);
register_rest_route('api/v1', 'posts/(?P<slug>[a-zA-Z0-9-]+)', array(
'methods' => 'GET',
'callback' => 'api_post',
));
});
Footnote: The website is not ready to publish. I am using free wordpress blog theme for the test. But I will use the jannah theme when I publish my website.
Post ID values are visible to visitors to a WordPress site. (They show up in places like HTML element classes. Do View Source on a page showing posts and you'll see this.)
So if your reason for using an alternative ID is to avoid disclosing post ID values (maybe for security reasons) don't bother. They are already available.
Plus, if you use an alternative ID you'll probably need to store it as a post attribute in wp_postmeta in your database. That is, putting it mildly, not the best-performing part of WordPress.

How to get all custom field values for specific field for custom post type WordPress

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;

Query all wordpress post titles

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 :) )

Search Wordpress Magic Fields items? No search results

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.

How to fix this WordPress function so that it doesn't return a 404 page?

I have the following function that I've added to my functions.php file in WordPress. The idea is that it gathers all of the titles of 'fsmodel' posts (a custom post type that I've created). It then returns these as an array, which I then use to populate a select tag in the custom meta fields for a second custom post type.
Basically, 'fsmodel' will have posts with a boat model, and the 'fsboat' post type will have a drop-down with the names of each of the models to select from.
Now, this appears to works fine in the Dashboard - the drop-down is populated as expected. When I save, however, the post doesn't show up in the Edit list. Also on the website, all pages output as the 404 error page when this function is active.
I'm certain that the problem lies within the following code - does anyone have any idea what I might have done wrong?
function fs_model_array() {
$models_array = array();
$loop = new WP_Query(array(
'post_type' => 'fsmodel',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
'post_status' => 'publish'
));
while ( $loop->have_posts() ) : $loop->the_post();
$models_array[] = get_the_title();
endwhile;
return $models_array;
};
OK, I've come up with a solution (I hope - it's holding up for now).
Instead of creating a loop, I've just used the $wpdb->get_results to search the database for the column with a WHERE filter for the custom post type.
Then run an array builder:
$models_array = array();
$model_db = $wpdb->get_results("SELECT post_title FROM $wpdb->posts WHERE post_type='fsmodel' AND post_status = 'publish'");
foreach ($model_db as $model_db) {
$models_array[] = $model_db->post_title;
}
Thanks again for your time, hsatterwhite! :-)
I think you might find that adding wp_reset_query() to the end of your function will solve your problems :)
I like your solution, but I'd be inclined to say that you need to call the global variable of $post whenever you use the loop like this in a function, as it assigns it to that variable.
function fs_model_array(){
global $post;
$models_array = array();
$loop = new WP_Query(array(
...

Categories