File: /var/www/linde/wp-content/plugins/lindevr-site-plugin/faqs/rest/articles.php
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Register a custom API endpoint to fetch Platform articles.
*/
function linde_register_platform_articles_endpoint() {
register_rest_route('platform/v1', '/articles', array(
'methods' => 'GET',
'callback' => 'linde_get_platform_articles',
'permission_callback' => '__return_true'
));
}
add_action('rest_api_init', 'linde_register_platform_articles_endpoint');
/**
* Main function to get platform articles
* Handles fetching articles with optional search, tag filtering, and pagination.
* When searching, prioritizes title matches followed by content matches, both sorted by custom order.
*/
function linde_get_platform_articles($data) {
$search = isset($data['search']) ? sanitize_text_field($data['search']) : '';
$tags = isset($data['tags']) ? sanitize_text_field($data['tags']) : '';
$page = isset($data['page']) ? absint($data['page']) : 1;
$per_page = 15;
// No search term: Perform a single query with standard filtering
$args = linde_get_platform_query_args($search, $tags, $page, $per_page);
$query = new WP_Query($args);
remove_all_filters('posts_orderby');
$articles = array();
while ($query->have_posts()) {
$query->the_post();
$post_id = get_the_ID();
// Get the tag names
$tags = wp_get_post_tags($post_id, array('fields' => 'names'));
$post_data = array(
'id' => $post_id,
'title' => get_the_title(),
'featured_image' => get_api_image_renditions($post_id),
'tags' => $tags
);
$articles[] = $post_data;
}
$pagination = linde_get_pagination_data($query, $page, $per_page);
// Get FAQ tags used for filtering articles on platform (3 tags above the list as per design)
$faq_tags_results = get_field('faq_tags', 'option');
$faq_tags = [];
foreach ( $faq_tags_results as $tag ) {
$faq_tags[] = [
"id" => $tag->term_id,
"name" => $tag->name
];
}
$response = array(
'faq_tags' => $faq_tags,
'articles' => $articles,
'pagination' => $pagination,
);
return rest_ensure_response($response);
}
/**
* Builds WP_Query arguments for platform articles
* Filters posts to include only those with post_visibility set to "lva-platform" or "everywhere"
*/
function linde_get_platform_query_args($search, $tags, $page, $per_page) {
$args = array(
'post_type' => 'linde_faq',
'post_status' => 'publish',
'posts_per_page' => $per_page,
'paged' => $page,
'meta_query' => array(
array(
'key' => 'post_visibility',
'value' => array('lva-platform', 'everywhere'),
'compare' => 'IN',
),
),
'orderby' => 'date',
'order' => 'DESC',
);
if (!empty($search)) {
global $wpdb;
$safe_search = esc_sql($search);
$like = '%' . $wpdb->esc_like($safe_search) . '%';
add_filter('posts_orderby', function($orderby) use ($wpdb, $like) {
// Create a relevance score: 2 points for title match, 1 for content
$relevance = "
{$wpdb->posts}.post_title LIKE '{$like}'
";
// Order by relevance DESC first, then menu_order ASC
return "{$relevance} DESC, {$wpdb->posts}.date ASC";
});
// Add the search query
$args['s'] = $search;
}
if (!empty($tags)) {
$tag_array = explode(',', $tags);
$args['tax_query'] = array(
array(
'taxonomy' => 'post_tag',
'field' => 'term_id',
'terms' => $tag_array,
'operator' => 'IN',
)
);
}
return $args;
}
/**
* Gets pagination data from WP_Query
*/
function linde_get_pagination_data($query, $current_page, $per_page) {
return array(
'current_page' => $current_page,
'per_page' => $per_page,
'total_posts' => (int) $query->found_posts,
'total_pages' => (int) $query->max_num_pages,
);
}
?>