PluginProbe
WooCommerce / 11.1.0-beta.1
WooCommerce v11.1.0-beta.1
11.1.0 11.1.0-rc.2 11.1.0-rc.1 11.1.0-beta.2 11.1.0-beta.1 11.0.1 11.0.0 11.0.0-rc.3 11.0.0-rc.2 11.0.0-rc.1 11.0.0-beta.2 11.0.0-beta.1 10.9.4 10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 All 648 releases
woocommerce / src / Admin / API / Notes.php

Notes.php in WooCommerce 11.1.0-beta.1, at src/Admin/API/Notes.php

816 lines 25.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * REST API Admin Notes controller
4 *
5 * Handles requests to the admin notes endpoint.
6 */
7
8 namespace Automattic\WooCommerce\Admin\API;
9
10 defined( 'ABSPATH' ) || exit;
11
12 use Automattic\WooCommerce\Admin\Notes\Note;
13 use Automattic\WooCommerce\Admin\Notes\Notes as NotesRepository;
14
15 /**
16 * REST API Admin Notes controller class.
17 *
18 * @internal
19 * @extends WC_REST_CRUD_Controller
20 */
21 class Notes extends \WC_REST_CRUD_Controller {
22
23 /**
24 * Endpoint namespace.
25 *
26 * @var string
27 */
28 protected $namespace = 'wc-analytics';
29
30 /**
31 * Route base.
32 *
33 * @var string
34 */
35 protected $rest_base = 'admin/notes';
36
37 /**
38 * Register the routes for admin notes.
39 */
40 public function register_routes() {
41 register_rest_route(
42 $this->namespace,
43 '/' . $this->rest_base,
44 array(
45 array(
46 'methods' => \WP_REST_Server::READABLE,
47 'callback' => array( $this, 'get_items' ),
48 'permission_callback' => array( $this, 'get_items_permissions_check' ),
49 'args' => $this->get_collection_params(),
50 ),
51 'schema' => array( $this, 'get_public_item_schema' ),
52 )
53 );
54
55 register_rest_route(
56 $this->namespace,
57 '/' . $this->rest_base . '/(?P<id>[\d-]+)',
58 array(
59 'args' => array(
60 'id' => array(
61 'description' => __( 'Unique ID for the resource.', 'woocommerce' ),
62 'type' => 'integer',
63 ),
64 ),
65 array(
66 'methods' => \WP_REST_Server::READABLE,
67 'callback' => array( $this, 'get_item' ),
68 'permission_callback' => array( $this, 'get_item_permissions_check' ),
69 ),
70 array(
71 'methods' => \WP_REST_Server::EDITABLE,
72 'callback' => array( $this, 'update_item' ),
73 'permission_callback' => array( $this, 'update_items_permissions_check' ),
74 ),
75 'schema' => array( $this, 'get_public_item_schema' ),
76 )
77 );
78
79 register_rest_route(
80 $this->namespace,
81 '/' . $this->rest_base . '/delete/(?P<id>[\d-]+)',
82 array(
83 array(
84 'methods' => \WP_REST_Server::DELETABLE,
85 'callback' => array( $this, 'delete_item' ),
86 'permission_callback' => array( $this, 'update_items_permissions_check' ),
87 ),
88 'schema' => array( $this, 'get_public_item_schema' ),
89 )
90 );
91
92 register_rest_route(
93 $this->namespace,
94 '/' . $this->rest_base . '/delete/all',
95 array(
96 array(
97 'methods' => \WP_REST_Server::DELETABLE,
98 'callback' => array( $this, 'delete_all_items' ),
99 'permission_callback' => array( $this, 'update_items_permissions_check' ),
100 'args' => array(
101 'status' => array(
102 'description' => __( 'Status of note.', 'woocommerce' ),
103 'type' => 'array',
104 'sanitize_callback' => 'wp_parse_slug_list',
105 'validate_callback' => 'rest_validate_request_arg',
106 'items' => array(
107 'enum' => Note::get_allowed_statuses(),
108 'type' => 'string',
109 ),
110 ),
111 ),
112 ),
113 'schema' => array( $this, 'get_public_item_schema' ),
114 )
115 );
116
117 register_rest_route(
118 $this->namespace,
119 '/' . $this->rest_base . '/update',
120 array(
121 array(
122 'methods' => \WP_REST_Server::EDITABLE,
123 'callback' => array( $this, 'batch_update_items' ),
124 'permission_callback' => array( $this, 'update_items_permissions_check' ),
125 ),
126 'schema' => array( $this, 'get_public_item_schema' ),
127 )
128 );
129
130 register_rest_route(
131 $this->namespace,
132 '/' . $this->rest_base . '/experimental-activate-promo/(?P<promo_note_name>[\w-]+)',
133 array(
134 array(
135 'methods' => \WP_REST_Server::EDITABLE,
136 'callback' => array( $this, 'activate_promo_note' ),
137 'permission_callback' => array( $this, 'update_items_permissions_check' ),
138 ),
139 'schema' => array( $this, 'get_public_item_schema' ),
140 )
141 );
142 }
143
144 /**
145 * Get a single note.
146 *
147 * @param WP_REST_Request $request Request data.
148 * @return WP_REST_Response|WP_Error
149 */
150 public function get_item( $request ) {
151 $note = NotesRepository::get_note( $request->get_param( 'id' ) );
152
153 if ( ! $note ) {
154 return new \WP_Error(
155 'woocommerce_note_invalid_id',
156 __( 'Sorry, there is no resource with that ID.', 'woocommerce' ),
157 array( 'status' => 404 )
158 );
159 }
160
161 if ( is_wp_error( $note ) ) {
162 return $note;
163 }
164
165 $data = $this->prepare_note_data_for_response( $note, $request );
166
167 return rest_ensure_response( $data );
168 }
169
170 /**
171 * Get all notes.
172 *
173 * @param WP_REST_Request $request Request data.
174 * @return WP_REST_Response
175 */
176 public function get_items( $request ) {
177 $query_args = $this->prepare_objects_query( $request );
178
179 $notes = NotesRepository::get_notes( 'edit', $query_args );
180
181 $data = array();
182 foreach ( (array) $notes as $note_obj ) {
183 $note = $this->prepare_item_for_response( $note_obj, $request );
184 $note = $this->prepare_response_for_collection( $note );
185 $data[] = $note;
186 }
187
188 $response = rest_ensure_response( $data );
189 $response->header( 'X-WP-Total', count( $data ) );
190
191 return $response;
192 }
193
194 /**
195 * Checks if user is in tasklist experiment.
196 *
197 * @return bool Whether remote inbox notifications are enabled.
198 */
199 private function is_tasklist_experiment_assigned_treatment() {
200 $anon_id = isset( $_COOKIE['tk_ai'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['tk_ai'] ) ) : '';
201 $allow_tracking = 'yes' === get_option( 'woocommerce_allow_tracking' );
202 $abtest = new \WooCommerce\Admin\Experimental_Abtest(
203 $anon_id,
204 'woocommerce',
205 $allow_tracking
206 );
207
208 $date = new \DateTime();
209 $date->setTimeZone( new \DateTimeZone( 'UTC' ) );
210
211 $experiment_name = sprintf(
212 'woocommerce_tasklist_progression_headercard_%s_%s',
213 $date->format( 'Y' ),
214 $date->format( 'm' )
215 );
216
217 $experiment_name_2col = sprintf(
218 'woocommerce_tasklist_progression_headercard_2col_%s_%s',
219 $date->format( 'Y' ),
220 $date->format( 'm' )
221 );
222
223 return $abtest->get_variation( $experiment_name ) === 'treatment' ||
224 $abtest->get_variation( $experiment_name_2col ) === 'treatment';
225 }
226
227 /**
228 * Prepare objects query.
229 *
230 * @param WP_REST_Request $request Full details about the request.
231 * @return array
232 */
233 protected function prepare_objects_query( $request ) {
234 $args = array();
235 $args['order'] = $request['order'];
236 $args['orderby'] = $request['orderby'];
237 $args['per_page'] = $request['per_page'];
238 $args['page'] = $request['page'];
239 $args['type'] = isset( $request['type'] ) ? $request['type'] : array();
240 $args['status'] = isset( $request['status'] ) ? $request['status'] : array();
241 $args['source'] = isset( $request['source'] ) ? $request['source'] : array();
242 $args['is_deleted'] = 0;
243
244 if ( isset( $request['is_read'] ) ) {
245 $args['is_read'] = filter_var( $request['is_read'], FILTER_VALIDATE_BOOLEAN );
246 }
247
248 if ( 'date' === $args['orderby'] ) {
249 $args['orderby'] = 'date_created';
250 }
251
252 /**
253 * Filter the query arguments for a request.
254 *
255 * Enables adding extra arguments or setting defaults for a post
256 * collection request.
257 *
258 * @param array $args Key value array of query var to query value.
259 * @param WP_REST_Request $request The request used.
260 * @since 3.9.0
261 */
262 $args = apply_filters( 'woocommerce_rest_notes_object_query', $args, $request );
263
264 return $args;
265 }
266
267 /**
268 * Check whether a given request has permission to read a single note.
269 *
270 * @param WP_REST_Request $request Full details about the request.
271 * @return WP_Error|boolean
272 */
273 public function get_item_permissions_check( $request ) {
274 if ( ! wc_rest_check_manager_permissions( 'system_status', 'read' ) ) {
275 return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
276 }
277
278 return true;
279 }
280
281 /**
282 * Check whether a given request has permission to read notes.
283 *
284 * @param WP_REST_Request $request Full details about the request.
285 * @return WP_Error|boolean
286 */
287 public function get_items_permissions_check( $request ) {
288 if ( ! wc_rest_check_manager_permissions( 'system_status', 'read' ) ) {
289 return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
290 }
291
292 return true;
293 }
294
295 /**
296 * Update a single note.
297 *
298 * @param WP_REST_Request $request Full details about the request.
299 * @return WP_REST_Request|WP_Error
300 */
301 public function update_item( $request ) {
302 $note = NotesRepository::get_note( $request->get_param( 'id' ) );
303
304 if ( ! $note ) {
305 return new \WP_Error(
306 'woocommerce_note_invalid_id',
307 __( 'Sorry, there is no resource with that ID.', 'woocommerce' ),
308 array( 'status' => 404 )
309 );
310 }
311
312 NotesRepository::update_note( $note, $this->get_requested_updates( $request ) );
313 return $this->get_item( $request );
314 }
315
316 /**
317 * Delete a single note.
318 *
319 * @param WP_REST_Request $request Full details about the request.
320 * @return WP_REST_Request|WP_Error
321 */
322 public function delete_item( $request ) {
323 $note = NotesRepository::get_note( $request->get_param( 'id' ) );
324
325 if ( ! $note ) {
326 return new \WP_Error(
327 'woocommerce_note_invalid_id',
328 __( 'Sorry, there is no note with that ID.', 'woocommerce' ),
329 array( 'status' => 404 )
330 );
331 }
332
333 NotesRepository::delete_note( $note );
334 $data = $this->prepare_note_data_for_response( $note, $request );
335 return rest_ensure_response( $data );
336 }
337
338 /**
339 * Delete all notes.
340 *
341 * @param WP_REST_Request $request Request object.
342 * @return WP_REST_Request|WP_Error
343 */
344 public function delete_all_items( $request ) {
345 $args = array();
346 if ( isset( $request['status'] ) ) {
347 $args['status'] = $request['status'];
348 }
349 $notes = NotesRepository::delete_all_notes( $args );
350 $data = array();
351 foreach ( (array) $notes as $note_obj ) {
352 $data[] = $this->prepare_note_data_for_response( $note_obj, $request );
353 }
354
355 $response = rest_ensure_response( $data );
356 $response->header( 'X-WP-Total', NotesRepository::get_notes_count( array( 'info', 'warning' ), array() ) );
357 return $response;
358 }
359
360 /**
361 * Prepare note data.
362 *
363 * @param Note $note Note data.
364 * @param WP_REST_Request $request Request object.
365 *
366 * @return WP_REST_Response $response Response data.
367 */
368 public function prepare_note_data_for_response( $note, $request ) {
369 $note = $note->get_data();
370 $note = $this->prepare_item_for_response( $note, $request );
371 return $this->prepare_response_for_collection( $note );
372 }
373
374 /**
375 * Prepare an array with the requested updates.
376 *
377 * @param WP_REST_Request $request Request object.
378 * @return array A list of the requested updates values.
379 */
380 protected function get_requested_updates( $request ) {
381 $requested_updates = array();
382 if ( ! is_null( $request->get_param( 'status' ) ) ) {
383 $requested_updates['status'] = $request->get_param( 'status' );
384 }
385
386 if ( ! is_null( $request->get_param( 'date_reminder' ) ) ) {
387 $requested_updates['date_reminder'] = $request->get_param( 'date_reminder' );
388 }
389
390 if ( ! is_null( $request->get_param( 'is_deleted' ) ) ) {
391 $requested_updates['is_deleted'] = $request->get_param( 'is_deleted' );
392 }
393
394 if ( ! is_null( $request->get_param( 'is_read' ) ) ) {
395 $requested_updates['is_read'] = $request->get_param( 'is_read' );
396 }
397
398 return $requested_updates;
399 }
400
401 /**
402 * Batch update a set of notes.
403 *
404 * @param WP_REST_Request $request Request object.
405 * @return WP_REST_Request|WP_Error
406 */
407 public function batch_update_items( $request ) {
408 $data = array();
409 $note_ids = $request->get_param( 'noteIds' );
410
411 if ( ! isset( $note_ids ) || ! is_array( $note_ids ) ) {
412 return new \WP_Error(
413 'woocommerce_note_invalid_ids',
414 __( 'Please provide an array of IDs through the noteIds param.', 'woocommerce' ),
415 array( 'status' => 422 )
416 );
417 }
418
419 foreach ( (array) $note_ids as $note_id ) {
420 $note = NotesRepository::get_note( (int) $note_id );
421 if ( $note ) {
422 NotesRepository::update_note( $note, $this->get_requested_updates( $request ) );
423 $data[] = $this->prepare_note_data_for_response( $note, $request );
424 }
425 }
426
427 $response = rest_ensure_response( $data );
428 $response->header( 'X-WP-Total', NotesRepository::get_notes_count( array( 'info', 'warning' ), array() ) );
429 return $response;
430 }
431
432 /**
433 * Activate a promo note, create if not exist.
434 *
435 * @param WP_REST_Request $request Request object.
436 * @return WP_REST_Request|WP_Error
437 */
438 public function activate_promo_note( $request ) {
439 /**
440 * Filter allowed promo notes for experimental-activate-promo.
441 *
442 * @param array $promo_notes Array of allowed promo notes.
443 * @since 7.8.0
444 */
445 $allowed_promo_notes = apply_filters( 'woocommerce_admin_allowed_promo_notes', [] );
446
447 $promo_note_name = $request->get_param( 'promo_note_name' );
448
449 if ( ! in_array( $promo_note_name, $allowed_promo_notes, true ) ) {
450 return new \WP_Error(
451 'woocommerce_note_invalid_promo_note_name',
452 __( 'Please provide a valid promo note name.', 'woocommerce' ),
453 array( 'status' => 422 )
454 );
455 }
456
457 $data_store = NotesRepository::load_data_store();
458 $note_ids = $data_store->get_notes_with_name( $promo_note_name );
459
460 if ( empty( $note_ids ) ) {
461 // Promo note doesn't exist, this could happen in cases where
462 // user might have disabled RemoteInboxNotications via disabling
463 // marketing suggestions. Thus we'd have to manually add the note.
464 $note = new Note();
465 $note->set_name( $promo_note_name );
466 $note->set_status( Note::E_WC_ADMIN_NOTE_ACTIONED );
467 $data_store->create( $note );
468 } else {
469 $note = NotesRepository::get_note( $note_ids[0] );
470 NotesRepository::update_note(
471 $note,
472 [
473 'status' => Note::E_WC_ADMIN_NOTE_ACTIONED,
474 ]
475 );
476 }
477
478 return rest_ensure_response(
479 array(
480 'success' => true,
481 )
482 );
483 }
484
485 /**
486 * Makes sure the current user has access to WRITE the settings APIs.
487 *
488 * @param WP_REST_Request $request Full data about the request.
489 * @return WP_Error|bool
490 */
491 public function update_items_permissions_check( $request ) {
492 if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) {
493 return new \WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
494 }
495 return true;
496 }
497
498 /**
499 * Prepare a path or query for serialization to the client.
500 *
501 * @param string $query The query, path, or URL to transform.
502 * @return string A fully formed URL.
503 */
504 public function prepare_query_for_response( $query ) {
505 if ( empty( $query ) ) {
506 return $query;
507 }
508 if ( 'https://' === substr( $query, 0, 8 ) ) {
509 return $query;
510 }
511 if ( 'http://' === substr( $query, 0, 7 ) ) {
512 return $query;
513 }
514 if ( '?' === substr( $query, 0, 1 ) ) {
515 return admin_url( 'admin.php' . $query );
516 }
517
518 return admin_url( $query );
519 }
520
521 /**
522 * Maybe add a nonce to a URL.
523 *
524 * @link https://codex.wordpress.org/WordPress_Nonces
525 *
526 * @param string $url The URL needing a nonce.
527 * @param string $action The nonce action.
528 * @param string $name The nonce name.
529 * @return string A fully formed URL.
530 */
531 private function maybe_add_nonce_to_url( string $url, string $action = '', string $name = '' ) : string {
532 if ( empty( $action ) ) {
533 return $url;
534 }
535
536 if ( empty( $name ) ) {
537 // Default parameter name.
538 $name = '_wpnonce';
539 }
540
541 return add_query_arg( $name, wp_create_nonce( $action ), $url );
542 }
543
544 /**
545 * Prepare a note object for serialization.
546 *
547 * @param array $data Note data.
548 * @param WP_REST_Request $request Request object.
549 * @return WP_REST_Response $response Response data.
550 */
551 public function prepare_item_for_response( $data, $request ) {
552 $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
553 $data = $this->add_additional_fields_to_object( $data, $request );
554 $data['date_created_gmt'] = wc_rest_prepare_date_response( $data['date_created'] );
555 $data['date_created'] = wc_rest_prepare_date_response( $data['date_created'], false );
556 $data['date_reminder_gmt'] = wc_rest_prepare_date_response( $data['date_reminder'] );
557 $data['date_reminder'] = wc_rest_prepare_date_response( $data['date_reminder'], false );
558 $data['title'] = stripslashes( $data['title'] );
559 $data['content'] = stripslashes( $data['content'] );
560 $data['is_snoozable'] = (bool) $data['is_snoozable'];
561 $data['is_deleted'] = (bool) $data['is_deleted'];
562 $data['is_read'] = (bool) $data['is_read'];
563 foreach ( (array) $data['actions'] as $key => $value ) {
564 $data['actions'][ $key ]->label = stripslashes( $data['actions'][ $key ]->label );
565 $data['actions'][ $key ]->url = $this->maybe_add_nonce_to_url(
566 $this->prepare_query_for_response( $data['actions'][ $key ]->query ),
567 (string) $data['actions'][ $key ]->nonce_action,
568 (string) $data['actions'][ $key ]->nonce_name
569 );
570 $data['actions'][ $key ]->status = stripslashes( $data['actions'][ $key ]->status );
571 }
572 $data = $this->filter_response_by_context( $data, $context );
573
574 // Wrap the data in a response object.
575 $response = rest_ensure_response( $data );
576 $response->add_links(
577 array(
578 'self' => array(
579 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $data['id'] ) ),
580 ),
581 'collection' => array(
582 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
583 ),
584 )
585 );
586 /**
587 * Filter a note returned from the API.
588 *
589 * Allows modification of the note data right before it is returned.
590 *
591 * @param WP_REST_Response $response The response object.
592 * @param array $data The original note.
593 * @param WP_REST_Request $request Request used to generate the response.
594 * @since 3.9.0
595 */
596 return apply_filters( 'woocommerce_rest_prepare_note', $response, $data, $request );
597 }
598
599 /**
600 * Track opened emails.
601 *
602 * @deprecated 10.6.0 This method is no longer functional as the email tracking feature was removed in WooCommerce 9.9.
603 *
604 * @param WP_REST_Request $request Request object.
605 */
606 public function track_opened_email( $request ) {
607 wc_deprecated_function( __METHOD__, '10.6.0' );
608 }
609
610 /**
611 * Get the query params for collections.
612 *
613 * @return array
614 */
615 public function get_collection_params() {
616 $params = array();
617 $params['context'] = $this->get_context_param( array( 'default' => 'view' ) );
618 $params['order'] = array(
619 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ),
620 'type' => 'string',
621 'default' => 'desc',
622 'enum' => array( 'asc', 'desc' ),
623 'validate_callback' => 'rest_validate_request_arg',
624 );
625 $params['orderby'] = array(
626 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ),
627 'type' => 'string',
628 'default' => 'date',
629 'enum' => array(
630 'note_id',
631 'date',
632 'type',
633 'title',
634 'status',
635 ),
636 'validate_callback' => 'rest_validate_request_arg',
637 );
638 $params['page'] = array(
639 'description' => __( 'Current page of the collection.', 'woocommerce' ),
640 'type' => 'integer',
641 'default' => 1,
642 'sanitize_callback' => 'absint',
643 'validate_callback' => 'rest_validate_request_arg',
644 'minimum' => 1,
645 );
646 $params['per_page'] = array(
647 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ),
648 'type' => 'integer',
649 'default' => 10,
650 'minimum' => 1,
651 'maximum' => 100,
652 'sanitize_callback' => 'absint',
653 'validate_callback' => 'rest_validate_request_arg',
654 );
655 $params['type'] = array(
656 'description' => __( 'Type of note.', 'woocommerce' ),
657 'type' => 'array',
658 'sanitize_callback' => 'wp_parse_slug_list',
659 'validate_callback' => 'rest_validate_request_arg',
660 'items' => array(
661 'enum' => Note::get_allowed_types(),
662 'type' => 'string',
663 ),
664 );
665 $params['status'] = array(
666 'description' => __( 'Status of note.', 'woocommerce' ),
667 'type' => 'array',
668 'sanitize_callback' => 'wp_parse_slug_list',
669 'validate_callback' => 'rest_validate_request_arg',
670 'items' => array(
671 'enum' => Note::get_allowed_statuses(),
672 'type' => 'string',
673 ),
674 );
675 $params['source'] = array(
676 'description' => __( 'Source of note.', 'woocommerce' ),
677 'type' => 'array',
678 'sanitize_callback' => 'wp_parse_list',
679 'validate_callback' => 'rest_validate_request_arg',
680 'items' => array(
681 'type' => 'string',
682 ),
683 );
684 return $params;
685 }
686
687 /**
688 * Get the note's schema, conforming to JSON Schema.
689 *
690 * @return array
691 */
692 public function get_item_schema() {
693 $schema = array(
694 '$schema' => 'http://json-schema.org/draft-04/schema#',
695 'title' => 'note',
696 'type' => 'object',
697 'properties' => array(
698 'id' => array(
699 'description' => __( 'ID of the note record.', 'woocommerce' ),
700 'type' => 'integer',
701 'context' => array( 'view' ),
702 'readonly' => true,
703 ),
704 'name' => array(
705 'description' => __( 'Name of the note.', 'woocommerce' ),
706 'type' => 'string',
707 'context' => array( 'view', 'edit' ),
708 'readonly' => true,
709 ),
710 'type' => array(
711 'description' => __( 'The type of the note (e.g. error, warning, etc.).', 'woocommerce' ),
712 'type' => 'string',
713 'context' => array( 'view', 'edit' ),
714 'readonly' => true,
715 ),
716 'locale' => array(
717 'description' => __( 'Locale used for the note title and content.', 'woocommerce' ),
718 'type' => 'string',
719 'context' => array( 'view', 'edit' ),
720 'readonly' => true,
721 ),
722 'title' => array(
723 'description' => __( 'Title of the note.', 'woocommerce' ),
724 'type' => 'string',
725 'context' => array( 'view', 'edit' ),
726 'readonly' => true,
727 ),
728 'content' => array(
729 'description' => __( 'Content of the note.', 'woocommerce' ),
730 'type' => 'string',
731 'context' => array( 'view', 'edit' ),
732 'readonly' => true,
733 ),
734 'content_data' => array(
735 'description' => __( 'Content data for the note. JSON string. Available for re-localization.', 'woocommerce' ),
736 'type' => 'string',
737 'context' => array( 'view', 'edit' ),
738 'readonly' => true,
739 ),
740 'status' => array(
741 'description' => __( 'The status of the note (e.g. unactioned, actioned).', 'woocommerce' ),
742 'type' => 'string',
743 'context' => array( 'view', 'edit' ),
744 ),
745 'source' => array(
746 'description' => __( 'Source of the note.', 'woocommerce' ),
747 'type' => 'string',
748 'context' => array( 'view', 'edit' ),
749 'readonly' => true,
750 ),
751 'date_created' => array(
752 'description' => __( 'Date the note was created.', 'woocommerce' ),
753 'type' => 'string',
754 'context' => array( 'view', 'edit' ),
755 'readonly' => true,
756 ),
757 'date_created_gmt' => array(
758 'description' => __( 'Date the note was created (GMT).', 'woocommerce' ),
759 'type' => 'string',
760 'context' => array( 'view', 'edit' ),
761 'readonly' => true,
762 ),
763 'date_reminder' => array(
764 'description' => __( 'Date after which the user should be reminded of the note, if any.', 'woocommerce' ),
765 'type' => 'string',
766 'context' => array( 'view', 'edit' ),
767 'readonly' => true, // @todo Allow date_reminder to be updated.
768 ),
769 'date_reminder_gmt' => array(
770 'description' => __( 'Date after which the user should be reminded of the note, if any (GMT).', 'woocommerce' ),
771 'type' => 'string',
772 'context' => array( 'view', 'edit' ),
773 'readonly' => true,
774 ),
775 'is_snoozable' => array(
776 'description' => __( 'Whether or not a user can request to be reminded about the note.', 'woocommerce' ),
777 'type' => 'boolean',
778 'context' => array( 'view', 'edit' ),
779 'readonly' => true,
780 ),
781 'actions' => array(
782 'description' => __( 'An array of actions, if any, for the note.', 'woocommerce' ),
783 'type' => 'array',
784 'context' => array( 'view', 'edit' ),
785 'readonly' => true,
786 ),
787 'layout' => array(
788 'description' => __( 'Deprecated. Always returns "plain". Inbox notes no longer support layout variants; this field will be removed in a future release.', 'woocommerce' ),
789 'type' => 'string',
790 'context' => array( 'view', 'edit' ),
791 'readonly' => true,
792 ),
793 'image' => array(
794 'description' => __( 'Deprecated. Always returns an empty string. Inbox notes no longer render images; this field will be removed in a future release.', 'woocommerce' ),
795 'type' => 'string',
796 'context' => array( 'view', 'edit' ),
797 'readonly' => true,
798 ),
799 'is_deleted' => array(
800 'description' => __( 'Registers whether the note is deleted or not', 'woocommerce' ),
801 'type' => 'boolean',
802 'context' => array( 'view', 'edit' ),
803 'readonly' => true,
804 ),
805 'is_read' => array(
806 'description' => __( 'Registers whether the note is read or not', 'woocommerce' ),
807 'type' => 'boolean',
808 'context' => array( 'view', 'edit' ),
809 'readonly' => true,
810 ),
811 ),
812 );
813 return $this->add_additional_fields_schema( $schema );
814 }
815 }
816