PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 5.8.0
Defender Security – Malware Scanner, Login Security & Firewall v5.8.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 / model / notification / class-tweak-reminder.php

class-tweak-reminder.php in Defender Security – Malware Scanner, Login Security & Firewall 5.8.0, at src/model/notification/class-tweak-reminder.php

241 lines 7.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Handles the notification of security recommendations that need fixing.
4 *
5 * @package WP_Defender\Model\Notification
6 */
7
8 namespace WP_Defender\Model\Notification;
9
10 use DateTime;
11 use Countable;
12 use Exception;
13 use DateInterval;
14 use DI\DependencyException;
15 use Calotes\Helper\Array_Cache;
16 use WP_Defender\Component\Mail;
17 use WP_Defender\Component\Notification;
18 use WP_Defender\Controller\Security_Tweaks;
19
20 /**
21 * Handles the notification of security recommendations that need fixing.
22 */
23 class Tweak_Reminder extends \WP_Defender\Model\Notification {
24
25 /**
26 * Table name.
27 *
28 * @var string
29 */
30 protected $table = 'wd_security_tweaks_reminder';
31 /**
32 * Slug identifier for the tweak reminder.
33 *
34 * @var string
35 */
36 public const SLUG = 'tweak-reminder';
37
38 /**
39 * Constructor method.
40 * Sets default values for the class.
41 */
42 protected function before_load(): void {
43 $params = array(
44 'slug' => self::SLUG,
45 'title' => esc_html__( 'Security Recommendations - Notification', 'defender-security' ),
46 'status' => self::STATUS_DISABLED,
47 'description' => esc_html__(
48 'Get email notifications if/when a security recommendation needs fixing.',
49 'defender-security'
50 ),
51 // @since 3.0.0 Fix 'Guest'-line.
52 'in_house_recipients' => is_user_logged_in() ? array( $this->get_default_user() ) : array(),
53 'out_house_recipients' => array(),
54 'type' => 'notification',
55 'dry_run' => false,
56 'configs' => array(
57 'reminder' => 'weekly',
58 ),
59 );
60 $this->import( $params );
61 }
62
63 /**
64 * Determines if a notification should be sent based on the current status and time.
65 *
66 * @return bool Returns true if a notification should be sent, false otherwise.
67 */
68 public function maybe_send(): bool {
69 if ( self::STATUS_ACTIVE !== $this->status ) {
70 return false;
71 }
72
73 $est = new DateTime( 'now', wp_timezone() );
74 $est->setTimestamp( $this->last_sent );
75 $now = new DateTime( 'now', wp_timezone() );
76 $interval = DateInterval::createFromDateString( (string) $est->getOffset() . 'seconds' );
77 $now->add( $interval );
78
79 switch ( $this->configs['reminder'] ) {
80 case 'daily':
81 $est->add( new DateInterval( 'P1D' ) );
82 break;
83 case 'weekly':
84 $est->add( new DateInterval( 'P1W' ) );
85 break;
86 case 'monthly':
87 default:
88 $est->add( new DateInterval( 'P1M' ) );
89 break;
90 }
91 $est->add( $interval );
92 // Testing.
93 if ( defined( 'WP_DEFENDER_TESTING' ) && true === constant( 'WP_DEFENDER_TESTING' ) ) {
94 return true;
95 }
96 if ( $est->getTimestamp() < $now->getTimestamp() ) {
97 return true;
98 }
99
100 return false;
101 }
102
103 /**
104 * Sends the email.
105 * Retrieves data based on logic.
106 *
107 * @return void
108 * @throws Exception When an error occurs.
109 */
110 public function send() {
111 $tweaks = wd_di()->get( \WP_Defender\Model\Setting\Security_Tweaks::class );
112 if ( 0 === ( is_array( $tweaks->issues ) || $tweaks->issues instanceof Countable ? count( $tweaks->issues ) : 0 ) ) {
113 return;
114 }
115 $arr = Array_Cache::get( 'tweaks', 'tweaks' );
116 $issues = '';
117 $template = wd_di()->get( Security_Tweaks::class );
118 $status_img = defender_asset_url( '/assets/email-assets/img/[email protected]' );
119 foreach ( $tweaks->issues as $slug ) {
120 if ( isset( $arr[ $slug ] ) ) {
121 $issue = $arr[ $slug ];
122 $issues .= $template->render_partial(
123 'email/tweak-issue',
124 array(
125 'tweak_title' => $issue->get_label(),
126 'error_reason' => $issue->get_error_reason(),
127 'status_img' => $status_img,
128 ),
129 false
130 );
131 }
132 }
133
134 $service = wd_di()->get( Notification::class );
135 foreach ( $this->in_house_recipients as $recipient ) {
136 if ( self::USER_SUBSCRIBED !== $recipient['status'] ) {
137 continue;
138 }
139 $this->send_to_user( $recipient['email'], $recipient['name'], $issues, $service );
140 }
141
142 foreach ( $this->out_house_recipients as $recipient ) {
143 if ( self::USER_SUBSCRIBED !== $recipient['status'] ) {
144 continue;
145 }
146 $this->send_to_user( $recipient['email'], $recipient['name'], $issues, $service );
147 }
148 $this->last_sent = time();
149 $this->save();
150 }
151
152 /**
153 * Sends the email to a specific user.
154 * Constructs and sends the email to the specified recipient.
155 *
156 * @param string $email The recipient's email address.
157 * @param string $name The recipient's name.
158 * @param array $issues The summarized list of events.
159 * @param object $service The notification service object.
160 *
161 * @throws DependencyException If a dependency cannot be resolved.
162 * @return void
163 */
164 public function send_to_user( $email, $name, $issues, $service ) {
165 $tweaks = wd_di()->get( \WP_Defender\Model\Setting\Security_Tweaks::class );
166 $logs_url = network_admin_url( 'admin.php?page=wdf-hardener' );
167 $logs_url = apply_filters( 'report_email_logs_link', $logs_url, $email );
168
169 $security_tweak = wd_di()->get( Security_Tweaks::class );
170 $content_body = $security_tweak->render_partial(
171 'email/tweaks-reminder',
172 array(
173 'count' => is_array( $tweaks->issues ) || $tweaks->issues instanceof Countable ? count( $tweaks->issues ) : 0,
174 'view_url' => $logs_url,
175 'name' => $name,
176 'issues' => $issues,
177 'site_url' => network_site_url(),
178 ),
179 false
180 );
181 $unsubscribe_link = $service->create_unsubscribe_url( $this->slug, $email );
182 $content = $security_tweak->render_partial(
183 'email/index',
184 array(
185 'title' => esc_html__( 'Security Report', 'defender-security' ),
186 'content_body' => $content_body,
187 'unsubscribe_link' => $unsubscribe_link,
188 ),
189 false
190 );
191
192 /* translators: 1: Site URL, 2: Count for unresolved security recommendations */
193 $subject = _n(
194 'Security Recommendation Report for %1$s. %2$s recommendation to action.',
195 'Security Recommendation Report for %1$s. %2$s recommendations to action.',
196 is_array( $tweaks->issues ) || $tweaks->issues instanceof Countable ? count( $tweaks->issues ) : 0,
197 'defender-security'
198 );
199 $subject = sprintf(
200 $subject,
201 network_site_url(),
202 is_array( $tweaks->issues ) || $tweaks->issues instanceof Countable ? count( $tweaks->issues ) : 0
203 );
204
205 $headers = wd_di()->get( Mail::class )->get_headers(
206 defender_noreply_email( 'wd_recommendation_noreply_email' ),
207 self::SLUG
208 );
209
210 $ret = wp_mail( $email, $subject, $content, $headers );
211 if ( $ret ) {
212 $this->save_log( $email );
213 }
214 }
215
216 /**
217 * Define settings labels.
218 *
219 * @return array
220 */
221 public function labels(): array {
222 return array(
223 'notification' => esc_html__( 'Security Recommendations - Notification', 'defender-security' ),
224 'notification_repeat' => esc_html__( 'Frequency', 'defender-security' ),
225 'subscribers' => esc_html__( 'Recipients', 'defender-security' ),
226 );
227 }
228
229 /**
230 * Additional converting rules.
231 *
232 * @param array $configs The configuration data.
233 *
234 * @return array The type-casted configuration data.
235 * @since 3.1.0
236 */
237 public function type_casting( $configs ): array {
238 return is_array( $configs ) ? $configs : array();
239 }
240 }
241