PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 5.9.0
Defender Security – Malware Scanner, Login Security & Firewall v5.9.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / src / controller / class-antibot-global-firewall.php

class-antibot-global-firewall.php in Defender Security – Malware Scanner, Login Security & Firewall 5.9.0, at src/controller/class-antibot-global-firewall.php

737 lines 20.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * It handles functionalities such as saving settings and handle the request for downloading the IPs from AntiBot Global Firewall.
4 *
5 * @package WP_Defender\Controller
6 */
7
8 namespace WP_Defender\Controller;
9
10 use Calotes\Component\Request;
11 use Calotes\Component\Response;
12 use WP_Defender\Component\Network_Cron_Manager;
13 use WP_Defender\Component\Config\Config_Hub_Helper;
14 use WP_Defender\Event;
15 use WP_Defender\Traits\Setting;
16 use WP_Defender\Traits\Defender_Dashboard_Client;
17 use WP_Defender\Model\Setting\Antibot_Global_Firewall_Setting;
18 use WP_Defender\Behavior\WPMUDEV;
19 use WP_Defender\Component\IP\Antibot_Global_Firewall as Antibot_Global_Firewall_Component;
20 use WP_Defender\Component\Blacklist_Lockout;
21 use WP_Defender\Component\IP\Global_IP;
22 use WP_Defender\Component\Scheduler\Scheduler;
23 use WP_Defender\Helper\Analytics\Antibot as Antibot_Analytics;
24
25 /**
26 * Class Antibot_Global_Firewall.
27 */
28 class Antibot_Global_Firewall extends Event {
29 use Setting;
30 use Defender_Dashboard_Client;
31
32 /**
33 * The slug identifier for this controller.
34 *
35 * @var string
36 */
37 protected $slug = 'wdf-ip-lockout';
38
39 /**
40 * The model for handling AntiBot Global Firewall settings.
41 *
42 * @var Antibot_Global_Firewall_Setting
43 */
44 protected $model;
45
46 /**
47 * The service for handling AntiBot Global Firewall logic.
48 *
49 * @var Antibot_Global_Firewall_Component
50 */
51 protected $service;
52
53 /**
54 * The WPMUDEV instance.
55 *
56 * @var WPMUDEV
57 */
58 private $wpmudev;
59
60 /**
61 * Initializes the class with model and service.
62 *
63 * @param Antibot_Global_Firewall_Setting $model The model for handling AntiBot Global Firewall settings.
64 * @param Antibot_Global_Firewall_Component $service The service for handling AntiBot Global Firewall logic.
65 * @param WPMUDEV $wpmudev The WPMUDEV instance.
66 */
67 public function __construct( Antibot_Global_Firewall_Setting $model, Antibot_Global_Firewall_Component $service, WPMUDEV $wpmudev ) {
68 $this->register_routes();
69 add_action( 'defender_enqueue_assets', array( $this, 'enqueue_assets' ) );
70
71 $this->model = $model;
72 $this->service = $service;
73 $this->wpmudev = $wpmudev;
74
75 add_action( 'wpmudev_hub_connector_first_sync_completed', array( $this, 'maybe_hcm_connection_attempt' ) );
76
77 /**
78 * Download and store Blocklist from the API.
79 */
80 if ( $this->service->is_active_via_plugin() ) {
81 /**
82 * Network Cron Manager
83 *
84 * @var Network_Cron_Manager $network_cron_manager
85 */
86 $network_cron_manager = wd_di()->get( Network_Cron_Manager::class );
87 $network_cron_manager->register_callback(
88 'wpdef_antibot_global_firewall_fetch_blocklist',
89 array( $this, 'handle_download_and_store_blocklist' ),
90 12 * HOUR_IN_SECONDS,
91 time() + 15
92 );
93 } elseif ( wp_next_scheduled( 'wpdef_antibot_global_firewall_fetch_blocklist' ) ) {
94 wp_clear_scheduled_hook( 'wpdef_antibot_global_firewall_fetch_blocklist' );
95 }
96
97 if ( $this->wpmudev->is_wpmu_hosting() ) {
98 add_action( 'init', array( $this, 'sync_state' ) );
99 }
100 add_action( 'init', array( $this, 'handle_expired_membership' ) );
101 add_action( 'init', array( $this->service, 'maybe_set_notice_time' ) );
102 }
103
104 /**
105 * Handle request to save settings.
106 *
107 * @param Request $request The request object.
108 *
109 * @defender_route
110 * @return Response
111 */
112 public function save_settings( Request $request ) {
113 $data = $request->get_data(
114 array(
115 'enabled' => array( 'type' => 'bool' ),
116 'managed_by' => array( 'type' => 'string' ),
117 // Temporary property.
118 'module_title' => array(
119 'type' => 'string',
120 'sanitize' => 'sanitize_text_field',
121 ),
122 'module_location' => array(
123 'type' => 'string',
124 'sanitize' => 'sanitize_text_field',
125 ),
126 'redirect_to_feature_page' => array( 'type' => 'bool' ),
127 // End.
128 )
129 );
130 $old_enabled = $this->model->enabled;
131
132 $location = 'Feature Page';
133 // Split module's titles and locations.
134 if ( isset( $data['module_title'] ) && 'antibot' === $data['module_title'] ) {
135 if ( ! isset( $data['module_location'] ) || '' === $data['module_location'] ) {
136 $location = 'Dashboard';
137 } else {
138 $location = $data['module_location'];
139 unset( $data['module_location'] );
140 }
141 unset( $data['module_title'] );
142 }
143
144 $this->model->import( $data );
145 if ( $this->model->validate() ) {
146 $this->model->save();
147
148 if ( 'plugin' === $this->service->get_managed_by() ) {
149 if ( $old_enabled !== $this->model->enabled ) {
150 if ( ! $this->model->enabled ) {
151 $this->service->delete_blocklist();
152 } elseif ( $this->model->enabled && $this->service->maybe_download() ) {
153 $this->service->download_and_store_blocklist();
154 }
155 }
156 } else {
157 $old_enabled = $this->service->frontend_is_enabled();
158 $result = $this->service->toggle_on_hosting( $this->model->enabled );
159
160 if ( is_wp_error( $result ) ) {
161 return new Response(
162 false,
163 array( 'message' => esc_html__( 'Something wrong happened, please try again!', 'defender-security' ) )
164 );
165 }
166 }
167
168 Config_Hub_Helper::set_clear_active_flag();
169
170 // Hide the Antibot notice on the Dashboard page.
171 if ( isset( $data['enabled'] ) && true === (bool) $data['enabled'] ) {
172 delete_site_option( Antibot_Global_Firewall_Component::NOTICE_SLUG );
173 }
174 // Maybe track.
175 if ( ! defender_is_wp_cli() && $old_enabled !== $data['enabled'] ) {
176 wd_di()->get( Antibot_Analytics::class )->track_antibot( $old_enabled, $location );
177 }
178
179 $update_message = $this->get_update_message( $data, $old_enabled, Antibot_Global_Firewall_Setting::get_module_name() );
180 $referrer = wp_get_referer();
181 if ( $referrer && strpos( $referrer, 'page=wp-defender' ) !== false ) {
182 $update_message = sprintf(
183 /* translators: 1: Bold open tag, 2: Bold close tag */
184 __( '%s is now enabled.', 'defender-security' ),
185 '<strong>' . Antibot_Global_Firewall_Setting::get_module_name() . '</strong>'
186 );
187 }
188
189 $data_frontend = $this->data_frontend();
190
191 if ( isset( $data['redirect_to_feature_page'] ) && $data['redirect_to_feature_page'] ) {
192 $data_frontend['redirect'] = network_admin_url( 'admin.php?page=wdf-ip-lockout' );
193 }
194
195 return new Response(
196 true,
197 array_merge(
198 array(
199 'message' => $update_message,
200 'auto_close' => true,
201 ),
202 $data_frontend
203 )
204 );
205 }
206
207 return new Response(
208 false,
209 array( 'message' => $this->model->get_formatted_errors() )
210 );
211 }
212
213 /**
214 * Hide the Antibot notice.
215 *
216 * @return Response
217 * @defender_route
218 */
219 public function hide_antibot_notice(): Response {
220 delete_site_option( Antibot_Global_Firewall_Component::NOTICE_SLUG );
221
222 return new Response( true, array() );
223 }
224
225 /**
226 * Queue assets and require data.
227 *
228 * @return void
229 */
230 public function enqueue_assets() {
231 if ( $this->is_page_active() ) {
232 wp_localize_script( 'def-iplockout', 'antibot', $this->data_frontend() );
233 }
234 }
235
236 /**
237 * All the variables that we will show on frontend, both in the main page, or dashboard widget.
238 *
239 * @return array
240 */
241 public function data_frontend(): array {
242 /**
243 * Show the onboarding reminder notice if:
244 * 1. If the reminder time is set and the time difference is greater than a week.
245 * 2. No click on the Cross icon before.
246 */
247 $is_reminder = false;
248 $last_reminder = (int) get_site_option( Onboard::REMINDER_KEY, 0 );
249 if ( $last_reminder > 0 ) {
250 $time_diff = time() - $last_reminder;
251 if ( $time_diff > WEEK_IN_SECONDS ) {
252 $is_reminder = true;
253 }
254 }
255
256 $model_export = $this->model->export();
257 $model_export['managed_by'] = $this->service->get_managed_by();
258 $module_name = Antibot_Global_Firewall_Setting::get_module_name();
259
260 return array_merge(
261 array(
262 'model' => $model_export,
263 'misc' => array(
264 'module_slug' => Antibot_Global_Firewall_Setting::get_module_slug(),
265 'module_name' => $module_name,
266 'show_notice' => $is_reminder
267 && (bool) get_site_option( Antibot_Global_Firewall_Component::NOTICE_SLUG, false ),
268 'sync_schedule' => __( 'Twice Daily', 'defender-security' ),
269 'ips_count' => $this->service->get_blocklisted_ip_count(),
270 'frontend_is_enabled' => $this->service->frontend_is_enabled(),
271 'frontend_mode' => $this->service->frontend_mode(),
272 'is_active' => $this->service->is_active(),
273 'show_stats_button' => ! $this->wpmudev->is_whitelabel_enabled(),
274 'show_checker' => ! $this->wpmudev->is_wpmu_hosting()
275 || $this->wpmudev->is_wpmu_dev_admin()
276 || ! ( $this->service->is_active_via_hosting() && $this->wpmudev->is_whitelabel_enabled() ),
277 'active_tooltip_text' => __( 'List of exploit attempts detected and blocked across all connected sites by AntiBot Firewall.', 'defender-security' ),
278 'inactive_tooltip_text' => sprintf(
279 /* translators: %s: Module name. */
280 __( '%s is Inactive.', 'defender-security' ),
281 $module_name
282 ),
283 'current_user' => esc_html( wp_get_current_user()->display_name ?? __( 'User', 'defender-security' ) ),
284 'current_plan' => $this->get_membership_type(),
285 'is_expired_membership' => $this->is_expired_membership_type(),
286 'should_show_global_notice' => $this->service->should_show_global_notice(),
287 ),
288 ),
289 $this->dump_routes_and_nonces()
290 );
291 }
292
293 /**
294 * Download and store blocklist.
295 *
296 * @return void
297 */
298 public function handle_download_and_store_blocklist(): void {
299 if ( is_multisite() ) {
300 $next_run = (int) get_site_option( Antibot_Global_Firewall_Component::DOWNLOAD_SYNC_NEXT_RUN_OPTION, 0 );
301 if ( $next_run > 0 && $next_run > time() ) {
302 return;
303 }
304
305 $interval = (int) wd_di()->get( Scheduler::class )->get_cron_schedule_interval( Antibot_Global_Firewall_Component::DOWNLOAD_SYNC_SCHEDULE );
306 $next_run = time() + ( $interval > 0 ? $interval : 12 * HOUR_IN_SECONDS );
307 update_site_option( Antibot_Global_Firewall_Component::DOWNLOAD_SYNC_NEXT_RUN_OPTION, $next_run );
308 }
309
310 if ( true === $this->service->is_active_via_plugin() ) {
311 $is_switch_to_main_site = is_multisite() && ! is_main_site();
312 if ( $is_switch_to_main_site ) {
313 switch_to_blog( get_main_site_id() );
314 }
315
316 $this->service->download_and_store_blocklist();
317
318 if ( $is_switch_to_main_site ) {
319 restore_current_blog();
320 }
321 }
322 }
323
324 /**
325 * Handle the HCM connection attempt via Antibot page.
326 *
327 * @return void
328 */
329 public function maybe_hcm_connection_attempt() {
330 $data = get_site_transient( Hub_Connector::TRANSIENT_KEY );
331 $module_slug = $data['module_slug'] ?? '';
332
333 if ( Antibot_Global_Firewall_Setting::get_module_slug() === $module_slug && self::get_status() ) {
334 delete_site_transient( Hub_Connector::TRANSIENT_KEY );
335
336 if ( 'plugin' === $this->service->get_managed_by() ) {
337 $this->service->managed_by_plugin_action();
338 } else {
339 $this->service->managed_by_hosting_action();
340 }
341 }
342 }
343
344 /**
345 * Export the data of this module, we will use this for export to HUB, create a preset etc.
346 *
347 * @return array
348 */
349 public function to_array(): array {
350 return array();
351 }
352
353 /**
354 * Import the data from the HUB, or from the preset.
355 *
356 * @param array $data The data to be imported.
357 *
358 * @return void
359 */
360 public function import_data( $data ) {
361 $model = $this->model;
362 if ( isset( $data['antibot'] ) ) {
363 $model->enabled = (bool) $data['antibot'];
364 } else {
365 $model->enabled = true;
366 }
367 $model->save();
368 }
369
370 /**
371 * Remove all settings, configs generated in this container runtime.
372 */
373 public function remove_settings() {}
374
375 /**
376 * Remove all data.
377 */
378 public function remove_data() {
379 $this->service->delete_blocklist();
380
381 delete_site_option( Antibot_Global_Firewall_Component::NOTICE_SLUG );
382 delete_site_option( Antibot_Global_Firewall_Component::DOWNLOAD_SYNC_NEXT_RUN_OPTION );
383 delete_site_option( Antibot_Global_Firewall_Component::GLOBAL_NOTICE_TIME_OPTION );
384 delete_site_transient( Antibot_Global_Firewall_Component::BLOCKLIST_STATS_KEY . '_' . Antibot_Global_Firewall_Setting::MODE_BASIC );
385 delete_site_transient( Antibot_Global_Firewall_Component::BLOCKLIST_STATS_KEY . '_' . Antibot_Global_Firewall_Setting::MODE_STRICT );
386 delete_site_transient( Antibot_Global_Firewall_Component::IS_SWITCHING_TO_PLUGIN_IN_PROGRESS );
387 }
388
389 /**
390 * Export strings.
391 *
392 * @return array
393 */
394 public function export_strings() {
395 return array();
396 }
397
398 /**
399 * Handle request to switch managed by.
400 *
401 * @defender_route
402 * @return Response
403 */
404 public function switch_managed_by(): Response {
405 $result = $this->service->switch_managed_by();
406 if ( false !== $result ) {
407 return new Response(
408 true,
409 array(
410 'message' => sprintf(
411 /* translators: 1. Open tag. 2. Close tag. 3. Managed by label. */
412 __( '%1$sAntiBot%2$s blocklist is now being managed by %3$s.', 'defender-security' ),
413 '<strong>',
414 '</strong>',
415 $this->service->get_managed_by_label()
416 ),
417 'managed_by' => $result,
418 'frontend_mode' => $this->service->frontend_mode(),
419 'ips_count' => $this->service->get_blocklisted_ip_count(),
420 'auto_close' => true,
421 )
422 );
423 }
424
425 return new Response(
426 false,
427 array(
428 'message' => __( 'Failed to switch. Please try again.', 'defender-security' ),
429 'auto_close' => true,
430 )
431 );
432 }
433
434 /**
435 * Various actions during form submission.
436 *
437 * @param Request $request The HTTP request object.
438 *
439 * @defender_route
440 * @return Response
441 */
442 public function blocklist_checker_submit_trusted_ip_form( Request $request ): Response {
443 $data = $request->get_data(
444 array(
445 'ip' => array(
446 'type' => 'string',
447 'sanitize' => 'sanitize_text_field',
448 ),
449 'email' => array(
450 'type' => 'string',
451 'sanitize' => 'sanitize_text_field',
452 ),
453 'service' => array(
454 'type' => 'string',
455 'sanitize' => 'sanitize_text_field',
456 ),
457 'reason' => array(
458 'type' => 'string',
459 'sanitize' => 'sanitize_text_field',
460 ),
461 )
462 );
463 // Logging.
464 $message = sprintf(
465 'IP: %s, email: %s, service: %s, reason: %s',
466 $data['ip'],
467 $data['email'],
468 $data['service'],
469 $data['reason']
470 );
471 $this->service->log_ip_message( $message );
472
473 return new Response( true, array() );
474 }
475
476 /**
477 * Check if an IP exists in the Local, Custom and AntiBot blocklist.
478 *
479 * @param Request $request The HTTP request object.
480 *
481 * @defender_route
482 * @return Response
483 */
484 public function blocklist_checker_search( Request $request ): Response {
485 $data = $request->get_data(
486 array(
487 'ip' => array(
488 'type' => 'string',
489 'sanitize' => 'sanitize_text_field',
490 ),
491 )
492 );
493
494 if ( false === filter_var( $data['ip'], FILTER_VALIDATE_IP ) ) {
495 return new Response(
496 false,
497 array(
498 'success' => false,
499 'show_notice' => false,
500 'message' => __( 'Invalid IP address.', 'defender-security' ),
501 )
502 );
503 }
504
505 $bl_service = wd_di()->get( Blacklist_Lockout::class );
506 $gi_service = wd_di()->get( Global_IP::class );
507
508 return new Response(
509 true,
510 array(
511 'success' => true,
512 'show_notice' => false,
513 'message' => __( 'The IP address is searched successfully.', 'defender-security' ),
514 'local' => $bl_service->is_blacklist( $data['ip'] ),
515 'central' => $gi_service->is_global_ip_enabled() && $gi_service->is_ip_blocked( $data['ip'] ),
516 'antibot' => $this->service->is_ip_blocked( $data['ip'] ),
517 )
518 );
519 }
520
521 /**
522 * Add IP to AntiBot allowlist.
523 *
524 * @param Request $request The HTTP request object.
525 *
526 * @defender_route
527 * @return Response
528 */
529 public function blocklist_checker_add_ip_to_allowlist( Request $request ): Response {
530 $data = $request->get_data(
531 array(
532 'ip' => array(
533 'type' => 'string',
534 'sanitize' => 'sanitize_text_field',
535 ),
536 )
537 );
538 $ip = $data['ip'];
539 if ( false === filter_var( $ip, FILTER_VALIDATE_IP ) ) {
540 return new Response(
541 false,
542 array(
543 'message' => esc_html__( 'Invalid IP address.', 'defender-security' ),
544 )
545 );
546 }
547 $collection = 'allowlist';
548 // Add to Local allowlist.
549 $model = wd_di()->get( \WP_Defender\Model\Setting\Blacklist_Lockout::class );
550 if ( ! $model->is_ip_in_list( $ip, $collection ) ) {
551 $model->add_to_list( $ip, $collection );
552 }
553 // Add to Custom IP allowlist.
554 $global_ip_service = wd_di()->get( Global_IP::class );
555 if ( $global_ip_service->can_central_ip_autosync() ) {
556 $data = array(
557 'allow_list' => array( $ip ),
558 );
559
560 $res = $global_ip_service->add_to_global_ip_list( $data );
561 if ( is_wp_error( $res ) ) {
562 return new Response(
563 false,
564 array(
565 'message' => $res->get_error_message(),
566 )
567 );
568 }
569 }
570
571 return new Response(
572 true,
573 array(
574 'message' => sprintf(
575 /* translators: 1: IP address. 2: Opening anchor tag. 3: Closing anchor tag. */
576 esc_html__(
577 'IP %1$s has been added to your Site\'s allowlist. You can manage it in %2$sIP Lockouts%3$s.',
578 'defender-security'
579 ),
580 $ip,
581 '<a href="' . network_admin_url( 'admin.php?page=wdf-ip-lockout&view=blocklist#tab-ip-allowlist' ) . '">',
582 '</a>'
583 ),
584 'interval' => 5,
585 )
586 );
587 }
588
589 /**
590 * Sync AntiBot status with Hosting.
591 * If AntiBot is enabled in Hosting, update the 'managed_by' and 'enabled' status.
592 * If AntiBot is disabled in Hosting, do nothing.
593 *
594 * @return void
595 */
596 public function sync_state(): void {
597 $hosting_enabled = defender_get_hosting_feature_state( 'antibot' );
598
599 if (
600 true === $hosting_enabled
601 && 'plugin' === $this->model->managed_by
602 && true !== get_site_transient( Antibot_Global_Firewall_Component::IS_SWITCHING_TO_PLUGIN_IN_PROGRESS )
603 ) {
604 $this->model->enabled = false;
605 $this->model->managed_by = 'hosting';
606 $this->model->save();
607 }
608 }
609
610 /**
611 * Handle request to switch mode.
612 *
613 * @defender_route
614 * @return Response
615 */
616 public function switch_mode(): Response {
617 $result = $this->process_switch_mode();
618 if ( $result['success'] ) {
619 if ( $this->maybe_track() ) {
620 wd_di()->get( Antibot_Analytics::class )->track_antibot( false, 'Feature Page' );
621 }
622 return new Response( true, $result['data'] );
623 }
624
625 return new Response( false, $result['data'] );
626 }
627
628 /**
629 * Process request to switch mode.
630 *
631 * @return array
632 */
633 public function process_switch_mode(): array {
634 $result = $this->service->switch_mode();
635 if ( false !== $result && ! is_wp_error( $result ) ) {
636 return array(
637 'success' => true,
638 'data' => array(
639 'message' => sprintf(
640 /* translators: 1. Open tag. 2. Close tag. 3. Mode. */
641 __( '%1$sAntiBot Firewall%2$s mode updated – You\'re now using %3$s Mode.', 'defender-security' ),
642 '<strong>',
643 '</strong>',
644 ucfirst( $result )
645 ),
646 'mode' => $result,
647 'ips_count' => $this->service->get_blocklisted_ip_count(),
648 'auto_close' => true,
649 ),
650 );
651 }
652
653 return array(
654 'success' => false,
655 'data' => array(
656 'message' => __( 'Failed to switch. Please try again.', 'defender-security' ),
657 'auto_close' => true,
658 ),
659 );
660 }
661
662 /**
663 * Handle expired membership by automatically disabling the AntiBot Global Firewall module.
664 * Logs the action when the feature is disabled due to expired membership.
665 *
666 * @return void
667 */
668 public function handle_expired_membership(): void {
669 if ( $this->is_expired_membership_type() && $this->model->enabled ) {
670 $this->service->managed_by_plugin_action( false );
671 $this->log( 'AntiBot Global Firewall automatically disabled due to expired membership.', Antibot_Global_Firewall_Component::LOG_FILE_NAME );
672 }
673 }
674
675 /**
676 * Handle request to send feedback.
677 *
678 * @param Request $request The request object.
679 *
680 * @defender_route
681 * @return Response
682 */
683 public function send_feedback( Request $request ) {
684 $data = $request->get_data(
685 array(
686 'feedback' => array( 'type' => 'string' ),
687 )
688 );
689 if ( '' !== $data['feedback'] ) {
690 // Send feedback.
691 $this->track_feature(
692 'Antibot Survey',
693 array(
694 'Notice Action' => 'Share feedback',
695 'Feedback' => $data['feedback'],
696 )
697 );
698 }
699 // Dismiss the global notice.
700 $this->service->dismiss_global_notice();
701
702 $message = sprintf(
703 /* translators: 1: Open tag, 2: Close tag */
704 __( '%1$sThanks for your feedback!%2$s It helps us make Defender even better.', 'defender-security' ),
705 '<strong>',
706 '</strong>'
707 );
708
709 return new Response(
710 true,
711 array(
712 'message' => $message,
713 'auto_close' => true,
714 )
715 );
716 }
717
718 /**
719 * Dismiss the global notice.
720 *
721 * @defender_route
722 * @return Response
723 */
724 public function dismiss_global_notice(): Response {
725 $this->service->dismiss_global_notice();
726
727 return new Response(
728 true,
729 array(
730 'message' => __( 'The global notice has been dismissed.', 'defender-security' ),
731 'success' => true,
732 'show_notice' => false,
733 )
734 );
735 }
736 }
737