Firewall_Notification::SLUG: return wd_di()->get( Firewall_Notification::class ); case Malware_Report::SLUG: return wd_di()->get( Malware_Report::class ); case Firewall_Report::SLUG: return wd_di()->get( Firewall_Report::class ); case Audit_Report::SLUG: default: return wd_di()->get( Audit_Report::class ); } } /** * Send a verification email to users. * * @param \WP_Defender\Model\Notification $model Notification model containing recipient details. * * @throws Exception Emits Exception in case of an error. */ public function send_subscription_confirm_email( \WP_Defender\Model\Notification $model ) { foreach ( $model->in_house_recipients as &$subscriber ) { if ( empty( $subscriber['status'] ) ) { continue; } if ( \WP_Defender\Model\Notification::USER_SUBSCRIBE_NA !== $subscriber['status'] ) { continue; } $ret = $this->send_email( $subscriber, $model ); if ( $ret ) { $subscriber['status'] = \WP_Defender\Model\Notification::USER_SUBSCRIBE_WAITING; } } foreach ( $model->out_house_recipients as &$subscriber ) { if ( empty( $subscriber['status'] ) ) { continue; } if ( \WP_Defender\Model\Notification::USER_SUBSCRIBE_NA !== $subscriber['status'] ) { continue; } $ret = $this->send_email( $subscriber, $model ); if ( $ret ) { $subscriber['status'] = \WP_Defender\Model\Notification::USER_SUBSCRIBE_WAITING; } } $model->save(); } /** * Sends an email to a subscriber. * * @param array $subscriber Subscriber information. * @param \WP_Defender\Model\Notification $model Notification model used for the email. * * @return bool Returns true if the email was sent successfully. */ public function send_email( $subscriber, \WP_Defender\Model\Notification $model ) { $headers = wd_di()->get( Mail::class )->get_headers( defender_noreply_email( 'wd_confirm_noreply_email' ), 'subscription' ); $email = $subscriber['email']; $name = $subscriber['name'] ?? ''; $inhouse = false; if ( isset( $subscriber['id'] ) ) { $inhouse = true; } $url = $this->create_subscribe_url( $model->slug, $email, $inhouse ); $subject = sprintf( /* translators: %s: Model title. */ 'Subscribe to %s', $model->title ); // Renders emails. $notification = wd_di()->get( Controller_Notification::class ); $content_body = $notification->render_partial( 'email/confirm', array( 'subject' => $subject, 'email' => $email, 'notification_name' => $model->title, 'url' => $url, 'site_url' => network_site_url(), 'name' => $name, ), false ); $content = $notification->render_partial( 'email/index', array( 'title' => preg_replace( '/ - Notification$/', '', $model->title ), 'content_body' => $content_body, // An empty value because this is a confirmation email. 'unsubscribe_link' => '', ), false ); // We send email here. return wp_mail( $email, $subject, $content, $headers ); } /** * Sends a subscription confirmation email to a user. * * @param string $email Email address of the subscriber. * @param object $m Notification model object. * @param string $name Name of the subscriber. */ public function send_subscribed_email( $email, $m, $name ) { $headers = wd_di()->get( Mail::class )->get_headers( defender_noreply_email( 'wd_subscribe_noreply_email' ), 'subscribe_confimed' ); $notification = wd_di()->get( Controller_Notification::class ); $subject = esc_html__( 'Confirmed', 'wpdef' ); $content_body = $notification->render_partial( 'email/subscribed', array( 'subject' => esc_html__( 'Subscription Confirmed', 'wpdef' ), 'notification_name' => $m->title, 'url' => $this->create_unsubscribe_url( $m->slug, $email ), 'name' => $name, ) ); $content = $notification->render_partial( 'email/index', array( 'title' => preg_replace( '/ - Notification$/', '', $m->title ), 'content_body' => $content_body, // An empty value because this is a subscribed email. 'unsubscribe_link' => '', ), false ); wp_mail( $email, $subject, $content, $headers ); } /** * Sends an unsubscribe email to a user. * * @param object $m Notification model object. * @param string $email Email address of the subscriber. * @param bool $inhouse Indicates if the user is an in-house user. * @param string $name Name of the subscriber. */ public function send_unsubscribe_email( $m, $email, $inhouse, $name ) { $subject = esc_html__( 'Unsubscribed', 'wpdef' ); $url = $this->create_subscribe_url( $m->slug, $email, $inhouse ); // Render emails. $notification = wd_di()->get( Controller_Notification::class ); $content_body = $notification->render_partial( 'email/unsubscribe', array( 'subject' => esc_html__( 'Unsubscribed', 'wpdef' ), 'notification_name' => $m->title, 'url' => $url, 'name' => $name, ) ); $title = preg_replace( '/ - Notification$/', '', $m->title ); $title = preg_replace( '/ - Reporting$/', '', $title ); $content = $notification->render_partial( 'email/index', array( 'title' => $title, 'content_body' => $content_body, // An empty value because this is an unsubscribed email. 'unsubscribe_link' => '', ), false ); $headers = wd_di()->get( Mail::class )->get_headers( defender_noreply_email( 'wd_unsubscribe_noreply_email' ), 'unsubscription' ); wp_mail( $email, $subject, $content, $headers ); } /** * Create a URL for unsubscribing from notifications. * * @param string $slug Notification slug. * @param string $email Email address of the subscriber. * * @return string Unsubscribe URL. */ public function create_unsubscribe_url( $slug, $email ): string { return add_query_arg( array( 'action' => Controller_Notification::SLUG_UNSUBSCRIBE, 'hash' => hash( 'sha256', $email . AUTH_SALT ), 'slug' => $slug, ), admin_url( 'admin-ajax.php' ) ); } /** * Create a URL for subscribing to notifications. * * @param string $slug Notification slug. * @param string $email Email address of the subscriber. * @param bool $inhouse Indicates if the user is an in-house user. * * @return string Subscribe URL. */ public function create_subscribe_url( $slug, $email, $inhouse ): string { return add_query_arg( array( 'action' => Controller_Notification::SLUG_SUBSCRIBE, 'hash' => hash( 'sha256', $email . AUTH_SALT ), 'uid' => $slug, 'inhouse' => $inhouse, ), admin_url( 'admin-ajax.php' ) ); } /** * Get all modules as array of arrays. * * @return array */ public function get_modules(): array { $modules = array( wd_di()->get( Tweak_Reminder::class )->export(), wd_di()->get( Malware_Notification::class )->export(), wd_di()->get( Firewall_Notification::class )->export(), ); if ( true === $this->is_pro ) { return array_merge( $modules, $this->get_active_pro_reports() ); } else { return $modules; } } /** * Get all modules as array of objects. * * @return array */ public function get_modules_as_objects(): array { $modules = array( wd_di()->get( Tweak_Reminder::class ), wd_di()->get( Malware_Notification::class ), wd_di()->get( Firewall_Notification::class ), ); if ( true === $this->is_pro ) { $modules = array_merge( $modules, array( wd_di()->get( Malware_Report::class ), wd_di()->get( Firewall_Report::class ), wd_di()->get( Audit_Report::class ), ) ); } return $modules; } /** * Return the time that next report will be trigger. * * @return string|null */ public function get_next_run() { if ( false === $this->is_pro ) { return esc_html__( 'Never', 'wpdef' ); } $modules = $this->get_active_pro_reports_as_objects(); $next_run = null; foreach ( $modules as $module ) { if ( \WP_Defender\Model\Notification::STATUS_ACTIVE !== $module->status ) { continue; } if ( is_null( $next_run ) ) { $next_run = $module; } elseif ( $module->est_timestamp < $next_run->est_timestamp ) { $next_run = $module; } } if ( is_null( $next_run ) ) { return esc_html__( 'Never', 'wpdef' ); } return $next_run->get_next_run_as_string(); } /** * Get inactive modules. * * @return array * @since 2.7.0 Malware Scanning - Reporting may be inactive. */ public function get_inactive_modules(): array { if ( false === $this->is_pro ) { return array(); } $modules = array(); if ( false === wd_di()->get( \WP_Defender\Model\Setting\Scan::class )->scheduled_scanning ) { $module = wd_di()->get( Malware_Report::class )->export(); $module['link'] = network_admin_url( 'admin.php?page=wdf-scan&view=settings&enable=scheduled_scanning#setting_scheduled_scanning' ); $modules[] = $module; } if ( false === wd_di()->get( Audit_Logging::class )->is_active() ) { $module = wd_di()->get( Audit_Report::class )->export(); $module['link'] = network_admin_url( 'admin.php?page=wdf-logging&view=logs' ); $modules[] = $module; } return $modules; } /** * Get active modules of Pro reports as array of arrays. * * @return array */ public function get_active_pro_reports(): array { $modules = array(); // Malware_Report. if ( true === wd_di()->get( \WP_Defender\Model\Setting\Scan::class )->scheduled_scanning ) { $modules[] = wd_di()->get( Malware_Report::class )->export(); } // Firewall_Report. $modules[] = wd_di()->get( Firewall_Report::class )->export(); // Audit_Report. if ( true === wd_di()->get( Audit_Logging::class )->is_active() ) { $modules[] = wd_di()->get( Audit_Report::class )->export(); } return $modules; } /** * Get active modules of Pro reports as array of objects. * * @return array */ public function get_active_pro_reports_as_objects(): array { $modules = array(); // Malware_Report. if ( true === wd_di()->get( \WP_Defender\Model\Setting\Scan::class )->scheduled_scanning ) { $modules[] = wd_di()->get( Malware_Report::class ); } // Firewall_Report. $modules[] = wd_di()->get( Firewall_Report::class ); // Audit_Report. if ( true === wd_di()->get( Audit_Logging::class )->is_active() ) { $modules[] = wd_di()->get( Audit_Report::class ); } return $modules; } /** * Counts the number of active modules. * * @return int Number of active modules. */ public function count_active(): int { $count = 0; foreach ( $this->get_modules() as $module ) { if ( \WP_Defender\Model\Notification::STATUS_ACTIVE === $module['status'] ) { ++$count; } } return $count; } /** * Dispatches reports if conditions are met. */ public function maybe_dispatch_report() { $modules = array( wd_di()->get( Tweak_Reminder::class ) ); if ( true === $this->is_pro ) { $modules = array_merge( $modules, $this->get_active_pro_reports_as_objects() ); } foreach ( $modules as $module ) { if ( $module->maybe_send() ) { $module->send(); } } } /** * Get available user roles with user count. * * @return array Return user roles with user count. */ public function get_user_roles(): array { $user_roles = count_users(); if ( isset( $user_roles['avail_roles'] ) ) { foreach ( $user_roles['avail_roles'] as $key => $value ) { if ( 0 === $value ) { unset( $user_roles['avail_roles'][ $key ] ); } } } return $user_roles; } }Firewall_Notification::SLUG: return wd_di()->get( Firewall_Notification::class ); case Malware_Report::SLUG: return wd_di()->get( Malware_Report::class ); case Firewall_Report::SLUG: return wd_di()->get( Firewall_Report::class ); case Audit_Report::SLUG: default: return wd_di()->get( Audit_Report::class ); } } /** * Send a verification email to users. * * @param \WP_Defender\Model\Notification $model Notification model containing recipient details. * * @throws Exception Emits Exception in case of an error. */ public function send_subscription_confirm_email( \WP_Defender\Model\Notification $model ) { foreach ( $model->in_house_recipients as &$subscriber ) { if ( empty( $subscriber['status'] ) ) { continue; } if ( \WP_Defender\Model\Notification::USER_SUBSCRIBE_NA !== $subscriber['status'] ) { continue; } $ret = $this->send_email( $subscriber, $model ); if ( $ret ) { $subscriber['status'] = \WP_Defender\Model\Notification::USER_SUBSCRIBE_WAITING; } } foreach ( $model->out_house_recipients as &$subscriber ) { if ( empty( $subscriber['status'] ) ) { continue; } if ( \WP_Defender\Model\Notification::USER_SUBSCRIBE_NA !== $subscriber['status'] ) { continue; } $ret = $this->send_email( $subscriber, $model ); if ( $ret ) { $subscriber['status'] = \WP_Defender\Model\Notification::USER_SUBSCRIBE_WAITING; } } $model->save(); } /** * Sends an email to a subscriber. * * @param array $subscriber Subscriber information. * @param \WP_Defender\Model\Notification $model Notification model used for the email. * * @return bool Returns true if the email was sent successfully. */ public function send_email( $subscriber, \WP_Defender\Model\Notification $model ) { $headers = wd_di()->get( Mail::class )->get_headers( defender_noreply_email( 'wd_confirm_noreply_email' ), 'subscription' ); $email = $subscriber['email']; $name = $subscriber['name'] ?? ''; $inhouse = false; if ( isset( $subscriber['id'] ) ) { $inhouse = true; } $url = $this->create_subscribe_url( $model->slug, $email, $inhouse ); $subject = sprintf( /* translators: %s: Model title. */ 'Subscribe to %s', $model->title ); // Renders emails. $notification = wd_di()->get( Controller_Notification::class ); $content_body = $notification->render_partial( 'email/confirm', array( 'subject' => $subject, 'email' => $email, 'notification_name' => $model->title, 'url' => $url, 'site_url' => network_site_url(), 'name' => $name, ), false ); $content = $notification->render_partial( 'email/index', array( 'title' => preg_replace( '/ - Notification$/', '', $model->title ), 'content_body' => $content_body, // An empty value because this is a confirmation email. 'unsubscribe_link' => '', ), false ); // We send email here. return wp_mail( $email, $subject, $content, $headers ); } /** * Sends a subscription confirmation email to a user. * * @param string $email Email address of the subscriber. * @param object $m Notification model object. * @param string $name Name of the subscriber. */ public function send_subscribed_email( $email, $m, $name ) { $headers = wd_di()->get( Mail::class )->get_headers( defender_noreply_email( 'wd_subscribe_noreply_email' ), 'subscribe_confimed' ); $notification = wd_di()->get( Controller_Notification::class ); $subject = esc_html__( 'Confirmed', 'wpdef' ); $content_body = $notification->render_partial( 'email/subscribed', array( 'subject' => esc_html__( 'Subscription Confirmed', 'wpdef' ), 'notification_name' => $m->title, 'url' => $this->create_unsubscribe_url( $m->slug, $email ), 'name' => $name, ) ); $content = $notification->render_partial( 'email/index', array( 'title' => preg_replace( '/ - Notification$/', '', $m->title ), 'content_body' => $content_body, // An empty value because this is a subscribed email. 'unsubscribe_link' => '', ), false ); wp_mail( $email, $subject, $content, $headers ); } /** * Sends an unsubscribe email to a user. * * @param object $m Notification model object. * @param string $email Email address of the subscriber. * @param bool $inhouse Indicates if the user is an in-house user. * @param string $name Name of the subscriber. */ public function send_unsubscribe_email( $m, $email, $inhouse, $name ) { $subject = esc_html__( 'Unsubscribed', 'wpdef' ); $url = $this->create_subscribe_url( $m->slug, $email, $inhouse ); // Render emails. $notification = wd_di()->get( Controller_Notification::class ); $content_body = $notification->render_partial( 'email/unsubscribe', array( 'subject' => esc_html__( 'Unsubscribed', 'wpdef' ), 'notification_name' => $m->title, 'url' => $url, 'name' => $name, ) ); $title = preg_replace( '/ - Notification$/', '', $m->title ); $title = preg_replace( '/ - Reporting$/', '', $title ); $content = $notification->render_partial( 'email/index', array( 'title' => $title, 'content_body' => $content_body, // An empty value because this is an unsubscribed email. 'unsubscribe_link' => '', ), false ); $headers = wd_di()->get( Mail::class )->get_headers( defender_noreply_email( 'wd_unsubscribe_noreply_email' ), 'unsubscription' ); wp_mail( $email, $subject, $content, $headers ); } /** * Create a URL for unsubscribing from notifications. * * @param string $slug Notification slug. * @param string $email Email address of the subscriber. * * @return string Unsubscribe URL. */ public function create_unsubscribe_url( $slug, $email ): string { return add_query_arg( array( 'action' => Controller_Notification::SLUG_UNSUBSCRIBE, 'hash' => hash( 'sha256', $email . AUTH_SALT ), 'slug' => $slug, ), admin_url( 'admin-ajax.php' ) ); } /** * Create a URL for subscribing to notifications. * * @param string $slug Notification slug. * @param string $email Email address of the subscriber. * @param bool $inhouse Indicates if the user is an in-house user. * * @return string Subscribe URL. */ public function create_subscribe_url( $slug, $email, $inhouse ): string { return add_query_arg( array( 'action' => Controller_Notification::SLUG_SUBSCRIBE, 'hash' => hash( 'sha256', $email . AUTH_SALT ), 'uid' => $slug, 'inhouse' => $inhouse, ), admin_url( 'admin-ajax.php' ) ); } /** * Get all modules as array of arrays. * * @return array */ public function get_modules(): array { $modules = array( wd_di()->get( Tweak_Reminder::class )->export(), wd_di()->get( Malware_Notification::class )->export(), wd_di()->get( Firewall_Notification::class )->export(), ); if ( true === $this->is_pro ) { return array_merge( $modules, $this->get_active_pro_reports() ); } else { return $modules; } } /** * Get all modules as array of objects. * * @return array */ public function get_modules_as_objects(): array { $modules = array( wd_di()->get( Tweak_Reminder::class ), wd_di()->get( Malware_Notification::class ), wd_di()->get( Firewall_Notification::class ), ); if ( true === $this->is_pro ) { $modules = array_merge( $modules, array( wd_di()->get( Malware_Report::class ), wd_di()->get( Firewall_Report::class ), wd_di()->get( Audit_Report::class ), ) ); } return $modules; } /** * Return the time that next report will be trigger. * * @return string|null */ public function get_next_run() { if ( false === $this->is_pro ) { return esc_html__( 'Never', 'wpdef' ); } $modules = $this->get_active_pro_reports_as_objects(); $next_run = null; foreach ( $modules as $module ) { if ( \WP_Defender\Model\Notification::STATUS_ACTIVE !== $module->status ) { continue; } if ( is_null( $next_run ) ) { $next_run = $module; } elseif ( $module->est_timestamp < $next_run->est_timestamp ) { $next_run = $module; } } if ( is_null( $next_run ) ) { return esc_html__( 'Never', 'wpdef' ); } return $next_run->get_next_run_as_string(); } /** * Get inactive modules. * * @return array * @since 2.7.0 Malware Scanning - Reporting may be inactive. */ public function get_inactive_modules(): array { if ( false === $this->is_pro ) { return array(); } $modules = array(); if ( false === wd_di()->get( \WP_Defender\Model\Setting\Scan::class )->scheduled_scanning ) { $module = wd_di()->get( Malware_Report::class )->export(); $module['link'] = network_admin_url( 'admin.php?page=wdf-scan&view=settings&enable=scheduled_scanning#setting_scheduled_scanning' ); $modules[] = $module; } if ( false === wd_di()->get( Audit_Logging::class )->is_active() ) { $module = wd_di()->get( Audit_Report::class )->export(); $module['link'] = network_admin_url( 'admin.php?page=wdf-logging&view=logs' ); $modules[] = $module; } return $modules; } /** * Get active modules of Pro reports as array of arrays. * * @return array */ public function get_active_pro_reports(): array { $modules = array(); // Malware_Report. if ( true === wd_di()->get( \WP_Defender\Model\Setting\Scan::class )->scheduled_scanning ) { $modules[] = wd_di()->get( Malware_Report::class )->export(); } // Firewall_Report. $modules[] = wd_di()->get( Firewall_Report::class )->export(); // Audit_Report. if ( true === wd_di()->get( Audit_Logging::class )->is_active() ) { $modules[] = wd_di()->get( Audit_Report::class )->export(); } return $modules; } /** * Get active modules of Pro reports as array of objects. * * @return array */ public function get_active_pro_reports_as_objects(): array { $modules = array(); // Malware_Report. if ( true === wd_di()->get( \WP_Defender\Model\Setting\Scan::class )->scheduled_scanning ) { $modules[] = wd_di()->get( Malware_Report::class ); } // Firewall_Report. $modules[] = wd_di()->get( Firewall_Report::class ); // Audit_Report. if ( true === wd_di()->get( Audit_Logging::class )->is_active() ) { $modules[] = wd_di()->get( Audit_Report::class ); } return $modules; } /** * Counts the number of active modules. * * @return int Number of active modules. */ public function count_active(): int { $count = 0; foreach ( $this->get_modules() as $module ) { if ( \WP_Defender\Model\Notification::STATUS_ACTIVE === $module['status'] ) { ++$count; } } return $count; } /** * Dispatches reports if conditions are met. */ public function maybe_dispatch_report() { $modules = array( wd_di()->get( Tweak_Reminder::class ) ); if ( true === $this->is_pro ) { $modules = array_merge( $modules, $this->get_active_pro_reports_as_objects() ); } foreach ( $modules as $module ) { if ( $module->maybe_send() ) { $module->send(); } } } /** * Get available user roles with user count. * * @return array Return user roles with user count. */ public function get_user_roles(): array { $user_roles = count_users(); if ( isset( $user_roles['avail_roles'] ) ) { foreach ( $user_roles['avail_roles'] as $key => $value ) { if ( 0 === $value ) { unset( $user_roles['avail_roles'][ $key ] ); } } } return $user_roles; } }