PluginProbe
WooCommerce / 11.1.0-rc.2
WooCommerce v11.1.0-rc.2
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 / Internal / PushNotifications / Controllers / NotificationPreferencesRestController.php
NotificationPreferencesRestController.php
215 lines 6.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare( strict_types = 1 );
4
5 namespace Automattic\WooCommerce\Internal\PushNotifications\Controllers;
6
7 defined( 'ABSPATH' ) || exit;
8
9 use Automattic\WooCommerce\Internal\PushNotifications\Services\NotificationPreferencesService;
10 use Automattic\WooCommerce\Internal\PushNotifications\Traits\AuthorizesPushNotificationRequests;
11 use Automattic\WooCommerce\Internal\PushNotifications\Traits\ConvertsExceptionsToWpError;
12 use Automattic\WooCommerce\Internal\RestApiControllerBase;
13 use Exception;
14 use WP_Error;
15 use WP_Http;
16 use WP_REST_Request;
17 use WP_REST_Response;
18 use WP_REST_Server;
19
20 /**
21 * Controller for the REST endpoints associated with the current user's
22 * push notification preferences.
23 *
24 * @since 10.8.0
25 */
26 class NotificationPreferencesRestController extends RestApiControllerBase {
27 use AuthorizesPushNotificationRequests;
28 use ConvertsExceptionsToWpError;
29
30 /**
31 * The root namespace for the JSON REST API endpoints.
32 *
33 * @var string
34 */
35 protected string $route_namespace = 'wc-push-notifications';
36
37 /**
38 * The REST base for the endpoints URL.
39 *
40 * @var string
41 */
42 protected string $rest_base = 'preferences';
43
44 /**
45 * The notification preferences service.
46 *
47 * @var NotificationPreferencesService
48 */
49 private NotificationPreferencesService $preferences_service;
50
51 /**
52 * Initialize injected dependencies.
53 *
54 * @internal
55 *
56 * @param NotificationPreferencesService $preferences_service The preferences service.
57 *
58 * @since 10.8.0
59 */
60 final public function init( NotificationPreferencesService $preferences_service ): void {
61 $this->preferences_service = $preferences_service;
62 }
63
64 /**
65 * Class identifier used by `woocommerce_rest_api_get_rest_namespaces`.
66 *
67 * Intentionally distinct from the URL `$route_namespace` — the filter keys
68 * one class per value here, so sharing the value with sibling controllers
69 * (e.g. `PushTokenRestController`) would overwrite them.
70 *
71 * @since 10.8.0
72 *
73 * @return string
74 */
75 protected function get_rest_api_namespace(): string {
76 return 'wc-push-notifications-preferences';
77 }
78
79 /**
80 * Register the REST API endpoints handled by this controller.
81 *
82 * @since 10.8.0
83 *
84 * @return void
85 */
86 public function register_routes(): void {
87 register_rest_route(
88 $this->route_namespace,
89 $this->rest_base,
90 array(
91 array(
92 'methods' => WP_REST_Server::READABLE,
93 'callback' => fn ( WP_REST_Request $request ) => $this->run( $request, 'get_preferences' ),
94 'permission_callback' => array( $this, 'authorize_as_authenticated' ),
95 ),
96 array(
97 'methods' => WP_REST_Server::EDITABLE,
98 'callback' => fn ( WP_REST_Request $request ) => $this->run( $request, 'update_preferences' ),
99 'permission_callback' => array( $this, 'authorize_as_authenticated' ),
100 'args' => $this->get_args(),
101 ),
102 )
103 );
104 }
105
106 /**
107 * Return the current user's notification preferences.
108 *
109 * @since 10.8.0
110 *
111 * @param WP_REST_Request $request The request object.
112 * @phpstan-param WP_REST_Request<array<string, mixed>> $request
113 * @return WP_REST_Response|WP_Error
114 */
115 public function get_preferences( WP_REST_Request $request ) {
116 unset( $request );
117
118 $preferences = $this->preferences_service->get_preferences( get_current_user_id() );
119
120 return new WP_REST_Response( $preferences, WP_Http::OK );
121 }
122
123 /**
124 * Partially update the current user's notification preferences and return
125 * the merged result.
126 *
127 * @since 10.8.0
128 *
129 * @param WP_REST_Request $request The request object.
130 * @phpstan-param WP_REST_Request<array<string, mixed>> $request
131 * @return WP_REST_Response|WP_Error
132 */
133 public function update_preferences( WP_REST_Request $request ) {
134 try {
135 $merged = $this->preferences_service->save_preferences(
136 get_current_user_id(),
137 $request->get_params()
138 );
139 } catch ( Exception $e ) {
140 return $this->convert_exception_to_wp_error( $e );
141 }
142
143 return new WP_REST_Response( $merged, WP_Http::OK );
144 }
145
146 /**
147 * Get the accepted arguments for the POST request.
148 *
149 * Each preference is an object so future sub-fields can be added without
150 * a schema-version bump. Keys are derived from the service's defaults so
151 * this stays in lock-step with the list of supported notification types.
152 *
153 * @return array<string, array<string, mixed>>
154 */
155 private function get_args(): array {
156 $args = array();
157 $defaults = $this->preferences_service->get_defaults();
158
159 foreach ( $defaults as $key => $shape ) {
160 $properties = array(
161 'enabled' => array(
162 'type' => 'boolean',
163 'description' => __( 'Whether this notification type is enabled.', 'woocommerce' ),
164 ),
165 );
166
167 if ( array_key_exists( 'min_amount', $shape ) ) {
168 $properties['min_amount'] = array(
169 'type' => array( 'number', 'null' ),
170 'minimum' => 0,
171 'exclusiveMinimum' => true,
172 'description' => __( 'Minimum order amount required to trigger this notification, or null to disable the threshold.', 'woocommerce' ),
173 );
174 }
175
176 if ( array_key_exists( 'max_rating', $shape ) ) {
177 $properties['max_rating'] = array(
178 'type' => array( 'integer', 'null' ),
179 'minimum' => 1,
180 'maximum' => 5,
181 'description' => __( 'Maximum star rating that triggers a review notification (1–5), or null to disable the threshold.', 'woocommerce' ),
182 );
183 }
184
185 $boolean_sub_fields = array( 'low_stock', 'out_of_stock', 'on_backorder' );
186 foreach ( $boolean_sub_fields as $sub_field ) {
187 if ( array_key_exists( $sub_field, $shape ) ) {
188 $properties[ $sub_field ] = array(
189 'type' => 'boolean',
190 'description' => sprintf(
191 /* translators: %s: sub-field name (e.g. low_stock). */
192 __( 'Whether %s notifications are enabled for this type.', 'woocommerce' ),
193 $sub_field
194 ),
195 );
196 }
197 }
198
199 $args[ $key ] = array(
200 'description' => sprintf(
201 /* translators: %s: notification preference key (e.g. store_order). */
202 __( 'Preferences for the %s push notification type.', 'woocommerce' ),
203 $key
204 ),
205 'type' => 'object',
206 'properties' => $properties,
207 'required' => false,
208 'validate_callback' => 'rest_validate_request_arg',
209 );
210 }//end foreach
211
212 return $args;
213 }
214 }
215