Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
Publisher
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
5 / 5
15
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 update_services
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 update_locations
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 update_post
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 build_payload
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
6
1<?php
2/**
3 * Publisher
4 * Handles Publishing job orchestration for Services and Locations.
5 *
6 * @package CNHSA_Federation
7 */
8
9namespace ChoctawNation\CNHSA_Federation\WP;
10
11use ChoctawNation\CNHSA_Federation\Transport\HTTP_Gateway;
12use ChoctawNation\CNHSA_Federation\WP\Payload\Location_Payload_Factory;
13use ChoctawNation\CNHSA_Federation\WP\Payload\Service_Payload_Factory;
14use Exception;
15use WP_Error;
16use WP_Post;
17
18/**
19 * Class Publisher
20 * Handles Publishing job orchestration for Services and Locations.
21 */
22class Publisher {
23    /**
24     * ID Resolver instance.
25     *
26     * @var ID_Resolver $id_resolver
27     */
28    public ID_Resolver $id_resolver;
29
30    /**
31     * HTTP Transport Gateway instance.
32     *
33     * @var HTTP_Gateway
34     */
35    public HTTP_Gateway $gateway;
36
37    /**
38     * Service Payload Factory instance.
39     *
40     * @var Service_Payload_Factory
41     */
42    public Service_Payload_Factory $service_payload_factory;
43
44    /**
45     * Location Payload Factory instance.
46     *
47     * @var Location_Payload_Factory
48     */
49    public Location_Payload_Factory $location_payload_factory;
50
51    /**
52     * Notifier instance.
53     *
54     * @var Notifier $notifier
55     */
56    public Notifier $notifier;
57
58    /**
59     * Constructor
60     *
61     * @param ID_Resolver              $id_resolver              An instance of the ID_Resolver class to resolve post IDs.
62     * @param HTTP_Gateway             $gateway                  An instance of the Gateway class to handle HTTP communication.
63     * @param Service_Payload_Factory  $service_payload_factory An instance of the Service_Payload_Factory class to create service payloads.
64     * @param Location_Payload_Factory $location_payload_factory An instance of the Location_Payload_Factory class to create location payloads.
65     * @param Notifier                 $notifier                 An instance of the Notifier class to handle notifications.
66     */
67    public function __construct( ID_Resolver $id_resolver, HTTP_Gateway $gateway, Service_Payload_Factory $service_payload_factory, Location_Payload_Factory $location_payload_factory, Notifier $notifier ) {
68        $this->id_resolver              = $id_resolver;
69        $this->gateway                  = $gateway;
70        $this->service_payload_factory  = $service_payload_factory;
71        $this->location_payload_factory = $location_payload_factory;
72        $this->notifier                 = $notifier;
73    }
74
75    /**
76     * Federate services post to CNHSA endpoint
77     *
78     * @param WP_Post $post The service post object to be published.
79     */
80    public function update_services( WP_Post $post ): void {
81        try {
82            $id   = $this->id_resolver->find_cnhsa_id( $post->post_type, $post, $this->gateway->base_url );
83            $url  = $id ? "{$this->gateway->base_url}/service/{$id}" : "{$this->gateway->base_url}/service";
84            $data = $this->update_post( $url, $post );
85            update_post_meta( $post->ID, 'cnhsa_id', $data['id'] );
86        } catch ( Exception $e ) {
87            $this->notifier->notify( 'CNHSA Services Federation Failed', esc_textarea( 'Publishing service post failed: ' . $e->getMessage() ) );
88        }
89    }
90
91    /**
92     * Federate location post to CNHSA endpoint
93     *
94     * @param WP_Post $post The location post object to be published.
95     */
96    public function update_locations( WP_Post $post ) {
97        try {
98            $id   = $this->id_resolver->find_cnhsa_id( $post->post_type, $post, $this->gateway->base_url );
99            $url  = $id ? "{$this->gateway->base_url}/location/{$id}" : "{$this->gateway->base_url}/location";
100            $data = $this->update_post( $url, $post );
101            update_post_meta( $post->ID, 'cnhsa_id', $data['id'] );
102        } catch ( Exception $e ) {
103            $this->notifier->notify( 'CNHSA Locations Federation Failed', esc_textarea( 'Publishing location post failed: ' . $e->getMessage() ) );
104        }
105    }
106
107    /**
108     * Updates the post content at the specified URL.
109     *
110     * @param string  $url  The endpoint URL to which the content should be published.
111     * @param WP_Post $post The post object containing the content to be published.
112     * @return array The response data from the publish_content method.
113     * @throws Exception If building the payload fails.
114     */
115    private function update_post( string $url, WP_Post $post ): array {
116        $payload = $this->build_payload( $post );
117        if ( is_wp_error( $payload ) ) {
118            throw new Exception( esc_textarea( 'Building payload failed: ' . $payload->get_error_message() ) );
119        }
120        return $this->gateway->publish_content( $url, $payload );
121    }
122
123    /**
124     * Builds the payload for the service post, including location data.
125     *
126     * @param WP_Post $post The service post object for which to build the payload.
127     * @return array|WP_Error The combined payload array or a WP_Error if payload creation fails.
128     */
129    private function build_payload( WP_Post $post ): array|WP_Error {
130        $service_payload = $this->service_payload_factory->create_payload( $post );
131        if ( is_wp_error( $service_payload ) ) {
132            return $service_payload;
133        }
134        $location_payload = $this->location_payload_factory->create_payload( $post );
135        if ( is_wp_error( $location_payload ) ) {
136            return $location_payload;
137        }
138        if ( 'services' === $post->post_type ) {
139            return is_null( $location_payload ) ? $service_payload : array_merge( $service_payload, array( 'location_data' => $location_payload ) );
140        } elseif ( 'locations' === $post->post_type ) {
141            return $location_payload[0];
142        } else {
143            return new WP_Error( 'invalid_post_type', 'Unsupported post type for payload creation.' );
144        }
145    }
146}