HEX
Server: Apache/2.4.41 (Ubuntu)
System: Linux wordpress-ubuntu-s-2vcpu-4gb-fra1-01 5.4.0-169-generic #187-Ubuntu SMP Thu Nov 23 14:52:28 UTC 2023 x86_64
User: root (0)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
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,
    );
}


?>