Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
91.80% covered (success)
91.80%
56 / 61
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ID_Resolver
91.80% covered (success)
91.80%
56 / 61
33.33% covered (danger)
33.33%
1 / 3
25.34
0.00% covered (danger)
0.00%
0 / 1
 find_cnhsa_id
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 find_cnhsa_service_id
91.67% covered (success)
91.67%
22 / 24
0.00% covered (danger)
0.00%
0 / 1
9.05
 find_cnhsa_location_id
89.66% covered (success)
89.66%
26 / 29
0.00% covered (danger)
0.00%
0 / 1
12.16
1<?php
2/**
3 * ID Resolver Class
4 * Handles matching of data between the CNO & CNHSA sites.
5 *
6 * @package ChoctawNation
7 * @subpackage CNHSA_Federation
8 */
9
10namespace ChoctawNation\CNHSA_Federation\WP;
11
12use Exception;
13use WP_Post;
14
15/**
16 * Class ID_Resolver
17 */
18class ID_Resolver {
19    /**
20     * Finds the CNHSA ID for a given post type and post ID.
21     *
22     * @param 'services'|'locations' $post_type The post type (slug) to search for (e.g., 'services').
23     * @param WP_Post                $post      The local post object to find the corresponding CNHSA ID for.
24     * @param string                 $base_url  The base URL of the CNHSA site to query.
25     * @return int The CNHSA ID if found, or 0 if not found.
26     */
27    public function find_cnhsa_id( string $post_type, WP_Post $post, string $base_url ): int {
28        $cnhsa_id = (int) get_post_meta( $post->ID, 'cnhsa_id', true );
29        if ( 0 !== $cnhsa_id ) {
30            return $cnhsa_id;
31        }
32        if ( 'services' === $post_type ) {
33            $cnhsa_id = $this->find_cnhsa_service_id( $base_url, $post->post_name );
34        } elseif ( 'locations' === $post_type ) {
35            $cnhsa_id = $this->find_cnhsa_location_id( $base_url, $post->post_name );
36        }
37        return $cnhsa_id;
38    }
39
40    /**
41     * Resolves the CNHSA ID for a given post type and post ID by querying the CNHSA API.
42     *
43     * @param string $base_url The base URL of the CNHSA site to query.
44     * @param string $slug The slug of the local post to find the corresponding CNHSA ID for.
45     * @return int The CNHSA ID if found, or 0 if not found.
46     * @throws Exception If the API request fails or returns an invalid response.
47     */
48    public function find_cnhsa_service_id( string $base_url, string $slug ): int {
49        $paged = 1;
50        $found = array();
51        do {
52            ++$paged;
53            $response = wp_remote_get(
54                "{$base_url}/wp/v2/services?_fields=id,title,slug&per_page=100&page={$paged}",
55            );
56            if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
57                $message = is_wp_error( $response ) ? $response->get_error_message() : 'Invalid response code';
58                throw new Exception( esc_textarea( $message ) );
59            }
60            $pages = (int) wp_remote_retrieve_header( $response, 'X-WP-TotalPages' );
61            $body  = wp_remote_retrieve_body( $response );
62            $data  = json_decode( $body, true );
63            if ( empty( $data ) || ! is_array( $data ) ) {
64                return 0;
65            }
66            $found = array_filter(
67                $data,
68                function ( $item ) use ( $slug ) {
69                    return isset( $item['slug'] ) && $item['slug'] === $slug;
70                }
71            );
72        } while ( $paged < $pages && empty( $found ) );
73        if ( empty( $found ) ) {
74            return 0;
75        }
76        return (int) $found[0]['id'];
77    }
78
79    /**
80     * Resolves the CNHSA ID for a given post type and post ID by querying the CNHSA API.
81     *
82     * @param string $base_url The base URL of the CNHSA site to query.
83     * @param string $slug      The slug of the local post to find the corresponding CNHSA ID for.
84     * @return int The CNHSA ID if found, or 0 if not found.
85     * @throws Exception If the API request fails or returns an invalid response.
86     */
87    public function find_cnhsa_location_id( string $base_url, string $slug ): int {
88        $found          = array();
89        $post_type_keys = array( 'clinic', 'additional-facility' );
90
91        foreach ( $post_type_keys as $post_type ) {
92            $paged = 1;
93            do {
94                $response = wp_remote_get(
95                    "{$base_url}/wp/v2/{$post_type}?_fields=id,title,slug&per_page=100&page={$paged}",
96                );
97                if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
98                    $message = is_wp_error( $response ) ? $response->get_error_message() : 'Invalid response code';
99                    throw new Exception( esc_textarea( $message ) );
100                }
101                $pages = (int) wp_remote_retrieve_header( $response, 'X-WP-TotalPages' );
102                $body  = wp_remote_retrieve_body( $response );
103                $data  = json_decode( $body, true );
104                if ( empty( $data ) || ! is_array( $data ) || ! isset( $data[0] ) ) {
105                    ++$paged;
106                    continue;
107
108                }
109                $found = array_filter(
110                    $data,
111                    function ( $item ) use ( $slug ) {
112                        return isset( $item['slug'] ) && $item['slug'] === $slug;
113                    }
114                );
115                if ( ! empty( $found ) ) {
116                    break 2; // Break out of both loops if a match is found
117                }
118                ++$paged;
119            } while ( empty( $found ) && $paged <= $pages );
120        }
121        if ( empty( $found ) ) {
122            return 0;
123        }
124        return (int) $found[0]['id'];
125    }
126}