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/component/class-notification.php +57 -460 5.5.1 → 6.3.0 View file →
@@ -1,7 +1,7 @@
1 1 <?php
2 2 /**
3 - * Handles notifications for various WP Defender components such as Firewall, Malware, and Audit Logging.
3 + * Notification component stub for free version.
4 4 *
5 5 * @package WP_Defender\Component
6 6 */
7 7
@@ -6,15 +6,9 @@
6 6 */
7 7
8 8 namespace WP_Defender\Component;
9 9
10 -use Exception;
11 -use WP_User_Query;
12 -use WP_Defender\Component;
13 -use WP_Defender\Traits\IO;
14 -use WP_Defender\Traits\User;
15 10 use WP_Defender\Behavior\WPMUDEV;
16 -use WP_Defender\Model\Setting\Audit_Logging;
17 11 use WP_Defender\Model\Notification\Audit_Report;
18 12 use WP_Defender\Model\Notification\Malware_Report;
19 13 use WP_Defender\Model\Notification\Tweak_Reminder;
20 14 use WP_Defender\Model\Notification\Firewall_Report;
@@ -19,530 +13,133 @@
19 13 use WP_Defender\Model\Notification\Tweak_Reminder;
20 14 use WP_Defender\Model\Notification\Firewall_Report;
21 15 use WP_Defender\Model\Notification\Malware_Notification;
22 16 use WP_Defender\Model\Notification\Firewall_Notification;
23 -use WP_Defender\Controller\Notification as Controller_Notification;
24 17
25 18 /**
26 - * Handles notifications for various WP Defender components such as Firewall, Malware, and Audit Logging.
19 + * Notification component.
27 20 */
28 -class Notification extends Component {
21 +class Notification extends Notification_Base {
29 22
30 - use User;
31 - use IO;
32 -
33 23 /**
34 - * Indicates if the current installation is a Pro version.
35 - *
36 - * @var bool
24 + * Constructs the Notification component.
37 25 */
38 - private $is_pro;
39 -
40 - /**
41 - * Constructs the Notification component and initializes the WPMUDEV behavior.
42 - */
43 26 public function __construct() {
44 27 $this->attach_behavior( WPMUDEV::class, WPMUDEV::class );
45 - $this->is_pro = ( new WPMUDEV() )->is_pro();
46 28 }
47 29
48 30 /**
49 - * Retrieves a pool of users based on specified criteria.
31 + * Get all non-pro modules as array of arrays.
50 32 *
51 - * @param array $exclude User IDs to exclude.
52 - * @param string $role Role to filter users by.
53 - * @param string $username Search term for username.
54 - * @param string $order_by Property to sort by.
55 - * @param string $order Sort order (ASC or DESC).
56 - * @param int $limit Number of users to retrieve.
57 - * @param int $paged Page number for pagination.
58 - *
59 - * @return array Array of user data including display name, email, role, avatar, and ID.
33 + * @return array
60 34 */
61 - public function get_users_pool(
62 - $exclude = array(),
63 - $role = '',
64 - $username = '',
65 - $order_by = 'ID',
66 - $order = 'ASC',
67 - $limit = 15,
68 - $paged = 1
69 - ): array {
70 - $params = array(
71 - 'site_id' => 0,
72 - 'role' => $role,
73 - 'orderby' => $order_by,
74 - 'order' => $order,
75 - 'number' => $limit,
76 - 'paged' => $paged,
77 - 'exclude' => $exclude,
35 + public function get_modules(): array {
36 + return array(
37 + Malware_Notification::SLUG => wd_di()->get( Malware_Notification::class )->export(),
38 + Firewall_Notification::SLUG => wd_di()->get( Firewall_Notification::class )->export(),
78 39 );
79 -
80 - if ( ! empty( $username ) ) {
81 - $params['search'] = strtolower( $username );
82 - $params['search_columns'] = array(
83 - 'user_login',
84 - 'user_email',
85 - 'user_nicename',
86 - 'display_name',
87 - );
88 - }
89 - $user_query = new WP_User_Query( $params );
90 -
91 - $pools = array();
92 - foreach ( $user_query->get_results() as $user ) {
93 - $pools[] = array(
94 - 'name' => $this->get_user_display( $user ),
95 - 'email' => $this->get_current_user_email( $user ),
96 - 'role' => $this->get_current_user_role( $user ),
97 - 'avatar' => get_avatar_url( $this->get_current_user_email( $user ) ),
98 - 'id' => $user->ID,
99 - 'status' => \WP_Defender\Model\Notification::USER_SUBSCRIBE_NA,
100 - );
101 - }
102 -
103 - return $pools;
104 40 }
105 41
106 42 /**
107 - * Dispatches notifications based on the module slug and additional arguments.
43 + * Get all non-pro modules as array of objects.
108 44 *
109 - * @param string $slug Module slug to identify the notification handler.
110 - * @param object $args Additional arguments for the notification.
45 + * @return array
111 46 */
112 - public function dispatch_notification( $slug, $args ) {
113 - $module = $this->find_module_by_slug( $slug );
114 - if ( is_object( $module ) ) {
115 - if ( 'malware-notification' === $module->slug && $module->check_options() ) {
116 - // Case report.
117 - $module->send( $args );
118 - } elseif ( 'firewall-notification' === $module->slug && $module->check_options( $args ) ) {
119 - $module->send( $args );
120 - }
121 - }
47 + public function get_modules_as_objects(): array {
48 + return array(
49 + wd_di()->get( Malware_Notification::class ),
50 + wd_di()->get( Firewall_Notification::class ),
51 + );
122 52 }
123 53
124 54 /**
125 - * Finds a notification module by its slug.
55 + * Build a slug-to-model index for all notification modules.
126 56 *
127 - * @param string $slug The slug of the module.
128 - *
129 - * @return mixed Returns the module object if found.
57 + * @return array<string, \WP_Defender\Model\Notification>
130 58 */
131 - public function find_module_by_slug( $slug ) {
132 - switch ( $slug ) {
133 - case Tweak_Reminder::SLUG:
134 - return wd_di()->get( Tweak_Reminder::class );
135 - case Malware_Notification::SLUG:
136 - return wd_di()->get( Malware_Notification::class );
137 - case Firewall_Notification::SLUG:
138 - return wd_di()->get( Firewall_Notification::class );
139 - case Malware_Report::SLUG:
140 - return wd_di()->get( Malware_Report::class );
141 - case Firewall_Report::SLUG:
142 - return wd_di()->get( Firewall_Report::class );
143 - case Audit_Report::SLUG:
144 - default:
145 - return wd_di()->get( Audit_Report::class );
59 + public function get_module_map(): array {
60 + $map = array();
61 + foreach ( $this->get_modules_as_objects() as $model ) {
62 + $map[ $model->slug ] = $model;
146 63 }
147 - }
148 64
149 - /**
150 - * Send a verification email to users.
151 - *
152 - * @param \WP_Defender\Model\Notification $model Notification model containing recipient details.
153 - *
154 - * @throws Exception Emits Exception in case of an error.
155 - */
156 - public function send_subscription_confirm_email( \WP_Defender\Model\Notification $model ) {
157 - foreach ( $model->in_house_recipients as &$subscriber ) {
158 - if ( empty( $subscriber['status'] ) ) {
159 - continue;
160 - }
161 - if ( \WP_Defender\Model\Notification::USER_SUBSCRIBE_NA !== $subscriber['status'] ) {
162 - continue;
163 - }
164 - $ret = $this->send_email( $subscriber, $model );
165 -
166 - if ( $ret ) {
167 - $subscriber['status'] = \WP_Defender\Model\Notification::USER_SUBSCRIBE_WAITING;
168 - }
169 - }
170 - foreach ( $model->out_house_recipients as &$subscriber ) {
171 - if ( empty( $subscriber['status'] ) ) {
172 - continue;
173 - }
174 - if ( \WP_Defender\Model\Notification::USER_SUBSCRIBE_NA !== $subscriber['status'] ) {
175 - continue;
176 - }
177 - $ret = $this->send_email( $subscriber, $model );
178 -
179 - if ( $ret ) {
180 - $subscriber['status'] = \WP_Defender\Model\Notification::USER_SUBSCRIBE_WAITING;
181 - }
182 - }
183 -
184 - $model->save();
65 + return $map;
185 66 }
186 67
187 68 /**
188 - * Sends an email to a subscriber.
69 + * Return the time that the next report will be triggered. For free always return 'Never'.
189 70 *
190 - * @param array $subscriber Subscriber information.
191 - * @param \WP_Defender\Model\Notification $model Notification model used for the email.
192 - *
193 - * @return bool Returns true if the email was sent successfully.
71 + * @return string
194 72 */
195 - public function send_email( $subscriber, \WP_Defender\Model\Notification $model ) {
196 - $headers = wd_di()->get( Mail::class )->get_headers(
197 - defender_noreply_email( 'wd_confirm_noreply_email' ),
198 - 'subscription'
199 - );
200 - $email = $subscriber['email'];
201 - $name = $subscriber['name'] ?? '';
202 - $inhouse = false;
203 - if ( isset( $subscriber['id'] ) ) {
204 - $inhouse = true;
205 - }
206 - $url = $this->create_subscribe_url( $model->slug, $email, $inhouse );
207 - $subject = sprintf( /* translators: %s: Model title. */ 'Subscribe to %s', $model->title );
208 - // Renders emails.
209 - $notification = wd_di()->get( Controller_Notification::class );
210 - $content_body = $notification->render_partial(
211 - 'email/confirm',
212 - array(
213 - 'subject' => $subject,
214 - 'email' => $email,
215 - 'notification_name' => $model->title,
216 - 'url' => $url,
217 - 'site_url' => network_site_url(),
218 - 'name' => $name,
219 - ),
220 - false
221 - );
222 - $content = $notification->render_partial(
223 - 'email/index',
224 - array(
225 - 'title' => preg_replace( '/ - Notification$/', '', $model->title ),
226 - 'content_body' => $content_body,
227 - // An empty value because this is a confirmation email.
228 - 'unsubscribe_link' => '',
229 - ),
230 - false
231 - );
232 -
233 - // We send email here.
234 - return wp_mail( $email, $subject, $content, $headers );
73 + public function get_next_run() {
74 + return esc_html__( 'Never', 'defender-security' );
235 75 }
236 76
237 77 /**
238 - * Sends a subscription confirmation email to a user.
78 + * Get inactive modules. For free it's always empty.
239 79 *
240 - * @param string $email Email address of the subscriber.
241 - * @param object $m Notification model object.
242 - * @param string $name Name of the subscriber.
80 + * @return array
243 81 */
244 - public function send_subscribed_email( $email, $m, $name ) {
245 - $headers = wd_di()->get( Mail::class )->get_headers(
246 - defender_noreply_email( 'wd_subscribe_noreply_email' ),
247 - 'subscribe_confimed'
248 - );
249 -
250 - $notification = wd_di()->get( Controller_Notification::class );
251 - $subject = esc_html__( 'Confirmed', 'defender-security' );
252 - $content_body = $notification->render_partial(
253 - 'email/subscribed',
254 - array(
255 - 'subject' => esc_html__( 'Subscription Confirmed', 'defender-security' ),
256 - 'notification_name' => $m->title,
257 - 'url' => $this->create_unsubscribe_url( $m->slug, $email ),
258 - 'name' => $name,
259 - )
260 - );
261 - $content = $notification->render_partial(
262 - 'email/index',
263 - array(
264 - 'title' => preg_replace( '/ - Notification$/', '', $m->title ),
265 - 'content_body' => $content_body,
266 - // An empty value because this is a subscribed email.
267 - 'unsubscribe_link' => '',
268 - ),
269 - false
270 - );
271 -
272 - wp_mail( $email, $subject, $content, $headers );
82 + public function get_inactive_modules(): array {
83 + return array();
273 84 }
274 85
275 86 /**
276 - * Sends an unsubscribe email to a user.
87 + * Get the alert model (firewall notification).
277 88 *
278 - * @param object $m Notification model object.
279 - * @param string $email Email address of the subscriber.
280 - * @param bool $inhouse Indicates if the user is an in-house user.
281 - * @param string $name Name of the subscriber.
282 - */
283 - public function send_unsubscribe_email( $m, $email, $inhouse, $name ) {
284 - $subject = esc_html__( 'Unsubscribed', 'defender-security' );
285 - $url = $this->create_subscribe_url( $m->slug, $email, $inhouse );
286 - // Render emails.
287 - $notification = wd_di()->get( Controller_Notification::class );
288 - $content_body = $notification->render_partial(
289 - 'email/unsubscribe',
290 - array(
291 - 'subject' => esc_html__( 'Unsubscribed', 'defender-security' ),
292 - 'notification_name' => $m->title,
293 - 'url' => $url,
294 - 'name' => $name,
295 - )
296 - );
297 - $title = preg_replace( '/ - Notification$/', '', $m->title );
298 - $title = preg_replace( '/ - Reporting$/', '', $title );
299 - $content = $notification->render_partial(
300 - 'email/index',
301 - array(
302 - 'title' => $title,
303 - 'content_body' => $content_body,
304 - // An empty value because this is an unsubscribed email.
305 - 'unsubscribe_link' => '',
306 - ),
307 - false
308 - );
309 -
310 - $headers = wd_di()->get( Mail::class )->get_headers(
311 - defender_noreply_email( 'wd_unsubscribe_noreply_email' ),
312 - 'unsubscription'
313 - );
314 -
315 - wp_mail( $email, $subject, $content, $headers );
316 - }
317 -
318 - /**
319 - * Create a URL for unsubscribing from notifications.
320 - *
321 - * @param string $slug Notification slug.
322 - * @param string $email Email address of the subscriber.
323 - *
324 - * @return string Unsubscribe URL.
325 - */
326 - public function create_unsubscribe_url( $slug, $email ): string {
327 - return add_query_arg(
328 - array(
329 - 'action' => Controller_Notification::SLUG_UNSUBSCRIBE,
330 - 'hash' => hash( 'sha256', $email . AUTH_SALT ),
331 - 'slug' => $slug,
332 - ),
333 - admin_url( 'admin-ajax.php' )
334 - );
335 - }
336 -
337 - /**
338 - * Create a URL for subscribing to notifications.
339 - *
340 - * @param string $slug Notification slug.
341 - * @param string $email Email address of the subscriber.
342 - * @param bool $inhouse Indicates if the user is an in-house user.
343 - *
344 - * @return string Subscribe URL.
345 - */
346 - public function create_subscribe_url( $slug, $email, $inhouse ): string {
347 - return add_query_arg(
348 - array(
349 - 'action' => Controller_Notification::SLUG_SUBSCRIBE,
350 - 'hash' => hash( 'sha256', $email . AUTH_SALT ),
351 - 'uid' => $slug,
352 - 'inhouse' => $inhouse,
353 - ),
354 - admin_url( 'admin-ajax.php' )
355 - );
356 - }
357 -
358 - /**
359 - * Get all modules as array of arrays.
360 - *
361 89 * @return array
362 90 */
363 - public function get_modules(): array {
364 - $modules = array(
365 - wd_di()->get( Tweak_Reminder::class )->export(),
366 - wd_di()->get( Malware_Notification::class )->export(),
367 - wd_di()->get( Firewall_Notification::class )->export(),
368 - );
369 -
370 - if ( true === $this->is_pro ) {
371 - return array_merge( $modules, $this->get_active_pro_reports() );
372 - } else {
373 - return $modules;
374 - }
91 + public function get_alert_model(): array {
92 + return array( Firewall_Notification::SLUG => wd_di()->get( Firewall_Notification::class )->export() );
375 93 }
376 94
377 95 /**
378 - * Get all modules as array of objects.
96 + * Get all report models keyed by slug. Only for the view.
379 97 *
380 98 * @return array
381 99 */
382 - public function get_modules_as_objects(): array {
383 - $modules = array(
384 - wd_di()->get( Tweak_Reminder::class ),
385 - wd_di()->get( Malware_Notification::class ),
386 - wd_di()->get( Firewall_Notification::class ),
387 - );
100 + public function get_reports_model(): array {
101 + $malware_report = wd_di()->get( Malware_Report::class )->export();
102 + $malware_report['ui_title'] = esc_html__( 'Issues', 'defender-security' );
388 103
389 - if ( true === $this->is_pro ) {
390 - $modules = array_merge(
391 - $modules,
392 - array(
393 - wd_di()->get( Malware_Report::class ),
394 - wd_di()->get( Firewall_Report::class ),
395 - wd_di()->get( Audit_Report::class ),
396 - )
397 - );
398 - }
104 + $tweak_reminder = wd_di()->get( Tweak_Reminder::class )->export();
105 + $tweak_reminder['ui_title'] = esc_html__( 'Hardening', 'defender-security' );
399 106
400 - return $modules;
401 - }
107 + $firewall_report = wd_di()->get( Firewall_Report::class )->export();
108 + $firewall_report['ui_title'] = esc_html__( 'Firewall', 'defender-security' );
402 109
403 - /**
404 - * Return the time that next report will be trigger.
405 - *
406 - * @return string|null
407 - */
408 - public function get_next_run() {
409 - if ( false === $this->is_pro ) {
410 - return esc_html__( 'Never', 'defender-security' );
411 - }
412 - $modules = $this->get_active_pro_reports_as_objects();
413 - $next_run = null;
414 - foreach ( $modules as $module ) {
415 - if ( \WP_Defender\Model\Notification::STATUS_ACTIVE !== $module->status ) {
416 - continue;
417 - }
418 - if ( is_null( $next_run ) ) {
419 - $next_run = $module;
420 - } elseif ( $module->est_timestamp < $next_run->est_timestamp ) {
421 - $next_run = $module;
422 - }
423 - }
424 - if ( is_null( $next_run ) ) {
425 - return esc_html__( 'Never', 'defender-security' );
426 - }
110 + $audit_report = wd_di()->get( Audit_Report::class )->export();
111 + $audit_report['ui_title'] = esc_html__( 'Audit log', 'defender-security' );
427 112
428 - return $next_run->get_next_run_as_string();
113 + return array(
114 + Malware_Report::SLUG => $malware_report,
115 + Tweak_Reminder::SLUG => $tweak_reminder,
116 + Firewall_Report::SLUG => $firewall_report,
117 + Audit_Report::SLUG => $audit_report,
118 + );
429 119 }
430 120
431 121 /**
432 - * Get inactive modules.
122 + * Get active pro report modules as arrays. For free it's always empty.
433 123 *
434 124 * @return array
435 - * @since 2.7.0 Malware Scanning - Reporting may be inactive.
436 125 */
437 - public function get_inactive_modules(): array {
438 - if ( false === $this->is_pro ) {
439 - return array();
440 - }
441 - $modules = array();
442 - if ( false === wd_di()->get( \WP_Defender\Model\Setting\Scan::class )->scheduled_scanning ) {
443 - $module = wd_di()->get( Malware_Report::class )->export();
444 - $module['link'] = network_admin_url( 'admin.php?page=wdf-scan&view=settings&enable=scheduled_scanning#setting_scheduled_scanning' );
445 - $modules[] = $module;
446 - }
447 - if ( false === wd_di()->get( Audit_Logging::class )->is_active() ) {
448 - $module = wd_di()->get( Audit_Report::class )->export();
449 - $module['link'] = network_admin_url( 'admin.php?page=wdf-logging&view=logs' );
450 - $modules[] = $module;
451 - }
452 -
453 - return $modules;
454 - }
455 -
456 - /**
457 - * Get active modules of Pro reports as array of arrays.
458 - *
459 - * @return array
460 - */
461 126 public function get_active_pro_reports(): array {
462 - $modules = array();
463 - // Malware_Report.
464 - if ( true === wd_di()->get( \WP_Defender\Model\Setting\Scan::class )->scheduled_scanning ) {
465 - $modules[] = wd_di()->get( Malware_Report::class )->export();
466 - }
467 - // Firewall_Report.
468 - $modules[] = wd_di()->get( Firewall_Report::class )->export();
469 - // Audit_Report.
470 - if ( true === wd_di()->get( Audit_Logging::class )->is_active() ) {
471 - $modules[] = wd_di()->get( Audit_Report::class )->export();
472 - }
473 -
474 - return $modules;
127 + return array();
475 128 }
476 129
477 130 /**
478 - * Get active modules of Pro reports as array of objects.
131 + * Get active pro report modules as objects. For free it's always empty.
479 132 *
480 133 * @return array
481 134 */
482 135 public function get_active_pro_reports_as_objects(): array {
483 - $modules = array();
484 - // Malware_Report.
485 - if ( true === wd_di()->get( \WP_Defender\Model\Setting\Scan::class )->scheduled_scanning ) {
486 - $modules[] = wd_di()->get( Malware_Report::class );
487 - }
488 - // Firewall_Report.
489 - $modules[] = wd_di()->get( Firewall_Report::class );
490 - // Audit_Report.
491 - if ( true === wd_di()->get( Audit_Logging::class )->is_active() ) {
492 - $modules[] = wd_di()->get( Audit_Report::class );
493 - }
494 -
495 - return $modules;
136 + return array();
496 137 }
497 138
498 139 /**
499 - * Counts the number of active modules.
500 - *
501 - * @return int Number of active modules.
140 + * Dispatches reports.
502 141 */
503 - public function count_active(): int {
504 - $count = 0;
505 - foreach ( $this->get_modules() as $module ) {
506 - if ( \WP_Defender\Model\Notification::STATUS_ACTIVE === $module['status'] ) {
507 - ++$count;
508 - }
509 - }
510 -
511 - return $count;
512 - }
513 -
514 - /**
515 - * Dispatches reports if conditions are met.
516 - */
517 142 public function maybe_dispatch_report() {
518 - $modules = array( wd_di()->get( Tweak_Reminder::class ) );
519 - if ( true === $this->is_pro ) {
520 - $modules = array_merge( $modules, $this->get_active_pro_reports_as_objects() );
521 - }
522 -
523 - foreach ( $modules as $module ) {
524 - if ( $module->maybe_send() ) {
525 - $module->send();
526 - }
527 - }
528 - }
529 -
530 - /**
531 - * Get available user roles with user count.
532 - *
533 - * @return array Return user roles with user count.
534 - */
535 - public function get_user_roles(): array {
536 - $user_roles = count_users();
537 -
538 - if ( isset( $user_roles['avail_roles'] ) ) {
539 - foreach ( $user_roles['avail_roles'] as $key => $value ) {
540 - if ( 0 === $value ) {
541 - unset( $user_roles['avail_roles'][ $key ] );
542 - }
543 - }
544 - }
545 -
546 - return $user_roles;
143 + // No Pro reports.
547 144 }
548 145 }