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/model/notification/class-malware-notification.php +48 -29 6.0.1 → 6.3.0 View file →
@@ -12,12 +12,10 @@
12 12 use WP_Defender\Model\Scan;
13 13 use WP_Defender\Component\Mail;
14 14 use WP_Defender\Component\Notification;
15 15 use WP_Defender\Model\Scan_Item;
16 -use WP_Defender\Model\Notification\Malware_Report;
17 16 use WP_Defender\Traits\Scan_Email_Template;
18 17 use WP_Defender\Traits\Scan_Upsell;
19 -use WP_Defender\Behavior\WPMUDEV;
20 18
21 19 /**
22 20 * Handles the scheduling and sending of malware-related notifications.
23 21 */
@@ -111,8 +109,44 @@
111 109 }
112 110 }
113 111
114 112 /**
113 + * Sends a manual scan notification to the user who triggered the scan.
114 + *
115 + * @param Scan $scan The scan object.
116 + *
117 + * @return bool Whether the manual scan notification was handled.
118 + */
119 + private function send_manual_scan( Scan $scan ): bool {
120 + $user_id = (int) get_transient( 'defender_scan_triggered_by_' . $scan->id );
121 + delete_transient( 'defender_scan_triggered_by_' . $scan->id );
122 + if ( $user_id <= 0 ) {
123 + return false;
124 + }
125 +
126 + $user = get_userdata( $user_id );
127 + if ( ! $user ) {
128 + return true;
129 + }
130 +
131 + $issues = $scan->get_issues( null, Scan_Item::STATUS_ACTIVE );
132 + if ( in_array( $scan->status, array( Scan::STATUS_ERROR, Scan::STATUS_IDLE ), true ) ) {
133 + $templates = $this->configs['template']['error'];
134 + } elseif ( 0 === count( $issues ) ) {
135 + return true;
136 + } else {
137 + $templates = $this->configs['template']['found'];
138 + }
139 +
140 + $subject = $templates['subject'];
141 + $content = nl2br( $templates['body'] );
142 + $service = wd_di()->get( Notification::class );
143 + $this->send_to_user( $user->user_email, $user->display_name, $subject, $content, $issues, $service );
144 +
145 + return true;
146 + }
147 +
148 + /**
115 149 * Sends the malware notification email.
116 150 * Constructs and sends the malware notification email to the recipients.
117 151 *
118 152 * @param Scan $scan The scan object.
@@ -119,24 +153,11 @@
119 153 *
120 154 * @return void
121 155 */
122 156 public function send( Scan $scan ): void {
123 - // Manual scan: always notify only the triggering user, no opt-in or status check required.
124 - if ( ! $scan->is_automation ) {
125 - $user_id = (int) get_transient( 'defender_scan_triggered_by_' . $scan->id );
126 - delete_transient( 'defender_scan_triggered_by_' . $scan->id );
127 - if ( $user_id > 0 ) {
128 - $user = get_userdata( $user_id );
129 - if ( $user ) {
130 - $issues = $scan->get_issues( null, Scan_Item::STATUS_ACTIVE );
131 - $templates = count( $issues ) ? $this->configs['template']['found'] : $this->configs['template']['not_found'];
132 - $subject = $templates['subject'];
133 - $content = nl2br( $templates['body'] );
134 - $service = wd_di()->get( Notification::class );
135 - $this->send_to_user( $user->user_email, $user->display_name, $subject, $content, $issues, $service );
136 - }
137 - return;
138 - }
157 + // Manual scan: notify only the triggering user when issues are found or the scan fails.
158 + if ( ! $scan->is_automation && $this->send_manual_scan( $scan ) ) {
159 + return;
139 160 }
140 161
141 162 $object = $this;
142 163 if ( $scan->is_automation ) {
@@ -148,19 +169,18 @@
148 169 // @since 2.7.0 Remove 'dry_run'-condition.
149 170 }
150 171 $issues = $scan->get_issues( null, Scan_Item::STATUS_ACTIVE );
151 172 /**
152 - * When the Defender is unable to scan files for some reason and the 'error_send' option is checked.
173 + * When the Defender is unable to scan files for some reason.
174 + * The 'error_send' option was removed in v6. Its stored value is preserved for backward
175 + * compatibility (downgrade safety), but error notifications are now always sent regardless
176 + * of what the legacy value is.
153 177 * Possible reasons:
154 178 * - no connection to Scan API,
155 179 * - no checksums received from wp.org,
156 180 * - scan process stuck.
157 181 */
158 - if (
159 - isset( $object->configs['error_send'] )
160 - && $object->configs['error_send']
161 - && in_array( $scan->status, array( Scan::STATUS_ERROR, Scan::STATUS_IDLE ), true )
162 - ) {
182 + if ( in_array( $scan->status, array( Scan::STATUS_ERROR, Scan::STATUS_IDLE ), true ) ) {
163 183 $subject = $object->configs['template']['error']['subject'];
164 184 $content = nl2br( $object->configs['template']['error']['body'] );
165 185
166 186 $this->email_engine( $scan, $object, $subject, $content, $issues );
@@ -167,13 +187,12 @@
167 187
168 188 return;
169 189 }
170 190
171 - // Sometimes value may be as empty string for disabled 'always_send'.
172 - if (
173 - ( ! isset( $object->configs['always_send'] ) || true !== $object->configs['always_send'] )
174 - && 0 === count( $issues )
175 - ) {
191 + // The 'always_send' option was removed in v6. Its stored value is preserved for backward
192 + // compatibility (downgrade safety), but it must have no effect here — never send when
193 + // there are no issues, regardless of what the legacy value is.
194 + if ( 0 === count( $issues ) ) {
176 195 return;
177 196 }
178 197 // For another case.
179 198 $templates = count( $issues ) ? $object->configs['template']['found'] : $object->configs['template']['not_found'];