Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
6.90% |
8 / 116 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
Events | |
6.90% |
8 / 116 |
|
0.00% |
0 / 5 |
149.39 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
register_routes | |
0.00% |
0 / 52 |
|
0.00% |
0 / 1 |
2 | |||
create_item | |
42.11% |
8 / 19 |
|
0.00% |
0 / 1 |
7.10 | |||
create_item_permissions_check | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
6 | |||
create_items | |
0.00% |
0 / 34 |
|
0.00% |
0 / 1 |
30 |
1 | <?php |
2 | |
3 | namespace NewfoldLabs\WP\Module\Data\API; |
4 | |
5 | use NewfoldLabs\WP\Module\Data\Event; |
6 | use NewfoldLabs\WP\Module\Data\EventManager; |
7 | use NewfoldLabs\WP\Module\Data\HiiveConnection; |
8 | use WP_REST_Controller; |
9 | use WP_REST_Server; |
10 | |
11 | /** |
12 | * REST API controller for sending events to the hiive. |
13 | */ |
14 | class Events extends WP_REST_Controller { |
15 | |
16 | /** |
17 | * Instance of the EventManager class. |
18 | * |
19 | * @var EventManager |
20 | */ |
21 | public $event_manager; |
22 | |
23 | /** |
24 | * Instance of the HiiveConnection class. |
25 | * |
26 | * @var HiiveConnection |
27 | */ |
28 | public $hiive; |
29 | |
30 | /** |
31 | * Events constructor. |
32 | * |
33 | * @param HiiveConnection $hiive Instance of the HiiveConnection class. |
34 | * @param EventManager $event_manager Instance of the EventManager class. |
35 | */ |
36 | public function __construct( HiiveConnection $hiive, EventManager $event_manager ) { |
37 | $this->event_manager = $event_manager; |
38 | $this->hiive = $hiive; |
39 | $this->namespace = 'newfold-data/v1'; |
40 | $this->rest_base = 'events'; |
41 | } |
42 | |
43 | /** |
44 | * Registers the routes for the objects of the controller. |
45 | * |
46 | * @see register_rest_route() |
47 | * @see EventManager::rest_api_init() |
48 | */ |
49 | public function register_routes() { |
50 | |
51 | register_rest_route( |
52 | $this->namespace, |
53 | '/' . $this->rest_base . '/', |
54 | array( |
55 | 'args' => array( |
56 | 'action' => array( |
57 | 'required' => true, |
58 | 'description' => __( 'Event action. For the "pageview" action/key, Hiive tries to read the page URL and page title only from the "page" and "page_title" keys in the data arg.' ), |
59 | 'type' => 'string', |
60 | 'sanitize_callback' => function ( $value ) { |
61 | return sanitize_title( $value ); |
62 | }, |
63 | ), |
64 | 'category' => array( |
65 | 'default' => 'admin', |
66 | 'description' => __( 'Event category' ), |
67 | 'type' => 'string', |
68 | 'sanitize_callback' => function ( $value ) { |
69 | return sanitize_title( $value ); |
70 | }, |
71 | ), |
72 | 'data' => array( |
73 | 'description' => __( 'Event data' ), |
74 | 'type' => 'object', |
75 | ), |
76 | 'queue' => array( |
77 | 'default' => true, |
78 | 'description' => __( 'Whether or not to queue the event' ), |
79 | 'type' => 'boolean', |
80 | 'sanitize_callback' => function ( $value ) { |
81 | return filter_var( $value, FILTER_VALIDATE_BOOLEAN ); |
82 | }, |
83 | ), |
84 | ), |
85 | array( |
86 | 'methods' => WP_REST_Server::CREATABLE, |
87 | 'callback' => array( $this, 'create_item' ), |
88 | 'permission_callback' => array( $this, 'create_item_permissions_check' ), |
89 | ), |
90 | ) |
91 | ); |
92 | |
93 | \register_rest_route( |
94 | $this->namespace, |
95 | '/' . $this->rest_base . '/batch', |
96 | array( |
97 | array( |
98 | 'methods' => \WP_REST_Server::CREATABLE, |
99 | 'callback' => array( $this, 'create_items' ), |
100 | 'permission_callback' => array( $this, 'create_item_permissions_check' ), |
101 | ), |
102 | ) |
103 | ); |
104 | } |
105 | |
106 | /** |
107 | * Dispatches a new event. |
108 | * |
109 | * `wp-json/newfold-data/v1/events` |
110 | * |
111 | * @param \WP_REST_Request $request Full details about the request. |
112 | * |
113 | * @used-by newfold-notifications/v1/notifications/ |
114 | * @used-by NotificationsApi::registerRoutes() (in callback) |
115 | * @used-by wp-module-notifications/assets/js/realtime-notices.js:189 |
116 | * |
117 | * @return \WP_REST_Response|\WP_Error Response object on success, or WP_Error object on failure. |
118 | */ |
119 | public function create_item( $request ) { |
120 | |
121 | $category = $request->get_param( 'category' ); |
122 | $action = $request->get_param( 'action' ); |
123 | $data = ! empty( $request['data'] ) ? $request['data'] : array(); |
124 | |
125 | $event = new Event( $category, $action, $data ); |
126 | |
127 | // If request isn't to be queued, we want the realtime response. |
128 | if ( ! $request['queue'] ) { |
129 | $hiive_response_notifications = $this->hiive->send_event( $event ); |
130 | |
131 | if ( is_wp_error( $hiive_response_notifications ) ) { |
132 | return new \WP_REST_Response( $hiive_response_notifications->get_error_message(), 500 ); |
133 | } |
134 | |
135 | return new \WP_REST_Response( array( 'data' => $hiive_response_notifications ), 201 ); |
136 | } |
137 | |
138 | // Otherwise, queue the event. |
139 | $this->event_manager->push( $event ); |
140 | |
141 | $response = rest_ensure_response( |
142 | array( |
143 | 'category' => $category, |
144 | 'action' => $action, |
145 | 'data' => $data, |
146 | ) |
147 | ); |
148 | // 202 – "The request has been accepted for processing, but the processing has not been completed.". |
149 | $response->set_status( 202 ); |
150 | |
151 | return $response; |
152 | } |
153 | |
154 | /** |
155 | * User is required to be logged in. |
156 | * |
157 | * @param \WP_REST_Request $request Full details about the request. |
158 | * |
159 | * @return true|\WP_Error |
160 | * |
161 | * @since 1.0 |
162 | */ |
163 | public function create_item_permissions_check( $request ) { |
164 | if ( ! current_user_can( 'read' ) ) { |
165 | return new \WP_Error( |
166 | 'rest_cannot_log_event', |
167 | __( 'Sorry, you are not allowed to use this endpoint.' ), |
168 | array( 'status' => rest_authorization_required_code() ) |
169 | ); |
170 | } |
171 | |
172 | return true; |
173 | } |
174 | |
175 | /** |
176 | * Manages sending a batch of events to the single event API. |
177 | * |
178 | * @param \WP_REST_Request $request A request containing an array of events. |
179 | * @return \WP_REST_Response|\WP_Error Response object on success, or WP_Error object on failure. |
180 | */ |
181 | public function create_items( $request ) { |
182 | $events = $request->get_json_params(); |
183 | if ( ! rest_is_array( $events ) ) { |
184 | return new \WP_Error( |
185 | 'rest_cannot_log_events', |
186 | __( 'Request does not contain an array of events.' ) |
187 | ); |
188 | } |
189 | |
190 | $errors = array(); |
191 | foreach ( $events as $index => $event ) { |
192 | $event_request = new \WP_REST_Request( |
193 | \WP_REST_Server::CREATABLE, |
194 | "/{$this->namespace}/{$this->rest_base}" |
195 | ); |
196 | $event_request->set_body_params( $event ); |
197 | $response = \rest_do_request( $event_request ); |
198 | if ( $response->is_error() ) { |
199 | array_push( |
200 | $errors, |
201 | array( |
202 | 'index' => $index, |
203 | 'data' => $response->as_error(), |
204 | ) |
205 | ); |
206 | } |
207 | } |
208 | |
209 | if ( ! empty( $errors ) ) { |
210 | return new \WP_Error( |
211 | 'rest_cannot_log_events', |
212 | __( 'Some events failed.' ), |
213 | array( |
214 | 'errors' => $errors, |
215 | ) |
216 | ); |
217 | } |
218 | |
219 | return new \WP_REST_Response( |
220 | array(), |
221 | 202 // Accepted. The request has been accepted for processing, but the processing has not been completed. |
222 | ); |
223 | } |
224 | } |