PluginProbe ʕ •ᴥ•ʔ
10Web Booster – Website speed optimization, Cache & Page Speed optimizer / trunk
10Web Booster – Website speed optimization, Cache & Page Speed optimizer vtrunk
2.33.0 2.30.5 2.30.7 2.30.9 2.31.10 2.31.8 2.32.11 2.32.21 2.32.3 2.32.4 2.32.7 2.6.31 2.6.40 2.6.42 2.6.7 2.7.37 2.7.44 2.7.47 2.8.18 2.8.19 2.8.32 2.8.34 2.8.35 2.9.23 2.9.24 2.9.25 2.9.27 v2.27.4 trunk 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.17 2.0.18 2.0.21 2.0.22 2.0.25 2.0.26 2.0.27 2.0.3 2.0.7 2.0.9 2.10.46 2.10.65 2.10.66 2.10.68 2.11.41 2.11.42 2.11.43 2.12.15 2.12.21 2.12.22 2.12.23 2.12.26 2.13.37 2.13.40 2.13.41 2.13.42 2.13.44 2.13.45 2.13.47 2.14.49 2.14.50 2.15.18 2.17.21 2.17.23 2.18.17 2.19.44 2.19.45 2.19.46 2.19.49 2.2.12 2.2.15 2.2.16 2.2.18 2.2.8 2.20.31 2.20.32 2.20.33 2.21.11 2.21.12 2.21.16 2.21.25 2.22.32 2.23.13 2.23.15 2.23.16 2.23.18 2.24.12 2.24.14 2.24.18 2.25.14 2.26.6 2.28.10 2.28.13 2.28.14 2.28.7 2.29.1 2.29.2 2.29.3 2.3.0 2.3.1 2.3.2 2.3.3 2.30.18
tenweb-speed-optimizer / OptimizerApi.php
tenweb-speed-optimizer Last commit date
assets 11 months ago config 2 years ago exported 4 years ago includes 2 months ago test 4 years ago vendor 1 month ago views 11 months ago .editorconfig 3 years ago OptimizerAdmin.php 1 year ago OptimizerAdminBar.php 2 years ago OptimizerApi.php 1 month ago OptimizerCli.php 1 year ago OptimizerDataRepository.php 1 year ago changelog.txt 3 years ago config.php 1 month ago env.php 1 month ago phpcs.xml 3 years ago readme.txt 1 month ago tenweb_speed_optimizer.php 1 month ago webpack.config.js 3 years ago
OptimizerApi.php
1463 lines
1 <?php
2
3 namespace TenWebOptimizer;
4
5 use Exception;
6 use Tenweb_Authorization\Login;
7 use WP_Error;
8 use WP_REST_Request;
9 use WP_REST_Response;
10
11 class OptimizerApi
12 {
13 public $modes = [];
14
15 private $OptimizerDataRepository = null;
16
17 public function __construct()
18 {
19 require __DIR__ . '/OptimizerDataRepository.php';
20 $this->OptimizerDataRepository = new \TenWebOptimizer\OptimizerDataRepository();
21
22 $this->modes = \TenWebOptimizer\OptimizerUtils::get_modes();
23 add_action('rest_api_init', [$this, 'two_rest']);
24 }
25
26 private function clear_response()
27 {
28 // Clear all unexpected output. We don't want to see a warning in rest response.
29 while (ob_get_level() !== 0) {
30 ob_end_clean();
31 }
32 }
33
34 public function two_rest()
35 {
36 register_rest_route(
37 'tenweb_so/v1',
38 'set_score',
39 [
40 'methods' => 'POST',
41 'callback' => [$this, 'set_score'],
42 'permission_callback' => [$this, 'check_authorization'],
43 'args' => [
44 'score_data' => [
45 'required' => true,
46 ],
47 ],
48 ]
49 );
50
51 register_rest_route(
52 'tenweb_so/v1',
53 'set_critical',
54 [
55 'methods' => 'POST',
56 'callback' => [$this, 'set_critical'],
57 'permission_callback' => [$this, 'check_critical_authorization'],
58 'args' => [
59 'page_id' => [
60 'type' => 'string',
61 'required' => true,
62 'validate_callback' => [$this, 'validate_page_id']
63 ],
64 'token' => [
65 'type' => 'string',
66 'required' => true,
67 'validate_callback' => [$this, 'validate_string'],
68 ],
69 ],
70 ]
71 );
72
73 register_rest_route(
74 'tenweb_so/v1',
75 'optimization_data',
76 [
77 'methods' => 'GET',
78 'callback' => [$this, 'optimization_data'],
79 'permission_callback' => [$this, 'check_authorization'],
80 'args' => [
81 ],
82 ]
83 );
84
85 register_rest_route(
86 'tenweb_so/v1',
87 'optimization_data',
88 [
89 'methods' => 'POST',
90 'callback' => [$this, 'optimization_data'],
91 'permission_callback' => [$this, 'check_authorization'],
92 'args' => [
93 ],
94 ]
95 );
96
97 register_rest_route(
98 'tenweb_so/v1',
99 'set_modes',
100 [
101 'methods' => 'POST',
102 'callback' => [$this, 'set_modes'],
103 'permission_callback' => [$this, 'check_authorization'],
104 'args' => [
105 'page_id' => [
106 'type' => 'string',
107 'required' => true,
108 'validate_callback' => [$this, 'validate_page_id']
109 ],
110 'mode' => [
111 'type' => 'string',
112 'required' => true,
113 'validate_callback' => [$this, 'validate_mode']
114 ],
115 'is_custom' => [
116 'type' => 'string',
117 'validate_callback' => [$this, 'validate_string'],
118 ],
119 ],
120 ]
121 );
122
123 register_rest_route(
124 'tenweb_so/v1',
125 'get_modes',
126 [
127 'methods' => 'GET',
128 'callback' => [$this, 'get_modes'],
129 'permission_callback' => [$this, 'check_authorization'],
130 'args' => [
131 'page_id' => [
132 'type' => 'string',
133 'required' => true,
134 'validate_callback' => [$this, 'validate_page_id']
135 ],
136 ],
137 ]
138 );
139
140 register_rest_route(
141 'tenweb_so/v1',
142 'get_modes',
143 [
144 'methods' => 'POST',
145 'callback' => [$this, 'get_modes'],
146 'permission_callback' => [$this, 'check_authorization'],
147 'args' => [
148 'page_id' => [
149 'type' => 'string',
150 'required' => true,
151 'validate_callback' => [$this, 'validate_page_id']
152 ],
153 ],
154 ]
155 );
156
157 register_rest_route(
158 'tenweb_so/v1',
159 'clear_cache',
160 [
161 'methods' => 'POST',
162 'permission_callback' => [$this, 'check_authorization'],
163 'callback' => [$this, 'clear_cache'],
164 'args' => [
165 'clear_critical' => [
166 'type' => 'boolean',
167 'required' => false,
168 'validate_callback' => [$this, 'validate_boolean'],
169 ],
170 ],
171 ]
172 );
173
174 register_rest_route(
175 'tenweb_so/v1',
176 'get_page_id',
177 [
178 'methods' => 'GET',
179 'permission_callback' => [$this, 'check_authorization'],
180 'callback' => [$this, 'get_page_id'],
181 'args' => [
182 'page_url' => [
183 'type' => 'string',
184 'required' => true,
185 'validate_callback' => [$this, 'validate_string'],
186 ],
187 ],
188 ]
189 );
190
191 register_rest_route(
192 'tenweb_so/v1',
193 'get_page_id',
194 [
195 'methods' => 'POST',
196 'permission_callback' => [$this, 'check_authorization'],
197 'callback' => [$this, 'get_page_id'],
198 'args' => [
199 'page_url' => [
200 'type' => 'string',
201 'required' => true,
202 'validate_callback' => [$this, 'validate_string'],
203 ],
204 ],
205 ]
206 );
207
208 register_rest_route(
209 'tenweb_so/v1',
210 'get_pages',
211 [
212 'methods' => 'GET',
213 'permission_callback' => [$this, 'check_authorization'],
214 'callback' => [$this, 'get_pages'],
215 ]
216 );
217
218 register_rest_route(
219 'tenweb_so/v1',
220 'get_pages',
221 [
222 'methods' => 'POST',
223 'permission_callback' => [$this, 'check_authorization'],
224 'callback' => [$this, 'get_pages'],
225 ]
226 );
227
228 register_rest_route(
229 'tenweb_so/v1',
230 'delete_so_page',
231 [
232 'methods' => 'POST',
233 'callback' => [$this, 'delete_so_page'],
234 'permission_callback' => [$this, 'check_authorization'],
235 'args' => [
236 'page_id' => [
237 'type' => 'string',
238 'required' => true,
239 'validate_callback' => [$this, 'validate_page_id']
240 ],
241 ],
242 ]
243 );
244
245 register_rest_route(
246 'tenweb_so/v1',
247 'logout',
248 [
249 'methods' => 'POST',
250 'callback' => [$this, 'logout'],
251 'permission_callback' => [$this, 'check_authorization'],
252 ]
253 );
254
255 /*
256 * Used in old connection logic with redirects and other places, do not remove
257 */
258 register_rest_route(
259 'tenweb_so/v1',
260 'check_domain',
261 [
262 'methods' => 'GET',
263 'permission_callback' => '__return_true',
264 'callback' => [$this, 'check_domain'],
265 ]
266 );
267
268 /*
269 * Used in old connection logic with redirects and other places, do not remove
270 */
271 register_rest_route(
272 'tenweb_so/v1',
273 'check_domain',
274 [
275 'methods' => 'POST',
276 'permission_callback' => '__return_true',
277 'callback' => [$this, 'check_domain'],
278 ]
279 );
280
281 /*
282 * Used in new connection logic without redirects
283 */
284 register_rest_route(
285 'tenweb_so/v1',
286 'connect_from_core',
287 [
288 'methods' => 'POST',
289 'permission_callback' => '__return_true',
290 'callback' => [$this, 'connect_from_core'],
291 ]
292 );
293
294 register_rest_route(
295 'tenweb_so/v1',
296 'get_webp_status',
297 [
298 'methods' => 'GET',
299 'callback' => [$this, 'get_webp_status'],
300 'permission_callback' => [$this, 'check_authorization'],
301 ]
302 );
303
304 register_rest_route(
305 'tenweb_so/v1',
306 'get_webp_status',
307 [
308 'methods' => 'POST',
309 'callback' => [$this, 'get_webp_status'],
310 'permission_callback' => [$this, 'check_authorization'],
311 ]
312 );
313
314 register_rest_route(
315 'tenweb_so/v1',
316 'set_webp_status',
317 [
318 'methods' => 'POST',
319 'callback' => [$this, 'set_webp_status'],
320 'permission_callback' => [$this, 'check_authorization'],
321 'args' => [
322 'webp_delivery' => [
323 'type' => 'boolean',
324 'required' => true,
325 'validate_callback' => [$this, 'validate_boolean'],
326 ],
327 'picture_webp_delivery' => [
328 'type' => 'boolean',
329 'required' => true,
330 'validate_callback' => [$this, 'validate_boolean'],
331 ],
332 ],
333 ]
334 );
335
336 register_rest_route(
337 'tenweb_so/v1',
338 'page_cache',
339 [
340 'methods' => 'POST',
341 'permission_callback' => [$this, 'check_authorization'],
342 'callback' => [$this, 'page_cache'],
343 'args' => [
344 'status' => [
345 'type' => 'boolean',
346 'required' => true,
347 'validate_callback' => [$this, 'validate_boolean'],
348 ],
349 ],
350 ]
351 );
352 register_rest_route(
353 'tenweb_so/v1',
354 'get_page_cache_status',
355 [
356 'methods' => 'GET',
357 'permission_callback' => [$this, 'check_authorization'],
358 'callback' => [$this, 'get_page_cache_status'],
359 ]
360 );
361
362 register_rest_route(
363 'tenweb_so/v1',
364 'update_settings',
365 [
366 'methods' => 'POST',
367 'callback' => [$this, 'update_settings'],
368 'permission_callback' => [$this, 'check_authorization'],
369 'args' => [
370 'key' => [
371 'type' => 'string',
372 'required' => true,
373 'validate_callback' => [$this, 'validate_string'],
374 ],
375 'val' => [
376 'type' => 'string',
377 'validate_callback' => [$this, 'validate_option_value']
378 ],
379 ],
380 ]
381 );
382
383 register_rest_route(
384 'tenweb_so/v1',
385 'get_settings',
386 [
387 'methods' => 'GET',
388 'callback' => [$this, 'get_settings'],
389 'permission_callback' => [$this, 'check_authorization'],
390 ]
391 );
392
393 register_rest_route(
394 'tenweb_so/v1',
395 'get_incompatible_active_plugins',
396 [
397 'methods' => 'GET',
398 'callback' => [$this, 'get_incompatible_active_plugins'],
399 'permission_callback' => [$this, 'check_authorization'],
400 ]
401 );
402
403 register_rest_route(
404 'tenweb_so/v1',
405 'set_cloudflare_status',
406 [
407 'methods' => 'POST',
408 'callback' => [$this, 'set_cloudflare_cache_status'],
409 'permission_callback' => [$this, 'check_authorization'],
410 'args' => [
411 'status' => [
412 'type' => 'string',
413 'required' => true,
414 'validate_callback' => [$this, 'validate_cloudflare_status']
415 ],
416 ],
417 ]
418 );
419
420 register_rest_route(
421 'tenweb_so/v1',
422 'two_settings',
423 [
424 'methods' => 'GET',
425 'callback' => [$this, 'get_two_settings'],
426 'permission_callback' => [$this, 'check_authorization'],
427 'args' => [
428 'filter' => [
429 'type' => 'string',
430 'validate_callback' => [$this, 'validate_string'],
431 ],
432 ],
433 ]
434 );
435 register_rest_route(
436 'tenweb_so/v1',
437 'two_settings',
438 [
439 'methods' => 'POST',
440 'callback' => [$this, 'set_two_settings'],
441 'permission_callback' => [$this, 'check_authorization'],
442 'args' => [
443 'settings' => [
444 'type' => 'json',
445 'required' => true,
446 ],
447 ],
448 ]
449 );
450 register_rest_route(
451 'tenweb_so/v1',
452 'regenerate_critical',
453 [
454 'methods' => 'POST',
455 'callback' => [$this, 'regenerate_critical'],
456 'permission_callback' => [$this, 'check_authorization'],
457 'args' => [
458 'page_id' => [
459 'type' => 'txt',
460 'required' => true,
461 'validate_callback' => [$this, 'validate_page_id']
462 ],
463 ],
464 ]
465 );
466
467 register_rest_route(
468 'tenweb_so/v1',
469 'regenerate_webp',
470 [
471 'methods' => 'POST',
472 'callback' => [$this, 'regenerate_home_webp'],
473 'permission_callback' => [$this, 'check_authorization'],
474 ]
475 );
476
477 register_rest_route(
478 'tenweb_so/v1',
479 'delete_webp_images',
480 [
481 'methods' => 'POST',
482 'callback' => [$this, 'delete_webp_images'],
483 'permission_callback' => [$this, 'check_authorization'],
484 ]
485 );
486 }
487
488 public function regenerate_home_webp(WP_REST_Request $request)
489 {
490 $this->clear_response();
491 $data_for_response = [
492 'success' => false,
493 'message' => 'Cannot regenerate critical',
494 ];
495
496 try {
497 $request_webp_action = OptimizerUtils::request_webp_action('regenerate');
498 $data_for_response['success'] = true;
499 $data_for_response['message'] = 'Regenerate critical started';
500 } catch (Exception $exception) {
501 $data_for_response['message'] = 'Error in regenerate critical';
502 $data_for_response['error'] = $exception->getMessage() . ' in ' . $exception->getFile() . ' on ' . $exception->getLine();
503
504 return new WP_REST_Response($data_for_response, 500);
505 }
506
507 return new WP_REST_Response($data_for_response, 200);
508 }
509
510 public function delete_webp_images(WP_REST_Request $request)
511 {
512 $this->clear_response();
513 $data_for_response = [
514 'success' => false,
515 'message' => 'Cannot regenerate critical',
516 ];
517
518 try {
519 $request_webp_action = OptimizerUtils::request_webp_action('delete');
520 $data_for_response['success'] = true;
521 $data_for_response['message'] = 'Regenerate critical started';
522 } catch (Exception $exception) {
523 $data_for_response['message'] = 'Error in regenerate critical';
524 $data_for_response['error'] = $exception->getMessage() . ' in ' . $exception->getFile() . ' on ' . $exception->getLine();
525
526 return new WP_REST_Response($data_for_response, 500);
527 }
528
529 return new WP_REST_Response($data_for_response, 200);
530 }
531
532 public function regenerate_critical(WP_REST_Request $request)
533 {
534 $this->clear_response();
535 $data_for_response = [
536 'success' => false,
537 'message' => 'Cannot regenerate critical',
538 ];
539
540 try {
541 $page_id = $request['page_id'];
542 $data_for_response['success'] = true;
543 $data_for_response['message'] = 'Regenerate critical started';
544 \TenWebOptimizer\OptimizerCriticalCss::generate_critical_css_by_id($page_id, false, 'dashboard_settings');
545 } catch (Exception $exception) {
546 $data_for_response['message'] = 'Error in regenerate critical';
547 $data_for_response['error'] = $exception->getMessage() . ' in ' . $exception->getFile() . ' on ' . $exception->getLine();
548
549 return new WP_REST_Response($data_for_response, 500);
550 }
551
552 return new WP_REST_Response($data_for_response, 200);
553 }
554
555 public function get_two_settings(WP_REST_Request $request)
556 {
557 $this->clear_response();
558 $data_for_response = [
559 'success' => false,
560 'message' => 'Cannot get settings',
561 ];
562
563 try {
564 $filter = sanitize_text_field($request['filter']);
565 $settings = $this->OptimizerDataRepository->get_settings($filter);
566
567 return new WP_REST_Response($settings, 200);
568 } catch (Exception $exception) {
569 return new WP_REST_Response($data_for_response, 500);
570 }
571 }
572
573 public function set_two_settings(WP_REST_Request $request)
574 {
575 $this->clear_response();
576 $data_for_response = [
577 'success' => false,
578 'message' => 'Cannot set option',
579 'accepted_value_error' => [],
580 ];
581
582 try {
583 global $TwoSettings;
584 $settings_names = $TwoSettings->settings_names;
585 $settings = json_decode($request['settings'], true);
586
587 if (is_array($settings)) {
588 if (isset($settings['two_bg_lazyload'])) {
589 $settings['two_img_in_viewport_lazyload'] = $settings['two_bg_lazyload'];
590 }
591
592 foreach ($settings as $key => $val) {
593 $key = sanitize_text_field($key);
594
595 if (is_array($val)) {
596 $val = array_map('sanitize_text_field', $val);
597 } else {
598 $val = sanitize_text_field($val);
599 }
600
601 if (isset($settings_names[$key])) {
602 if ($this->validate_accepted_value($settings_names[$key], $val)) {
603 if ($key === 'two_critical_status') {
604 $val = 'on' === $val ? 'true' : 'false';
605 }
606
607 $off_is_empty_string_options = [
608 'two_delay_all_js_execution',
609 'two_aggregate_js',
610 'two_minify_js',
611 'two_lazyload',
612 'two_bg_lazyload',
613 'two_aggregate_css',
614 'two_include_inline_css',
615 'two_minify_css',
616 'two_iframe_lazyload',
617 'two_video_lazyload',
618 ];
619
620 if (in_array($key, $off_is_empty_string_options) && $val === 'off') {
621 $val = '';
622 }
623 $TwoSettings->update_setting($key, $val);
624 } else {
625 $data_for_response['accepted_value_error'][$key] = $settings_names[$key]['accepted_value'];
626 }
627 }
628 }
629
630 if (!empty($data_for_response['accepted_value_error'])) {
631 return new WP_REST_Response($data_for_response, 429);
632 }
633 \TenWebOptimizer\OptimizerAdmin::clear_cache(false, true, true, true, 'front_page', false, true, true, false, '');
634 $data_for_response['success'] = true;
635 $data_for_response['message'] = 'Option updated successfully.';
636 $mode = '';
637
638 if (isset($settings['two_delay_all_js_execution']) && $settings['two_delay_all_js_execution'] == 'off') {
639 $mode = 'balanced';
640 } elseif (isset($settings['two_delay_all_js_execution']) && $settings['two_delay_all_js_execution'] == 'on') {
641 $mode = 'strong';
642 }
643
644 if (isset($settings['two_critical_status']) && $settings['two_critical_status'] == 'off') {
645 if ($mode == 'balanced') {
646 $mode = 'standard';
647 } else {
648 $mode = 'strong';
649 }
650 } elseif (isset($settings['two_critical_status']) && $settings['two_critical_status'] == 'on') {
651 if ($mode == 'strong') {
652 $mode = 'extreme';
653 }
654 }
655
656 \TenWebOptimizer\OptimizerAdmin::set_global_mode($mode);
657
658 return new WP_REST_Response($data_for_response, 200);
659 }
660 $data_for_response['message'] = 'Option name not found.';
661 $data_for_response['error'] = 'Option name not found.';
662
663 return new WP_REST_Response($data_for_response, 404);
664 } catch (Exception $exception) {
665 return new WP_REST_Response($data_for_response, 500);
666 }
667 }
668
669 public function set_cloudflare_cache_status(WP_REST_Request $request)
670 {
671 $this->clear_response();
672 $data_for_response = [
673 'success' => false,
674 'message' => 'Invalid status',
675 ];
676
677 try {
678 $status = $request['status'];
679 global $TwoSettings;
680 $TwoSettings->update_setting('cloudflare_cache_status', $status);
681 $data_for_response['success'] = true;
682 $data_for_response['message'] = 'Cloudflare status installed successfully';
683 } catch (Exception $exception) {
684 $data_for_response['message'] = 'Error in set Cloudflare status';
685 $data_for_response['error'] = $exception->getMessage() . ' in ' . $exception->getFile() . ' on ' . $exception->getLine();
686
687 return new WP_REST_Response($data_for_response, 500);
688 }
689
690 return new WP_REST_Response($data_for_response, 200);
691 }
692
693 public function optimization_data()
694 {
695 $this->clear_response();
696 $global_data = $this->OptimizerDataRepository->get_global_data();
697 $global_mode_data = $this->OptimizerDataRepository->get_modes('all');
698 $page_cache_status = $this->OptimizerDataRepository->get_page_cache_status();
699 $pages_data = $this->OptimizerDataRepository->get_pages();
700 $pages_data_custom = $this->OptimizerDataRepository->get_pages(1);
701 $incompatible_active_plugins = $this->OptimizerDataRepository->get_incompatible_active_plugins();
702 $webp_status = $this->OptimizerDataRepository->get_webp_status();
703 $return_data = [
704 'global_data' => $global_data,
705 'get_modes' => $global_mode_data,
706 'get_page_cache_status' => $page_cache_status,
707 'get_pages' => [
708 'free' => $pages_data,
709 'paid' => $pages_data_custom,
710 ],
711 'get_incompatible_active_plugins' => $incompatible_active_plugins,
712 'get_webp_status' => $webp_status,
713 ];
714
715 return new WP_REST_Response($return_data, 200);
716 }
717
718 public function set_critical()
719 {
720 $this->clear_response();
721 OptimizerUtils::set_critical();
722 }
723
724 public function get_incompatible_active_plugins()
725 {
726 $this->clear_response();
727 $incompatible_active_plugins = $this->OptimizerDataRepository->get_incompatible_active_plugins();
728
729 if ($incompatible_active_plugins['success']) {
730 return new WP_REST_Response($incompatible_active_plugins, 200);
731 }
732
733 return new WP_REST_Response($incompatible_active_plugins, 500);
734 }
735
736 public function get_settings()
737 {
738 $this->clear_response();
739 $data_for_response = [
740 'success' => false,
741 'message' => 'Cannot get settings',
742 ];
743
744 try {
745 $two_settings = get_option('two_settings');
746 $two_settings = json_decode($two_settings, true);
747 $two_critical_pages = OptimizerUtils::getCriticalPages();
748
749 if (isset($two_critical_pages) && is_array($two_critical_pages)) {
750 $two_settings['two_critical_pages'] = $two_critical_pages;
751 }
752 $two_triggerPostOptimizationTasks = get_option('two_triggerPostOptimizationTasks');
753 $data_for_response['success'] = true;
754 $data_for_response['message'] = 'Successfully';
755 $data_for_response['two_triggerPostOptimizationTasks'] = $two_triggerPostOptimizationTasks;
756 $data_for_response['settings'] = $two_settings;
757
758 return new WP_REST_Response($data_for_response, 200);
759 } catch (Exception $exception) {
760 return new WP_REST_Response($data_for_response, 500);
761 }
762 }
763
764 public function update_settings(WP_REST_Request $request)
765 {
766 $this->clear_response();
767 $data_for_response = [
768 'success' => false,
769 'message' => 'Cannot set option',
770 ];
771
772 try {
773 global $TwoSettings;
774 $settings_names = $TwoSettings->settings_names;
775 $key = sanitize_text_field($request['key']);
776
777 if (!isset($request['val'])) {
778 $option = $TwoSettings->get_settings($key);
779 $data_for_response['success'] = true;
780 $data_for_response['message'] = 'Successfully';
781 $data_for_response[$key] = $option;
782
783 return new WP_REST_Response($data_for_response, 200);
784 } else {
785 $val = sanitize_text_field($request['val']);
786 }
787
788 if (isset($settings_names[$key])) {
789 if (isset($settings_names[$key]['type']) && $settings_names[$key]['type'] === 'textarea') {
790 $option = $TwoSettings->get_settings($key);
791
792 if (!empty($option)) {
793 $arr_option = explode(',', $option);
794 $el_key = array_search($val, $arr_option, false); // phpcs:ignore
795
796 if ($el_key !== false) {
797 unset($arr_option[$el_key]);
798 $val = implode(',', $arr_option);
799 $data_for_response['success'] = true;
800 $data_for_response['message'] = 'Option deleted successfully.';
801 } else {
802 $val = $option . ',' . $val;
803 }
804 }
805 }
806
807 if (!$data_for_response['success']) {
808 $data_for_response['success'] = true;
809 $data_for_response['message'] = 'Option updated successfully.';
810 }
811 $TwoSettings->update_setting($key, $val);
812
813 return new WP_REST_Response($data_for_response, 200);
814 }
815
816 $data_for_response['message'] = 'Option name not found.';
817 $data_for_response['error'] = 'Option name not found.';
818
819 return new WP_REST_Response($data_for_response, 500);
820 } catch (Exception $exception) {
821 return new WP_REST_Response($data_for_response, 500);
822 }
823 }
824
825 /**
826 * @return WP_REST_Response
827 */
828 public function logout(WP_REST_Request $request)
829 {
830 $this->clear_response();
831 $data_for_response = [
832 'success' => false,
833 'message' => 'Cannot logout client',
834 'code' => 'not_ok'
835 ];
836
837 try {
838 \TenWebOptimizer\OptimizerAdmin::disconnect_from_tenweb(true);
839 \TenWebOptimizer\OptimizerAdmin::clear_cache(false, true);
840 $data_for_response['success'] = true;
841 $data_for_response['message'] = 'Successfully logged out';
842 $data_for_response['code'] = 'ok';
843 } catch (Exception $exception) {
844 $data_for_response['message'] = 'Error in logging out client';
845 $data_for_response['error'] = $exception->getMessage() . ' in ' . $exception->getFile() . ' on ' . $exception->getLine();
846
847 return new WP_REST_Response($data_for_response, 500);
848 }
849
850 return new WP_REST_Response($data_for_response, 200);
851 }
852
853 /**
854 * @return WP_REST_Response
855 */
856 public function get_page_cache_status(WP_REST_Request $request)
857 {
858 $this->clear_response();
859 $page_cache_status = $this->OptimizerDataRepository->get_page_cache_status();
860
861 if ($page_cache_status['success']) {
862 return new WP_REST_Response($page_cache_status, 200);
863 }
864
865 return new WP_REST_Response($page_cache_status, 500);
866 }
867
868 /**
869 * @return WP_REST_Response
870 */
871 public function page_cache(WP_REST_Request $request)
872 {
873 $this->clear_response();
874 $data_for_response = [
875 'success' => false,
876 'message' => 'Cannot change page cache status',
877 ];
878
879 try {
880 $status = $request['status'];
881 global $TwoSettings;
882
883 if ($status) {
884 $TwoSettings->update_setting('two_page_cache', 'on');
885 $data_for_response['success'] = true;
886 $data_for_response['message'] = 'Page cache enabled';
887 } else {
888 $TwoSettings->update_setting('two_page_cache', '');
889 $data_for_response['success'] = true;
890 $data_for_response['message'] = 'Page cache disabled';
891 }
892 \TenWebOptimizer\OptimizerAdmin::clear_cache(false, true);
893 } catch (Exception $exception) {
894 $data_for_response['message'] = 'Error in updating page cache status';
895 $data_for_response['error'] = $exception->getMessage() . ' in ' . $exception->getFile() . ' on ' . $exception->getLine();
896
897 return new WP_REST_Response($data_for_response, 500);
898 }
899
900 return new WP_REST_Response($data_for_response, 200);
901 }
902
903 /**
904 * @return WP_REST_Response
905 */
906 public function delete_so_page(WP_REST_Request $request)
907 {
908 $this->clear_response();
909 $data_for_response = [
910 'success' => false,
911 'message' => 'Cannot delete page',
912 ];
913
914 try {
915 global $TwoSettings;
916 $page_id = $request['page_id'];
917
918 if (OptimizerUrl::isCriticalSavedInSettings($page_id)) {
919 delete_option('two_mode_front_page');
920 $two_critical_pages = $TwoSettings->get_settings('two_critical_pages');
921 unset($two_critical_pages[$page_id], $two_critical_pages['']);
922 $TwoSettings->update_setting('two_critical_pages', $two_critical_pages);
923 } else {
924 delete_post_meta($page_id, 'two_mode');
925 delete_post_meta($page_id, 'two_critical_pages');
926 }
927
928 if (has_action('two_page_optimized_removed')) {
929 do_action('two_page_optimized_removed', $page_id);
930 }
931 $prefix = 'critical/two_' . $page_id . '_*.*';
932 \TenWebOptimizer\OptimizerUtils::delete_files_by_prefix($prefix);
933 \TenWebOptimizer\OptimizerAdmin::clear_cache(false, true);
934 //check if page from no_optimize_pages list delete the option
935 $no_optimize_pages_list = get_option('no_optimize_pages');
936
937 if (isset($no_optimize_pages_list[$page_id])) {
938 unset($no_optimize_pages_list[$page_id]);
939 update_option('no_optimize_pages', $no_optimize_pages_list);
940 }
941 $data_for_response['success'] = true;
942 $data_for_response['message'] = 'Page has been deleted';
943 OptimizerUtils::update_post();
944 } catch (Exception $exception) {
945 $data_for_response['message'] = 'Error in deleting page';
946 $data_for_response['error'] = $exception->getMessage() . ' in ' . $exception->getFile() . ' on ' . $exception->getLine();
947
948 return new WP_REST_Response($data_for_response, 500);
949 }
950
951 return new WP_REST_Response($data_for_response, 200);
952 }
953
954 /**
955 * @return WP_REST_Response
956 */
957 public function get_pages(WP_REST_Request $request)
958 {
959 $this->clear_response();
960 $is_custom = 0;
961
962 if (isset($request['is_custom'])) {
963 $is_custom = $request['is_custom'];
964 }
965 $pages_data = $this->OptimizerDataRepository->get_pages($is_custom);
966
967 if ($pages_data['success']) {
968 return new WP_REST_Response($pages_data, 200);
969 }
970
971 return new WP_REST_Response($pages_data, 500);
972 }
973
974 /**
975 * @return WP_REST_Response
976 */
977 public function check_domain(WP_REST_Request $request)
978 {
979 $this->clear_response();
980
981 if (get_site_option(TENWEB_PREFIX . '_is_available') !== '1') {
982 update_site_option(TENWEB_PREFIX . '_is_available', '1');
983 }
984 $parameters = self::wp_unslash_conditional($request->get_body_params());
985
986 if (isset($parameters['confirm_token'])) {
987 if (Login::get_instance()->checkConfirmToken($parameters['confirm_token'])) {
988 $data_for_response = [
989 'code' => 'ok',
990 'data' => 'it_was_me' // do not change
991 ];
992 $headers_for_response = ['tenweb_check_domain' => 'it_was_me'];
993 } else {
994 $data_for_response = [
995 'code' => 'ok',
996 'data' => 'it_was_not_me' // do not change
997 ];
998 $headers_for_response = ['tenweb_check_domain' => 'it_was_not_me'];
999 }
1000 } else {
1001 $data_for_response = [
1002 'code' => 'ok',
1003 'data' => 'alive' // do not change
1004 ];
1005 $headers_for_response = ['tenweb_check_domain' => 'alive'];
1006
1007 if (!\Tenweb_Authorization\Login::get_instance()->check_logged_in()) {
1008 $data_for_response['data'] = 'alive_but_not_connected';
1009 $headers_for_response['tenweb_check_domain'] = 'alive_but_not_connected'; //do not change
1010 }
1011 }
1012
1013 $tenweb_hash = $request->get_header('tenweb-check-hash');
1014
1015 if (!empty($tenweb_hash)) {
1016 $encoded = '__' . $tenweb_hash . '.';
1017 $encoded .= base64_encode(json_encode($data_for_response)); // phpcs:ignore
1018 $encoded .= '.' . $tenweb_hash . '__';
1019
1020 $data_for_response['encoded'] = $encoded;
1021 \Tenweb_Authorization\Helper::set_error_log('tenweb-check-hash', $encoded);
1022 }
1023
1024 return new WP_REST_Response($data_for_response, 200, $headers_for_response);
1025 }
1026
1027 /**
1028 * @return WP_REST_Response
1029 */
1030 public function clear_cache(WP_REST_Request $request)
1031 {
1032 $this->clear_response();
1033 $data_for_response = [
1034 'success' => false,
1035 'message' => 'Cache not cleared',
1036 ];
1037 $clear_critical = true;
1038
1039 if (isset($request['clear_critical'])) {
1040 $clear_critical = rest_sanitize_boolean($request['clear_critical']);
1041 }
1042
1043 try {
1044 \TenWebOptimizer\OptimizerUtils::two_update_subscription()['tenweb_subscription_id'];
1045 OptimizerUtils::update_post();
1046
1047 if (\TenWebOptimizer\OptimizerAdmin::clear_cache(false, true, true, true, 'front_page', $clear_critical)) {
1048 $data_for_response['success'] = true;
1049 $data_for_response['message'] = 'Cache cleared';
1050 }
1051 } catch (Exception $exception) {
1052 $data_for_response['message'] = 'Error in clearing cache';
1053 $data_for_response['error'] = $exception->getMessage() . ' in ' . $exception->getFile() . ' on ' . $exception->getLine();
1054
1055 return new WP_REST_Response($data_for_response, 500);
1056 }
1057
1058 return new WP_REST_Response($data_for_response, 200);
1059 }
1060
1061 /**
1062 * @return WP_REST_Response
1063 */
1064 public function get_modes(WP_REST_Request $request)
1065 {
1066 $this->clear_response();
1067 $page_id = $request['page_id'];
1068 $modes_data = $this->OptimizerDataRepository->get_modes($page_id);
1069
1070 if ($modes_data['success']) {
1071 return new WP_REST_Response($modes_data, 200);
1072 }
1073
1074 return new WP_REST_Response($modes_data, 500);
1075 }
1076
1077 /**
1078 * @return WP_REST_Response
1079 */
1080 public function set_modes(WP_REST_Request $request)
1081 {
1082 $this->clear_response();
1083 $data_for_response = [
1084 'success' => false,
1085 'message' => 'Invalid mode',
1086 ];
1087
1088 try {
1089 global $TwoSettings;
1090 $settings_names = $TwoSettings->settings_names;
1091 $mode = $request['mode'];
1092 $page_id = $request['page_id'];
1093 $is_custom = (int) $request['is_custom'];
1094 $no_optimize_pages_list = get_option('no_optimize_pages');
1095
1096 if ($page_id != 'all') {
1097 $post_data = OptimizerUtils::get_permalink_name_by_id($page_id);
1098 $page_url = $post_data[ 'url' ];
1099 }
1100
1101 if (isset($page_url)) {
1102 if ($mode == 'no_optimize') {
1103 if (!is_array($no_optimize_pages_list)) {
1104 $no_optimize_pages_list = [];
1105 }
1106 $no_optimize_pages_list[$page_id] = $page_url;
1107 } elseif (is_array($no_optimize_pages_list)) {
1108 unset($no_optimize_pages_list[$page_id]);
1109 }
1110 update_option('no_optimize_pages', $no_optimize_pages_list);
1111 }
1112
1113 if (isset($this->modes[$mode])) {
1114 if ($page_id == 'all') {
1115 foreach ($this->modes[$mode] as $key => $val) {
1116 if ($key === 'two_delay_all_js_execution') {
1117 if ($val) {
1118 $TwoSettings->update_setting('two_delay_all_js_execution', 'on');
1119 } else {
1120 $TwoSettings->update_setting('two_delay_all_js_execution', '');
1121 }
1122 } elseif (isset($settings_names[$key])) {
1123 $TwoSettings->update_setting($key, $val);
1124 } elseif ($key === 'critical_enabled') {
1125 if ($val) {
1126 $TwoSettings->update_setting('two_critical_status', 'true');
1127 } else {
1128 $TwoSettings->update_setting('two_critical_status', '');
1129 }
1130 }
1131 }
1132 update_option('two_default_mode', $this->modes[$mode]);
1133 } else {
1134 OptimizerCriticalCss::generate_critical_css_by_id($page_id, false, 'from_api');
1135 $this->modes[$mode]['is_custom'] = 0;
1136
1137 if ($is_custom === 1) {
1138 $this->modes[$mode]['is_custom'] = 1;
1139 }
1140
1141 if ($page_id === 'front_page') {
1142 update_option('two_mode_front_page', $this->modes[$mode]);
1143 } elseif (false !== strpos($page_id, 'term_')) {
1144 $term_id = (int) ltrim($page_id, 'term_');
1145 update_term_meta($term_id, 'two_mode', $this->modes[$mode]);
1146 } elseif (false !== strpos($page_id, 'user_')) {
1147 $user_id = (int) ltrim($page_id, 'user_');
1148 update_user_meta($user_id, 'two_mode', $this->modes[$mode]);
1149 } else {
1150 update_post_meta($page_id, 'two_mode', $this->modes[$mode]);
1151 }
1152 }
1153 OptimizerUtils::update_post();
1154 $data_for_response['success'] = true;
1155 $data_for_response['message'] = 'Mode installed successfully';
1156 } else {
1157 return new WP_REST_Response($data_for_response, 404);
1158 }
1159
1160 \TenWebOptimizer\OptimizerAdmin::clear_cache(false, true);
1161 } catch (Exception $exception) {
1162 $data_for_response['message'] = 'Error in applying page';
1163 $data_for_response['error'] = $exception->getMessage() . ' in ' . $exception->getFile() . ' on ' . $exception->getLine();
1164
1165 return new WP_REST_Response($data_for_response, 500);
1166 }
1167
1168 return new WP_REST_Response($data_for_response, 200);
1169 }
1170
1171 /**
1172 * @return WP_REST_Response
1173 */
1174 public function get_webp_status(WP_REST_Request $request)
1175 {
1176 $this->clear_response();
1177 $webp_status = $this->OptimizerDataRepository->get_webp_status();
1178
1179 if ($webp_status['success']) {
1180 return new WP_REST_Response($webp_status, 200);
1181 } else {
1182 return new WP_REST_Response($webp_status, 500);
1183 }
1184 }
1185
1186 /**
1187 * @return WP_REST_Response
1188 */
1189 public function set_webp_status(WP_REST_Request $request)
1190 {
1191 $this->clear_response();
1192 $data_for_response = [
1193 'success' => false,
1194 'message' => 'Nothing to change',
1195 ];
1196
1197 try {
1198 global $TwoSettings;
1199 $webp_delivery = $request['webp_delivery'] ? 'on' : '';
1200 $picture_webp_delivery = $request['picture_webp_delivery'] ? 'on' : '';
1201
1202 if ($TwoSettings->get_settings('two_enable_picture_webp_delivery') != $picture_webp_delivery) {
1203 $TwoSettings->update_setting('two_enable_picture_webp_delivery', $picture_webp_delivery);
1204 $data_for_response['success'] = true;
1205 }
1206
1207 if (TENWEB_SO_HOSTED_ON_10WEB) {
1208 if ($TwoSettings->get_settings('two_enable_nginx_webp_delivery') != $webp_delivery) {
1209 $TwoSettings->update_setting('two_enable_nginx_webp_delivery', $webp_delivery);
1210 $data_for_response['success'] = true;
1211 }
1212 } elseif (!TENWEB_SO_HOSTED_ON_NGINX && TENWEB_SO_HTACCESS_WRITABLE) {
1213 if ($TwoSettings->get_settings('two_enable_htaccess_webp_delivery') != $webp_delivery) {
1214 $TwoSettings->update_setting('two_enable_htaccess_webp_delivery', $webp_delivery);
1215 $data_for_response['success'] = true;
1216 }
1217 }
1218
1219 if ($data_for_response['success']) {
1220 $code = apply_filters('two_save_settings_code', 0);
1221
1222 if ('nginx_webp_delivery' === $code) {
1223 $data_for_response['config_changed'] = false;
1224 } else {
1225 $data_for_response['config_changed'] = true;
1226 }
1227 $data_for_response['message'] = 'WebP status changed successfully';
1228 }
1229 \TenWebOptimizer\OptimizerAdmin::clear_cache(false, true);
1230 } catch (Exception $exception) {
1231 $data_for_response['message'] = 'Error in setting webp status';
1232 $data_for_response['error'] = $exception->getMessage() . ' in ' . $exception->getFile() . ' on ' . $exception->getLine();
1233
1234 return new WP_REST_Response($data_for_response, 500);
1235 }
1236
1237 return new WP_REST_Response($data_for_response, 200);
1238 }
1239
1240 /**
1241 * @return WP_REST_Response
1242 */
1243 public function get_page_id(WP_REST_Request $request)
1244 {
1245 $this->clear_response();
1246 $data_for_response = [
1247 'success' => false,
1248 'message' => 'Invalid url',
1249 ];
1250
1251 try {
1252 $check_redirect = \TenWebOptimizer\OptimizerUtils::check_page_has_no_redirects($request['page_url']);
1253
1254 if ($check_redirect) {
1255 $page_id = \TenWebOptimizer\OptimizerUtils::get_post_id($request['page_url']);
1256
1257 if ($page_id) {
1258 $data_for_response['success'] = true;
1259 $data_for_response['message'] = 'Page found successfully';
1260 $data_for_response['page_id'] = $page_id;
1261 } else {
1262 $data_for_response['message'] = 'Page not found';
1263
1264 return new WP_REST_Response($data_for_response, 404);
1265 }
1266 } else {
1267 $data_for_response['message'] = 'Url has redirect';
1268
1269 return new WP_REST_Response($data_for_response, 400);
1270 }
1271 } catch (Exception $exception) {
1272 $data_for_response['message'] = 'Error in getting pageId';
1273 $data_for_response['error'] = $exception->getMessage() . ' in ' . $exception->getFile() . ' on ' . $exception->getLine();
1274
1275 return new WP_REST_Response($data_for_response, 500);
1276 }
1277
1278 return new WP_REST_Response($data_for_response, 200);
1279 }
1280
1281 public function set_score(WP_REST_Request $request)
1282 {
1283 $score_data = $request->get_param('score_data');
1284 $two_front_page_speed = get_option('two-front-page-speed', []);
1285
1286 if (isset($score_data['previous_score'])) {
1287 $two_front_page_speed['previous_score'] = $score_data['previous_score'];
1288 } elseif ($score_data['current_score']) {
1289 $two_front_page_speed['current_score'] = $score_data['current_score'];
1290 }
1291 update_option('two-front-page-speed', $two_front_page_speed, false);
1292 }
1293
1294 public function check_critical_authorization(WP_REST_Request $request)
1295 {
1296 $token = $request->get_param('token');
1297 $page_id = $request->get_param('page_id');
1298
1299 return isset($token, $page_id) && get_option('two_critical' . $page_id) === $token;
1300 }
1301
1302 public function validate_mode($param, $request, $key)
1303 {
1304 return isset($this->modes[$param]);
1305 }
1306
1307 public function validate_option_value($param, $request, $key)
1308 {
1309 global $TwoSettings;
1310 $valid_params = [
1311 '',
1312 'on',
1313 'off',
1314 'true',
1315 'false',
1316 '1',
1317 '0',
1318 'vanilla',
1319 'browser',
1320 ];
1321 $settings_names = $TwoSettings->settings_names;
1322 $option_name = sanitize_text_field($request['key']);
1323
1324 if (isset($settings_names[$option_name])) {
1325 if (isset($settings_names[$option_name]['type']) && $settings_names[$option_name]['type'] === 'textarea') {
1326 return true;
1327 }
1328 $el_key = in_array($param, $valid_params, false); // phpcs:ignore
1329
1330 if ($el_key !== false) {
1331 return true;
1332 }
1333 }
1334
1335 return false;
1336 }
1337
1338 public function validate_page_id($param, $request, $key)
1339 {
1340 return $param === 'front_page' || $param === 'all' || (int) ($param) > 0 || (false !== strpos($param, 'term_') && (int) (ltrim($param, 'term_')) > 0) || (false !== strpos($param, 'user_') && (int) (ltrim($param, 'user_')) > 0);
1341 }
1342
1343 public function validate_cloudflare_status($param, $request, $key)
1344 {
1345 if ($param == 'on' || $param == 'off') {
1346 return true;
1347 }
1348
1349 return false;
1350 }
1351
1352 public function check_authorization(WP_REST_Request $request)
1353 {
1354 if (!\Tenweb_Authorization\Login::get_instance()->check_logged_in()) {
1355 $data_for_response = [
1356 'code' => 'unauthorized',
1357 'message' => 'unauthorized',
1358 'data' => [
1359 'status' => 401
1360 ]
1361 ];
1362
1363 return new WP_Error('rest_forbidden', $data_for_response, 401);
1364 }
1365 add_filter('http_request_args', [$this, 'add_booster_version'], 10, 2); // phpcs:ignore
1366 $authorize = \Tenweb_Authorization\Login::get_instance()->authorize($request);
1367
1368 if (is_array($authorize)) {
1369 return new WP_Error('rest_forbidden', $authorize, 401);
1370 }
1371
1372 return true;
1373 }
1374
1375 public function validate_string($param, $request, $key)
1376 {
1377 return is_string($param);
1378 }
1379
1380 public function validate_boolean($param, $request, $key)
1381 {
1382 //axios which sents requests to this uses application/x-www-form-urlencoded, and converts all bools to string
1383 //example: false gets converted to 'false' and true to 'true'
1384 //so we convert that to actual bool and pass downstream
1385 $param = filter_var($param, FILTER_VALIDATE_BOOLEAN);
1386
1387 return is_bool($param);
1388 }
1389
1390 private function validate_accepted_value($option, $val)
1391 {
1392 if (isset($option['accepted_value'])) {
1393 if ($option['accepted_value'] == 'array') {
1394 return is_array($val);
1395 } elseif (is_array($option['accepted_value'])) {
1396 return in_array($val, $option['accepted_value']);
1397 }
1398 // ignore string
1399 }
1400
1401 return true;
1402 }
1403
1404 /*
1405 * wp 4.4 adds slashes, removes them
1406 *
1407 * https://core.trac.wordpress.org/ticket/36419
1408 **/
1409 private static function wp_unslash_conditional($data)
1410 {
1411 global $wp_version;
1412
1413 if ($wp_version < 4.5) {
1414 $data = wp_unslash($data);
1415 }
1416
1417 return $data;
1418 }
1419
1420 /**
1421 * Add manager_version to POST data to avoid blocking it in manager plugin
1422 *
1423 * @return array
1424 */
1425 public function add_booster_version($args, $url)
1426 {
1427 if (is_array($args['body'])) {
1428 $args['body']['manager_version'] = TENWEB_VERSION;
1429 $args['body']['other_data']['manager_version'] = TENWEB_VERSION;
1430 }
1431
1432 return $args;
1433 }
1434
1435 public function connect_from_core(WP_REST_Request $request)
1436 {
1437 $this->clear_response();
1438 $data_for_response = [];
1439 $headers_for_response = [];
1440 $parameters = self::wp_unslash_conditional($request->get_body_params());
1441
1442 if (isset($parameters['nonce'])) {
1443 $saved_nonce = get_site_option(TW_OPTIMIZE_PREFIX . '_saved_nonce');
1444
1445 if ($parameters['nonce'] === $saved_nonce) {
1446 delete_site_option(TW_OPTIMIZE_PREFIX . '_saved_nonce');
1447 \TenWebOptimizer\OptimizerAdmin::get_instance()->connect_to_tenweb($parameters); //no need for response because of die() call inside
1448 } else {
1449 $data_for_response = [
1450 'code' => 'ok',
1451 'data' => 'it_was_not_me' // do not change
1452 ];
1453 $headers_for_response = ['tenweb_connect_from_core' => 'it_was_not_me'];
1454 delete_site_option(TW_OPTIMIZE_PREFIX . '_saved_nonce');
1455 }
1456 } else {
1457 $headers_for_response = ['tenweb_connect_from_core' => 'it_was_not_me'];
1458 }
1459
1460 return new WP_REST_Response($data_for_response, 200, $headers_for_response);
1461 }
1462 }
1463