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,
    );
}
?>