PluginProbe
seQura / 4.0.0
seQura v4.0.0
4.3.4 4.3.3 4.3.2 4.3.1 trunk 2.0.0 2.0.10 2.0.11 2.0.12 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 3.0.0 3.0.2 3.0.5 3.0.6 3.0.7 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 4.0.0 All 30 releases
sequra / src / Controllers / Rest / class-general-settings-rest-controller.php

class-general-settings-rest-controller.php in seQura 4.0.0, at src/Controllers/Rest/class-general-settings-rest-controller.php

445 lines 13.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * REST Settings Controller
4 *
5 * @package SeQura/WC
6 * @subpackage SeQura/WC/Controllers/Rest
7 */
8
9 namespace SeQura\WC\Controllers\Rest;
10
11 use SeQura\Core\BusinessLogic\AdminAPI\AdminAPI;
12 use SeQura\Core\BusinessLogic\AdminAPI\GeneralSettings\Requests\GeneralSettingsRequest;
13 use SeQura\Core\BusinessLogic\AdminAPI\OrderStatusSettings\Requests\OrderStatusSettingsRequest;
14 use SeQura\Core\BusinessLogic\Domain\GeneralSettings\Models\GeneralSettings;
15 use SeQura\Core\BusinessLogic\Domain\Multistore\StoreContext;
16 use SeQura\Core\BusinessLogic\Domain\Order\OrderStates;
17 use SeQura\WC\Services\Log\Interface_Logger_Service;
18 use SeQura\Core\Infrastructure\Utility\RegexProvider;
19 use WP_Error;
20 use WP_REST_Request;
21 use WP_REST_Response;
22
23 /**
24 * REST Settings Controller
25 */
26 class General_Settings_REST_Controller extends REST_Controller {
27
28 private const PARAM_SEND_ORDER_REPORTS_PERIODICALLY_TO_SEQURA = 'sendOrderReportsPeriodicallyToSeQura';
29 private const PARAM_SHOW_SEQURA_CHECKOUT_AS_HOSTED_PAGE = 'showSeQuraCheckoutAsHostedPage';
30 private const PARAM_ALLOWED_IP_ADDRESSES = 'allowedIPAddresses';
31 private const PARAM_EXCLUDED_PRODUCTS = 'excludedProducts';
32 private const PARAM_EXCLUDED_CATEGORIES = 'excludedCategories';
33 private const PARAM_DEFAULT_SERVICES_END_DATE = 'defaultServicesEndDate';
34
35 /**
36 * Store context
37 *
38 * @var StoreContext
39 */
40 private $store_context;
41
42 /**
43 * Constructor.
44 *
45 * @param string $rest_namespace The namespace.
46 * @param Interface_Logger_Service $logger The logger service.
47 * @param RegexProvider $regex The regex provider.
48 */
49 public function __construct(
50 $rest_namespace,
51 Interface_Logger_Service $logger,
52 RegexProvider $regex,
53 StoreContext $store_context
54 ) {
55 parent::__construct( $logger, $regex );
56 $this->namespace = $rest_namespace;
57 $this->rest_base = '/settings';
58 $this->store_context = $store_context;
59 }
60
61 /**
62 * Register the API endpoints.
63 *
64 * @return void
65 */
66 public function register_routes() {
67 $this->logger->log_debug( 'Hook executed', __FUNCTION__, __CLASS__ );
68 $store_id_args = array( self::PARAM_STORE_ID => $this->get_arg_string() );
69 $general_args = array_merge(
70 $store_id_args,
71 array(
72 self::PARAM_SEND_ORDER_REPORTS_PERIODICALLY_TO_SEQURA => $this->get_arg_bool(),
73 self::PARAM_SHOW_SEQURA_CHECKOUT_AS_HOSTED_PAGE => $this->get_arg_bool( false, false ),
74 self::PARAM_ALLOWED_IP_ADDRESSES => $this->get_arg_ip_list( true, array() ),
75 self::PARAM_EXCLUDED_PRODUCTS => array(
76 'required' => true,
77 'validate_callback' => array( $this, 'validate_array_of_product_sku' ),
78 'sanitize_callback' => array( $this, 'sanitize_array_sanitize_text_field' ),
79 ),
80 self::PARAM_EXCLUDED_CATEGORIES => array(
81 'required' => false,
82 'validate_callback' => array( $this, 'validate_array_of_product_cat' ),
83 'sanitize_callback' => array( $this, 'sanitize_array_of_ids' ),
84 ),
85 self::PARAM_DEFAULT_SERVICES_END_DATE => $this->get_arg_string( false, GeneralSettings::DEFAULT_SERVICE_END_DATE, array( $this, 'validate_time_duration' ) ),
86 )
87 );
88
89 $store_id = $this->url_param_pattern( self::PARAM_STORE_ID );
90
91 $this->register_get( 'current-store', 'get_current_store' );
92 $this->register_get( "version/{$store_id}", 'get_version', $store_id_args );
93 $this->register_get( "stores/{$store_id}", 'get_stores', $store_id_args );
94 $this->register_get( "state/{$store_id}", 'get_state', $store_id_args );
95 $this->register_get( "shop-categories/{$store_id}", 'get_shop_categories', $store_id_args );
96 $this->register_get( "shop-name/{$store_id}", 'get_shop_name', $store_id_args );
97
98 $this->register_get( "general/{$store_id}", 'get_general', $store_id_args );
99 $this->register_post( "general/{$store_id}", 'save_general', $general_args );
100
101 $this->register_get( "order-status/list/{$store_id}", 'get_list_order_status', $store_id_args );
102 $this->register_get( "order-status/{$store_id}", 'get_order_status', $store_id_args );
103 $this->register_post( "order-status/{$store_id}", 'save_order_status', $store_id_args );
104 }
105
106 /**
107 * GET current store.
108 *
109 * @return WP_REST_Response|WP_Error
110 */
111 public function get_current_store() {
112 $response = null;
113 try {
114 $response = AdminAPI::get()
115 ->store( $this->store_context->getStoreId() )
116 ->getCurrentStore()
117 ->toArray();
118 } catch ( \Throwable $e ) {
119 $this->logger->log_throwable( $e, __FUNCTION__, __CLASS__ );
120 $response = new WP_Error( 'error', $e->getMessage() );
121 }
122 return \rest_ensure_response( $response );
123 }
124
125 /**
126 * GET version.
127 *
128 * @param WP_REST_Request $request The request.
129 *
130 * @return WP_REST_Response|WP_Error
131 */
132 public function get_version( WP_REST_Request $request ) {
133 $response = null;
134 try {
135 $response = AdminAPI::get()
136 ->integration( strval( $request->get_param( self::PARAM_STORE_ID ) ) )
137 ->getVersion()
138 ->toArray();
139 } catch ( \Throwable $e ) {
140 $this->logger->log_throwable( $e, __FUNCTION__, __CLASS__ );
141 $response = new WP_Error( 'error', $e->getMessage() );
142 }
143 return \rest_ensure_response( $response );
144 }
145
146 /**
147 * GET stores.
148 *
149 * @param WP_REST_Request $request The request.
150 *
151 * @return WP_REST_Response|WP_Error
152 */
153 public function get_stores( WP_REST_Request $request ) {
154 $response = null;
155 try {
156 $response = AdminAPI::get()
157 ->store( strval( $request->get_param( self::PARAM_STORE_ID ) ) )
158 ->getStores()
159 ->toArray();
160 } catch ( \Throwable $e ) {
161 $this->logger->log_throwable( $e, __FUNCTION__, __CLASS__ );
162 $response = new WP_Error( 'error', $e->getMessage() );
163 }
164 return \rest_ensure_response( $response );
165 }
166
167 /**
168 * GET state.
169 *
170 * @param WP_REST_Request $request The request.
171 *
172 * @return WP_REST_Response|WP_Error
173 */
174 public function get_state( WP_REST_Request $request ) {
175 $response = null;
176 try {
177 $response = AdminAPI::get()
178 ->integration( strval( $request->get_param( self::PARAM_STORE_ID ) ) )
179 ->getUIState( true ) // Pass false if the Onboarding does not configure widgets.
180 ->toArray();
181 } catch ( \Throwable $e ) {
182 $this->logger->log_throwable( $e, __FUNCTION__, __CLASS__ );
183 $response = new WP_Error( 'error', $e->getMessage() );
184 }
185 return \rest_ensure_response( $response );
186 }
187
188 /**
189 * GET general settings.
190 *
191 * @param WP_REST_Request $request The request.
192 *
193 * @return WP_REST_Response|WP_Error
194 */
195 public function get_general( WP_REST_Request $request ) {
196 $response = null;
197 try {
198 $response = AdminAPI::get()
199 ->generalSettings( strval( $request->get_param( self::PARAM_STORE_ID ) ) )
200 ->getGeneralSettings()
201 ->toArray();
202 } catch ( \Throwable $e ) {
203 $this->logger->log_throwable( $e, __FUNCTION__, __CLASS__ );
204 $response = new WP_Error( 'error', $e->getMessage() );
205 }
206 return \rest_ensure_response( $response );
207 }
208
209 /**
210 * GET general settings.
211 *
212 * @param WP_REST_Request $request The request.
213 *
214 * @return WP_REST_Response|WP_Error
215 */
216 public function get_shop_name( WP_REST_Request $request ) {
217 $response = null;
218 try {
219 $response = AdminAPI::get()
220 ->integration( strval( $request->get_param( self::PARAM_STORE_ID ) ) )
221 ->getShopName()
222 ->toArray();
223 } catch ( \Throwable $e ) {
224 $this->logger->log_throwable( $e, __FUNCTION__, __CLASS__ );
225 $response = new WP_Error( 'error', $e->getMessage() );
226 }
227 return \rest_ensure_response( $response );
228 }
229
230 /**
231 * Save general settings.
232 *
233 * @throws \Exception
234 * @param WP_REST_Request $request The request.
235 *
236 * @return WP_REST_Response|WP_Error
237 */
238 public function save_general( WP_REST_Request $request ) {
239 $response = null;
240 try {
241 $response = AdminAPI::get()
242 ->generalSettings( strval( $request->get_param( self::PARAM_STORE_ID ) ) )
243 ->saveGeneralSettings(
244 new GeneralSettingsRequest(
245 (bool) $request->get_param( self::PARAM_SEND_ORDER_REPORTS_PERIODICALLY_TO_SEQURA ),
246 (bool) $request->get_param( self::PARAM_SHOW_SEQURA_CHECKOUT_AS_HOSTED_PAGE ),
247 (array) $request->get_param( self::PARAM_ALLOWED_IP_ADDRESSES ),
248 (array) $request->get_param( self::PARAM_EXCLUDED_PRODUCTS ),
249 (array) $request->get_param( self::PARAM_EXCLUDED_CATEGORIES ),
250 strval( $request->get_param( self::PARAM_DEFAULT_SERVICES_END_DATE ) )
251 )
252 )
253 ->toArray();
254 } catch ( \Throwable $e ) {
255 $this->logger->log_throwable( $e, __FUNCTION__, __CLASS__ );
256 $response = new WP_Error( 'error', $e->getMessage() );
257 }
258 return \rest_ensure_response( $response );
259 }
260
261 /**
262 * GET shop categories.
263 *
264 * @param WP_REST_Request $request The request.
265 *
266 * @return WP_REST_Response|WP_Error
267 */
268 public function get_shop_categories( WP_REST_Request $request ) {
269 $response = null;
270 try {
271 $response = AdminAPI::get()
272 ->generalSettings( strval( $request->get_param( self::PARAM_STORE_ID ) ) )
273 ->getShopCategories()
274 ->toArray();
275 } catch ( \Throwable $e ) {
276 $this->logger->log_throwable( $e, __FUNCTION__, __CLASS__ );
277 $response = new WP_Error( 'error', $e->getMessage() );
278 }
279 return \rest_ensure_response( $response );
280 }
281
282 /**
283 * GET Order Status List.
284 *
285 * @param WP_REST_Request $request The request.
286 *
287 * @return WP_REST_Response|WP_Error
288 */
289 public function get_list_order_status( WP_REST_Request $request ) {
290 $response = null;
291 try {
292 $response = AdminAPI::get()
293 ->orderStatusSettings( strval( $request->get_param( self::PARAM_STORE_ID ) ) )
294 ->getShopOrderStatuses()
295 ->toArray();
296 } catch ( \Throwable $e ) {
297 $this->logger->log_throwable( $e, __FUNCTION__, __CLASS__ );
298 $response = new WP_Error( 'error', $e->getMessage() );
299 }
300 return \rest_ensure_response( $response );
301 }
302
303 /**
304 * GET Order Status settings.
305 *
306 * @param WP_REST_Request $request The request.
307 *
308 * @return WP_REST_Response|WP_Error
309 */
310 public function get_order_status( WP_REST_Request $request ) {
311 $response = null;
312 try {
313 $response = AdminAPI::get()
314 ->orderStatusSettings( strval( $request->get_param( self::PARAM_STORE_ID ) ) )
315 ->getOrderStatusSettings()
316 ->toArray();
317 } catch ( \Throwable $e ) {
318 $this->logger->log_throwable( $e, __FUNCTION__, __CLASS__ );
319 $response = new WP_Error( 'error', $e->getMessage() );
320 }
321 return \rest_ensure_response( $response );
322 }
323
324 /**
325 * POST Order Status settings.
326 *
327 * @param WP_REST_Request $request The request.
328 *
329 * @return WP_REST_Response|WP_Error
330 */
331 public function save_order_status( WP_REST_Request $request ) {
332 if ( ! $this->validate_order_status( $request ) ) {
333 return new WP_REST_Response( 'Invalid data', 400 );
334 }
335
336 $response = null;
337 try {
338
339 /**
340 * Order status mappings.
341 *
342 * @var array<string> $order_status_mappings
343 */
344 $order_status_mappings = (array) json_decode( $request->get_body(), true );
345
346 $response = AdminAPI::get()
347 ->orderStatusSettings( strval( $request->get_param( self::PARAM_STORE_ID ) ) )
348 ->saveOrderStatusSettings( new OrderStatusSettingsRequest( $order_status_mappings ) )
349 ->toArray();
350 } catch ( \Throwable $e ) {
351 $this->logger->log_throwable( $e, __FUNCTION__, __CLASS__ );
352 $response = new WP_Error( 'error', $e->getMessage() );
353 }
354 return \rest_ensure_response( $response );
355 }
356
357 /**
358 * Validate if the parameter is a boolean.
359 *
360 * @param mixed $param The parameter.
361 * @param WP_REST_Request $request The request.
362 * @param string $key The key.
363 */
364 public function validate_array_of_product_sku( $param, $request, $key ): bool {
365 if ( ! is_array( $param ) ) {
366 return false;
367 }
368
369 foreach ( $param as $sku ) {
370 if ( ! is_string( $sku ) || '' === trim( $sku ) ) {
371 return false;
372 }
373 }
374 return true;
375 }
376
377 /**
378 * Validate if the parameter is a boolean.
379 *
380 * @param mixed $param The parameter.
381 * @param WP_REST_Request $request The request.
382 * @param string $key The key.
383 */
384 public function validate_array_of_product_cat( $param, $request, $key ): bool {
385 if ( ! is_array( $param ) ) {
386 return false;
387 }
388
389 foreach ( $param as $term_id ) {
390 if ( ! is_numeric( $term_id ) || empty( $term_id ) ) {
391 return false;
392 }
393 }
394 return true;
395 }
396
397 /**
398 * Validate if order status payload is valid.
399 *
400 * @param WP_REST_Request $request The request.
401 */
402 public function validate_order_status( WP_REST_Request $request ): bool {
403 try {
404 $data = json_decode( $request->get_body(), true );
405 if ( ! is_array( $data ) ) {
406 return false;
407 }
408 $allowed_shop_statuses = AdminAPI::get()
409 ->orderStatusSettings( strval( $request->get_param( self::PARAM_STORE_ID ) ) )
410 ->getShopOrderStatuses()
411 ->toArray();
412 $allowed_shop_statuses = array_column( $allowed_shop_statuses, 'id' );
413 $allowed_sequra_statuses = OrderStates::toArray();
414
415 foreach ( $data as $status_map ) {
416 if ( ! isset( $status_map['sequraStatus'] )
417 || ! isset( $status_map['shopStatus'] )
418 || ! is_string( $status_map['sequraStatus'] )
419 || ! is_string( $status_map['shopStatus'] )
420 || ! in_array( $status_map['sequraStatus'], $allowed_sequra_statuses, true )
421 || ! in_array( $status_map['shopStatus'], $allowed_shop_statuses, true )
422 ) {
423 return false;
424 }
425 }
426 } catch ( \Throwable $e ) {
427 return false;
428 }
429 return true;
430 }
431
432 /**
433 * Sanitize an array of ids.
434 *
435 * @param mixed[] $param The parameter.
436 * @return mixed[]
437 */
438 public function sanitize_array_of_ids( array $param ): array {
439 foreach ( $param as &$val ) {
440 $val = (string) abs( intval( $val ) );
441 }
442 return $param;
443 }
444 }
445