PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.0.0
Defender Security – Malware Scanner, Login Security & Firewall v6.0.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 / component / class-recipients.php

class-recipients.php in Defender Security – Malware Scanner, Login Security & Firewall 6.0.0, at src/component/class-recipients.php

264 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Manages recipient subscriptions across notification modules.
4 *
5 * @package WP_Defender\Component
6 */
7
8 namespace WP_Defender\Component;
9
10 use WP_Defender\Component;
11 use WP_Defender\Model\Notification as Model_Notification;
12
13 /**
14 * Handles recipient persistence for notification modules.
15 */
16 class Recipients extends Component {
17
18 /**
19 * Notification service.
20 *
21 * @var Notification
22 */
23 private Notification $notification;
24
25 /**
26 * Initialize dependencies.
27 */
28 public function __construct() {
29 $this->notification = wd_di()->get( Notification::class );
30 }
31
32 /**
33 * Save recipient subscriptions.
34 *
35 * @param array $statuses Notification slugs to subscribe to.
36 * @param array $subscriber Subscriber data.
37 * @param array $unsubscribed Notification slugs to unsubscribe from.
38 * @return void
39 */
40 public function upsert_recipient_to_modules( array $statuses, array $subscriber, array $unsubscribed = array() ): void {
41 $name = $subscriber['name'];
42 $email = $subscriber['email'];
43 $in_house = isset( $subscriber['id'] );
44 $user_id = $in_house ? (int) $subscriber['id'] : 0;
45 $user = $in_house ? get_userdata( $user_id ) : false;
46 $key = $in_house && $user ? $user->user_email : $email;
47 $module_map = $this->notification->get_module_map();
48
49 $saved_models = $this->upsert_subscribed_modules(
50 $statuses,
51 $subscriber,
52 $key,
53 $name,
54 $in_house,
55 $user_id,
56 $module_map
57 );
58 $this->unsubscribe_recipient_from_modules( $unsubscribed, $key, $in_house, $module_map );
59
60 if ( ! empty( $saved_models ) ) {
61 if ( 1 === count( $saved_models ) ) {
62 $this->notification->send_email( $subscriber, $saved_models[0]->export() );
63 } else {
64 $this->notification->send_invite_all_email( $subscriber, $saved_models );
65 }
66 }
67 }
68
69 /**
70 * Add or reactivate a recipient in selected modules.
71 *
72 * @param array $statuses Notification slugs to subscribe to.
73 * @param array $subscriber Subscriber data.
74 * @param string $key Recipient lookup key.
75 * @param string $name Recipient display name.
76 * @param bool $in_house Whether the recipient is a WordPress user.
77 * @param int $user_id WordPress user ID for in-house recipients.
78 * @param array $module_map Pre-built slug → model index.
79 * @return array Saved notification models.
80 */
81 private function upsert_subscribed_modules(
82 array $statuses,
83 array $subscriber,
84 string $key,
85 string $name,
86 bool $in_house,
87 int $user_id,
88 array $module_map
89 ): array {
90 $saved_models = array();
91
92 foreach ( $statuses as $slug ) {
93 $model = $module_map[ sanitize_key( $slug ) ] ?? null;
94 if ( ! $model instanceof Model_Notification ) {
95 continue;
96 }
97
98 $changed = $this->upsert_recipient_to_module(
99 $model,
100 $subscriber,
101 $key,
102 $name,
103 $in_house,
104 $user_id
105 );
106
107 if ( ! $changed ) {
108 continue;
109 }
110
111 $model->save();
112 $saved_models[] = $model;
113 }
114
115 return $saved_models;
116 }
117
118 /**
119 * Add or reactivate a recipient in one module.
120 *
121 * @param Model_Notification $model Notification model.
122 * @param array $subscriber Subscriber data.
123 * @param string $key Recipient lookup key.
124 * @param string $name Recipient display name.
125 * @param bool $in_house Whether the recipient is a WordPress user.
126 * @param int $user_id WordPress user ID for in-house recipients.
127 * @return bool Whether the recipient data changed.
128 */
129 private function upsert_recipient_to_module(
130 Model_Notification $model,
131 array $subscriber,
132 string $key,
133 string $name,
134 bool $in_house,
135 int $user_id
136 ): bool {
137 if ( $in_house && 0 === $user_id ) {
138 return false;
139 }
140
141 $group = $in_house ? 'in_house_recipients' : 'out_house_recipients';
142 if ( isset( $model->{$group}[ $key ] ) ) {
143 $changed = $this->update_existing_recipient( $model, $group, $key, $name );
144 if ( $in_house ) {
145 $this->maybe_update_wp_user_profile( $user_id, $name, $subscriber );
146 }
147
148 return $changed;
149 }
150
151 $list = $model->{$group};
152
153 if ( $in_house ) {
154 $list[ $key ] = array(
155 'id' => $user_id,
156 'name' => $name,
157 'email' => $key,
158 'status' => Model_Notification::USER_SUBSCRIBE_NA,
159 );
160 } else {
161 $list[ $key ] = array(
162 'name' => $name,
163 'email' => $key,
164 'status' => Model_Notification::USER_SUBSCRIBE_NA,
165 );
166 }
167
168 $model->{$group} = $list;
169
170 return true;
171 }
172
173 /**
174 * Update an existing recipient record in one module.
175 *
176 * @param Model_Notification $model Notification model.
177 * @param string $group Recipient group property.
178 * @param string $key Recipient lookup key.
179 * @param string $name Recipient display name.
180 * @return bool Whether the recipient data changed.
181 */
182 private function update_existing_recipient( Model_Notification $model, string $group, string $key, string $name ): bool {
183 $changed = false;
184
185 if ( $model->{$group}[ $key ]['name'] !== $name ) {
186 $model->{$group}[ $key ]['name'] = $name;
187 $changed = true;
188 }
189
190 if ( Model_Notification::USER_SUBSCRIBE_CANCELED === $model->{$group}[ $key ]['status'] ) {
191 $model->{$group}[ $key ]['status'] = Model_Notification::USER_SUBSCRIBE_NA;
192 $changed = true;
193 }
194
195 return $changed;
196 }
197
198 /**
199 * Mark a recipient as unsubscribed in selected modules.
200 *
201 * @param array $unsubscribed Notification slugs to unsubscribe from.
202 * @param string $key Recipient lookup key.
203 * @param bool $in_house Whether the recipient is a WordPress user.
204 * @param array $module_map Pre-built slug → model index.
205 * @return void
206 */
207 private function unsubscribe_recipient_from_modules( array $unsubscribed, string $key, bool $in_house, array $module_map ): void {
208 foreach ( $unsubscribed as $slug ) {
209 $model = $module_map[ sanitize_key( $slug ) ] ?? null;
210 if ( ! $model instanceof Model_Notification ) {
211 continue;
212 }
213
214 $group = $in_house ? 'in_house_recipients' : 'out_house_recipients';
215 $recipient = $model->$group[ $key ] ?? null;
216
217 if (
218 ! is_array( $recipient )
219 || Model_Notification::USER_SUBSCRIBE_CANCELED === $recipient['status']
220 ) {
221 continue;
222 }
223
224 $model->{$group}[ $key ]['status'] = Model_Notification::USER_SUBSCRIBE_CANCELED;
225 $model->save();
226 $this->notification->send_unsubscribe_email( $model, $recipient['email'], $in_house, $recipient['name'] );
227 }
228 }
229
230 /**
231 * Update a WordPress user profile.
232 *
233 * @param int $user_id WordPress user ID.
234 * @param string $display_name User display name.
235 * @param array $subscriber Subscriber data.
236 * @return void
237 */
238 private function maybe_update_wp_user_profile( int $user_id, string $display_name, array $subscriber ): void {
239 if ( 0 === $user_id || ! current_user_can( 'edit_user', $user_id ) ) {
240 return;
241 }
242
243 $first_name = $subscriber['first_name'] ?? null;
244 $last_name = $subscriber['last_name'] ?? null;
245
246 if ( null === $first_name && null === $last_name && '' === $display_name ) {
247 return;
248 }
249
250 $args = array( 'ID' => $user_id );
251 if ( '' !== $display_name ) {
252 $args['display_name'] = $display_name;
253 }
254 if ( null !== $first_name ) {
255 $args['first_name'] = $first_name;
256 }
257 if ( null !== $last_name ) {
258 $args['last_name'] = $last_name;
259 }
260
261 wp_update_user( $args );
262 }
263 }
264