PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.3.0
Defender Security – Malware Scanner, Login Security & Firewall v6.3.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
← All changes | src/controller/class-waf.php +60 -86 5.8.1 → 6.3.0 View file →
@@ -14,10 +14,19 @@
14 14 /**
15 15 * Handles the settings, data, and other functionality related to the Web Application Firewall (WAF).
16 16 */
17 17 class WAF extends Controller {
18 + /**
19 + * Option key storing the last known WAF status for change detection.
20 + */
21 + private const LAST_STATUS_OPTION = 'defender_waf_last_known_status';
18 22
19 23 /**
24 + * Transient key set for 5 minutes when WAF status changes, used to drive the sync notice.
25 + */
26 + private const STATUS_CHANGED_TRANSIENT = 'defender_waf_status_changed';
27 +
28 + /**
20 29 * The slug identifier for this controller.
21 30 *
22 31 * @var string
23 32 */
@@ -33,55 +42,12 @@
33 42 * Initializes the model and service, registers routes, and sets up scheduled events if the model is active.
34 43 */
35 44 public function __construct() {
36 45 $this->wpmudev = wd_di()->get( WPMUDEV::class );
37 -
38 - // Return the constructor and do not register WAF page if Whitelable is enabled.
39 - if ( $this->wpmudev->is_whitelabel_enabled() ) {
40 - return;
41 - }
42 -
43 - $this->register_page(
44 - esc_html__( 'WAF', 'defender-security' ),
45 - $this->slug,
46 - array( $this, 'main_view' ),
47 - $this->parent_slug
48 - );
49 - add_action( 'defender_enqueue_assets', array( $this, 'enqueue_assets' ) );
50 46 $this->register_routes();
51 47 }
52 48
53 49 /**
54 - * Enqueues scripts and styles for this page.
55 - * Only enqueues assets if the page is active.
56 - */
57 - public function enqueue_assets() {
58 - if ( ! $this->is_page_active() ) {
59 - return;
60 - }
61 - wp_localize_script( 'def-waf', 'waf', $this->data_frontend() );
62 - wp_enqueue_script( 'def-waf' );
63 - $this->enqueue_main_assets();
64 - }
65 -
66 - /**
67 - * Renders the main view for this page.
68 - */
69 - public function main_view() {
70 - $this->render( 'main' );
71 - }
72 -
73 - /**
74 - * Retrieves the WAF status for a given site.
75 - *
76 - * @return bool Returns false on failure, true if WAF is enabled.
77 - */
78 - public function get_waf_status(): bool {
79 - $status = defender_get_hosting_feature_state( 'waf' );
80 - return '' !== $status && true === (bool) $status;
81 - }
82 -
83 - /**
84 50 * Remove the cache and return latest data.
85 51 *
86 52 * @return Response
87 53 * @defender_route
@@ -86,45 +52,18 @@
86 52 * @return Response
87 53 * @defender_route
88 54 */
89 55 public function recheck(): Response {
90 - return new Response( true, array( 'waf' => $this->data_frontend()['waf'] ) );
56 + return new Response( true, array( 'waf' => $this->data_frontend() ) );
91 57 }
92 58
93 59 /**
94 - * Checks if the WAF dashboard widget should be shown.
95 - *
96 - * @return bool Whether to show the widget or not.
97 - */
98 - public function maybe_show_dashboard_widget(): bool {
99 - if (
100 - // Not hosted on us.
101 - ! $this->wpmudev->is_wpmu_hosting()
102 - // Pro.
103 - && true === $this->wpmudev->is_pro()
104 - // Enable whitelabel.
105 - && $this->wpmudev->is_whitelabel_enabled()
106 - ) {
107 - // Hide it.
108 - return false;
109 - }
110 -
111 - return true;
112 - }
113 -
114 - /**
115 60 * Converts the current object state to an array.
116 61 *
117 62 * @return array The array representation of the object.
118 63 */
119 64 public function to_array(): array {
120 - return array(
121 - 'waf' => array(
122 - 'hosted' => $this->wpmudev->is_wpmu_hosting(),
123 - 'status' => $this->get_waf_status(),
124 - 'maybe_show' => $this->maybe_show_dashboard_widget(),
125 - ),
126 - );
65 + return array();
127 66 }
128 67
129 68 /**
130 69 * Removes settings for all submodules.
@@ -135,8 +74,10 @@
135 74 /**
136 75 * Delete all the data & the cache.
137 76 */
138 77 public function remove_data() {
78 + delete_option( self::LAST_STATUS_OPTION );
79 + delete_transient( self::STATUS_CHANGED_TRANSIENT );
139 80 }
140 81
141 82 /**
142 83 * Provides data for the frontend.
@@ -143,25 +84,52 @@
143 84 *
144 85 * @return array An array of data for the frontend.
145 86 */
146 87 public function data_frontend(): array {
147 - $site_id = $this->wpmudev->get_site_id();
88 + $current_status = $this->get_waf_status();
89 + return array(
90 + 'site_id' => $this->wpmudev->get_site_id(),
91 + 'status' => $current_status,
92 + 'show_sync_notice' => $this->get_show_sync_notice( $current_status ),
93 + );
94 + }
148 95
149 - return array_merge(
150 - array(
151 - 'site_id' => $site_id,
152 - 'waf' => array(
153 - 'hosted' => $this->wpmudev->is_wpmu_hosting(),
154 - 'status' => $this->get_waf_status(),
155 - ),
156 - 'hub_connector' => wd_di()->get( Hub_Connector::class )->data_frontend(),
157 - 'antibot' => wd_di()->get( Antibot_Global_Firewall::class )->data_frontend(),
158 - ),
159 - $this->dump_routes_and_nonces()
160 - );
96 + /**
97 + * Retrieves the WAF status for a given site.
98 + *
99 + * @return bool Returns false on failure, true if WAF is enabled.
100 + */
101 + public function get_waf_status(): bool {
102 + $status = defender_get_hosting_feature_state( 'waf' );
103 + return '' !== $status && true === (bool) $status;
161 104 }
162 105
163 106 /**
107 + * Detects whether WAF status has recently changed and returns whether the sync notice should be shown.
108 + *
109 + * Sets a 5-minute transient on first detection of a status change so the notice persists across page loads.
110 + *
111 + * @param bool $current_status Current WAF enabled/disabled state.
112 + * @return bool True if the sync notice should be displayed.
113 + */
114 + private function get_show_sync_notice( bool $current_status ): bool {
115 + $stored = get_option( self::LAST_STATUS_OPTION, null );
116 +
117 + if ( null === $stored ) {
118 + update_option( self::LAST_STATUS_OPTION, $current_status );
119 + return false;
120 + }
121 +
122 + if ( (bool) $stored !== $current_status ) {
123 + update_option( self::LAST_STATUS_OPTION, $current_status );
124 + set_transient( self::STATUS_CHANGED_TRANSIENT, true, 5 * MINUTE_IN_SECONDS );
125 + return true;
126 + }
127 +
128 + return (bool) get_transient( self::STATUS_CHANGED_TRANSIENT );
129 + }
130 +
131 + /**
164 132 * Imports data into the model.
165 133 *
166 134 * @param array $data Data to be imported into the model.
167 135 */
@@ -173,7 +141,13 @@
173 141 *
174 142 * @return array An array of strings.
175 143 */
176 144 public function export_strings(): array {
177 - return array();
145 + return array(
146 + sprintf(
147 + /* translators: %s: Html for Pro-tag. */
148 + esc_html__( 'Inactive %s', 'defender-security' ),
149 + '<span class="sui-tag sui-tag-pro">Pro</span>'
150 + ),
151 + );
178 152 }
179 153 }