Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 109
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
EventService
0.00% covered (danger)
0.00%
0 / 109
0.00% covered (danger)
0.00%
0 / 5
600
0.00% covered (danger)
0.00%
0 / 1
 send
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 1
20
 validate_category
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 validate_action
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 validate
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
30
 send_application_event
0.00% covered (danger)
0.00%
0 / 67
0.00% covered (danger)
0.00%
0 / 1
110
1<?php
2
3namespace NewfoldLabs\WP\Module\Migration\Services;
4
5use NewfoldLabs\WP\Module\Migration\Data\Events;
6use NewfoldLabs\WP\Module\Data\Event;
7use NewfoldLabs\WP\Module\Data\EventManager;
8use NewfoldLabs\WP\Module\Data\HiiveConnection;
9
10/**
11 * Class for handling analytics events.
12 */
13class EventService {
14
15    /**
16     * Sends a Hiive Event to the data module API.
17     *
18     * @param array $event The event to send.
19     * @return WP_REST_Response|WP_Error|bool
20     */
21    public static function send( $event ) {
22        $event = self::validate( $event );
23        if ( ! $event ) {
24            return new \WP_Error(
25                'nfd_module_migration_error',
26                __( 'Bad event structure/value.', 'wp-module-migration' )
27            );
28        }
29
30        if ( 'migration_completed' === $event['action'] ) {
31            $event_to_send = new Event(
32                $event['category'],
33                $event['action'],
34                $event['data']
35            );
36
37            $event_manager = new EventManager();
38            $event_manager->push( $event_to_send );
39            $event_manager->add_subscriber(
40                new HiiveConnection()
41            );
42            $event_manager->shutdown();
43
44            return true;
45        }
46
47        $event_data_request = new \WP_REST_Request(
48            \WP_REST_Server::CREATABLE,
49            NFD_MODULE_DATA_EVENTS_API
50        );
51        $event_data_request->set_body_params( $event );
52
53        $response = rest_do_request( $event_data_request );
54        if ( $response->is_error() ) {
55            return $response->as_error();
56        }
57
58        return $response;
59    }
60    /**
61     * Validates the category of an event.
62     *
63     * @param string $category The category of an event.
64     * @return boolean
65     */
66    public static function validate_category( $category ) {
67        $default_categories = Events::get_category();
68        foreach ( $default_categories as $event_category ) {
69            if ( $event_category === $category ) {
70                return true;
71            }
72        }
73        return false;
74    }
75
76    /**
77     * Validates the action performed in an event.
78     *
79     * @param string $action The action performed in an event.
80     * @return boolean
81     */
82    public static function validate_action( $action ) {
83        $valid_actions = Events::get_valid_actions();
84        if ( ! isset( $valid_actions[ $action ] ) ) {
85            return false;
86        }
87
88        return true;
89    }
90
91    /**
92     * Sanitizes and validates the action and category parameters of an event.
93     *
94     * @param array $event The event to sanitize and validate.
95     * @return array|boolean
96     */
97    public static function validate( $event ) {
98        if ( ! isset( $event['action'] ) || ! self::validate_action( $event['action'] ) ) {
99            return false;
100        }
101
102        if ( ! isset( $event['category'] ) || ! self::validate_category( $event['category'] ) ) {
103            return false;
104        }
105
106        return $event;
107    }
108
109    /**
110     * Sends a Hiive event to the Cloudflare worker's /events endpoint.
111     *
112     * @param string $key  The event action key.
113     * @param array  $data The event data payload (must include d_id and dest_url).
114     * @return bool|WP_Error
115     */
116    public static function send_application_event( $key, $data ) {
117        if ( get_option( 'nfd_migration_status_sent', false ) ) {
118            return true; // Event already sent, no need to send again.
119        }
120
121        // Validate input parameters.
122        if ( ! is_string( $key ) || empty( $key ) || ! is_array( $data ) ) {
123            return new \WP_Error(
124                'nfd_module_migration_invalid_input',
125                __( 'Invalid input for event key or data.', 'wp-module-migration' )
126            );
127        }
128
129        $category = Events::get_category()[1];
130        $event    = array(
131            'action'   => $key,
132            'category' => $category,
133            'data'     => $data,
134        );
135        $event    = self::validate( $event );
136        if ( ! $event ) {
137            return new \WP_Error(
138                'nfd_module_migration_invalid_event',
139                __( 'Invalid event payload.', 'wp-module-migration' )
140            );
141        }
142
143        $site_url = get_site_url();
144
145        $url     = trailingslashit( NFD_MIGRATION_PROXY_WORKER ) . 'events';
146        $payload = array(
147            'key'         => $event['action'],
148            'category'    => $event['category'],
149            'request'     => array(
150                'url' => $site_url,
151            ),
152            'environment' => array(
153                'brand' => BRAND_PLUGIN,
154            ),
155            'data'        => array_merge(
156                $event['data'],
157                array(
158                    'dest_url' => $site_url,
159                    'url'      => $site_url,
160                )
161            ),
162        );
163        $body    = wp_json_encode( $payload );
164        if ( false === $body ) {
165            return new \WP_Error(
166                'nfd_module_migration_encoding_failed',
167                __( 'Failed to encode event JSON.', 'wp-module-migration' )
168            );
169        }
170
171        $response = wp_remote_post(
172            $url,
173            array(
174                'headers' => array(
175                    'Content-Type' => 'application/json',
176                ),
177                'body'    => $body,
178                'timeout' => 10,
179            )
180        );
181
182        if ( is_wp_error( $response ) ) {
183            return $response;
184        }
185
186        $code = wp_remote_retrieve_response_code( $response );
187        if ( $code < 200 || $code >= 300 ) {
188            return new \WP_Error(
189                'nfd_module_migration_forward_failed',
190                __( 'Failed to forward event to Hiive.', 'wp-module-migration' ),
191                array(
192                    'status_code' => $code,
193                    'body'        => wp_remote_retrieve_body( $response ),
194                )
195            );
196        }
197
198        return true;
199    }
200}