Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
74 / 74
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
Service_Payload_Factory
100.00% covered (success)
100.00%
74 / 74
100.00% covered (success)
100.00%
4 / 4
11
100.00% covered (success)
100.00%
1 / 1
 create_payload
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
3
 build_acf_field_data
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
1 / 1
3
 handle_related_media
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
3
 add_additional_categories
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2/**
3 * Class Service Payload Factory
4 *
5 * @package ChoctawNation\CNHSA_Federation
6 */
7
8namespace ChoctawNation\CNHSA_Federation\WP\Payload;
9
10use WP_Error;
11use WP_Post;
12
13/**
14 * Service Payload Factory Class
15 * Responsible for constructing the payload for service posts to be sent to the external API.
16 */
17class Service_Payload_Factory extends Payload_Factory {
18    /**
19     * Builds the payload for a service post.
20     *
21     * @param WP_Post $data The service post object.
22     * @return array|WP_Error|null The payload array, a WP_Error on failure, or null if no payload is needed.
23     */
24    public function create_payload( WP_Post $data ): array|WP_Error|null {
25        if ( 'services' !== $data->post_type ) {
26            return null;
27        }
28        $content               = $this->build_acf_field_data( $data->ID );
29        $rest_data             = array(
30            'title'     => $data->post_title,
31            'status'    => $data->post_status,
32            'slug'      => $data->post_name,
33            'excerpt'   => get_field(
34                'archive_content',
35                $data->ID
36            ),
37            'post_data' => $content,
38        );
39        $additional_categories = $this->add_additional_categories( $data->ID );
40        if ( ! empty( $additional_categories ) ) {
41            $rest_data['additional_categories'] = $additional_categories;
42        }
43
44        return $rest_data;
45    }
46
47    /**
48     * Builds the ACF field data for the CNHSA Federation API.
49     *
50     * @param int $id The post ID.
51     * @return array The ACF field data.
52     */
53    private function build_acf_field_data( int $id ): array {
54        $content = array();
55        $fields  = array(
56            'cnhsa_eligibility_guidelines',
57            'eligibility_requirements',
58            'how_to_apply',
59            'apply_online',
60            'online_application_url',
61            'application_address',
62            'inside_or_outside_reservation',
63            'is_application_always_open',
64            'application_period_start',
65            'application_period_end',
66            'application_period_open',
67            'additional_information',
68            'faq_title',
69            'faq_in_modal',
70            'faq',
71            'form_title',
72            'form',
73            'related_media',
74            'contact_information',
75        );
76        foreach ( $fields as $field ) {
77            if ( 'related_media' === $field ) {
78                $media             = get_field( $field, $id );
79                $content[ $field ] = $this->handle_related_media( $media );
80                continue;
81            }
82            $content[ $field ] = get_field( $field, $id );
83        }
84        return $content;
85    }
86
87    /**
88     * Sets “related media” ACF data appropriately for the CNHSA Federation API.
89     *
90     * @param array|null $media The related media field data.
91     * @return array The processed related media data.
92     */
93    private function handle_related_media( $media ): array {
94        if ( empty( $media ) ) {
95            return array();
96        }
97        $media_data = array_map(
98            function ( $data ) {
99                $parsed  = array();
100                $is_link = false !== strpos( $data['file_or_link'], '_link' );
101                if ( $is_link ) {
102                    $parsed['internal_link'] = null;
103                    $parsed['external_link'] = $data['internal_link'];
104                } else {
105                    $parsed['internal_link'] = null;
106                    $parsed['external_link'] = $data['pdf'];
107                }
108                $parsed['file_or_link'] = 'external_link';
109                return array( ...$data, ...$parsed );
110            },
111            $media
112        );
113        return $media_data;
114    }
115
116    /**
117     * Add additional categories excluding 'Health'.
118     *
119     * @param int $id The post ID.
120     * @return array|null The additional categories or null if none found.
121     */
122    private function add_additional_categories( int $id ): ?array {
123        $categories = get_categories(
124            array(
125                'object_ids' => $id,
126            )
127        );
128        if ( empty( $categories ) ) {
129            return null;
130        }
131        return array_filter(
132            wp_list_pluck( $categories, 'name' ),
133            fn( $cat ) => 'Health' !== $cat
134        );
135    }
136}