PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.34.2
MailPoet – Newsletters, Email Marketing, and Automation v5.34.2
5.34.2 5.34.1 5.34.0 5.33.1 5.33.0 5.32.0 5.31.0 5.30.0 5.29.0 5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / lib / Subscription / AdminUserSubscription.php
mailpoet / lib / Subscription Last commit date
AdminUserSubscription.php 2 months ago Blacklist.php 1 year ago Comment.php 2 months ago Form.php 2 weeks ago Manage.php 5 days ago ManageSubscriptionFormRenderer.php 5 days ago Pages.php 5 days ago Registration.php 2 months ago SubscriptionUrlFactory.php 5 days ago Throttling.php 2 months ago index.php 3 years ago
AdminUserSubscription.php
200 lines
1 <?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
2
3 namespace MailPoet\Subscription;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\Config\Renderer as TemplateRenderer;
9 use MailPoet\Entities\SubscriberEntity;
10 use MailPoet\Logging\LoggerFactory;
11 use MailPoet\Settings\SettingsController;
12 use MailPoet\Subscribers\ConfirmationEmailMailer;
13 use MailPoet\Subscribers\SubscribersRepository;
14 use MailPoet\WP\Functions as WPFunctions;
15
16 class AdminUserSubscription {
17 /** @var WPFunctions */
18 private $wp;
19
20 /** @var SettingsController */
21 private $settings;
22
23 /** @var SubscribersRepository */
24 private $subscribersRepository;
25
26 /** @var ConfirmationEmailMailer */
27 private $confirmationEmailMailer;
28
29 /** @var LoggerFactory */
30 private $loggerFactory;
31
32 /** @var TemplateRenderer */
33 private $templateRenderer;
34
35 public function __construct(
36 WPFunctions $wp,
37 SettingsController $settings,
38 SubscribersRepository $subscribersRepository,
39 ConfirmationEmailMailer $confirmationEmailMailer,
40 LoggerFactory $loggerFactory,
41 TemplateRenderer $templateRenderer
42 ) {
43 $this->wp = $wp;
44 $this->settings = $settings;
45 $this->subscribersRepository = $subscribersRepository;
46 $this->confirmationEmailMailer = $confirmationEmailMailer;
47 $this->loggerFactory = $loggerFactory;
48 $this->templateRenderer = $templateRenderer;
49 }
50
51 /**
52 * Set up hooks for the Add New User form in WordPress admin
53 */
54 public function setupHooks(): void {
55 // Set up hooks for the Add New User form
56 $this->wp->addAction('user_new_form', [$this, 'displaySubscriberStatusField']);
57
58 // Use the lower priority filter instead of an action - this is simpler and more reliable
59 $this->wp->addFilter('mailpoet_subscriber_data_before_save', [$this, 'modifySubscriberData'], 10, 1);
60
61 // Add action to send confirmation email after user registration is complete
62 $this->wp->addAction('user_register', [$this, 'maybeSendConfirmationEmail'], 30, 1);
63 }
64
65 /**
66 * Display the subscriber status field on the Add New User form
67 *
68 * @param string $type The form context, 'add-new-user' for single site and network admin
69 */
70 public function displaySubscriberStatusField($type): void {
71 // According to WordPress docs, the parameter is 'add-new-user' for single site and network admin
72 if ($type !== 'add-new-user') {
73 return;
74 }
75
76 $templateData = [
77 'confirmationEnabled' => (bool)$this->settings->get('signup_confirmation.enabled', false),
78 'statuses' => [
79 'subscribed' => SubscriberEntity::STATUS_SUBSCRIBED,
80 'unconfirmed' => SubscriberEntity::STATUS_UNCONFIRMED,
81 'unsubscribed' => SubscriberEntity::STATUS_UNSUBSCRIBED,
82 ],
83 ];
84
85 $renderedTemplate = $this->templateRenderer->render(
86 'subscription/admin_user_status_field.html',
87 $templateData
88 );
89
90 $allowedHtml = [
91 'table' => ['class' => true],
92 'tr' => [],
93 'th' => ['scope' => true],
94 'td' => [],
95 'label' => ['for' => true],
96 'select' => ['name' => true, 'id' => true],
97 'option' => ['value' => true, 'selected' => true],
98 ];
99 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
100 echo $this->wp->wpKses($renderedTemplate, $allowedHtml);
101 }
102
103 /**
104 * Modify subscriber data before save during user creation
105 *
106 * @param array $data The subscriber data
107 * @return array Modified subscriber data
108 */
109 public function modifySubscriberData($data): array {
110 // Only process during user creation in admin
111 if (!$this->isAdminUserCreation()) {
112 return $data;
113 }
114
115 // Check if our field was submitted
116 if (!isset($_POST['mailpoet_subscriber_status']) || !is_string($_POST['mailpoet_subscriber_status'])) {
117 return $data;
118 }
119
120 $status = sanitize_text_field($_POST['mailpoet_subscriber_status']);
121
122 // Validate the status value
123 $validStatuses = [
124 SubscriberEntity::STATUS_SUBSCRIBED,
125 SubscriberEntity::STATUS_UNCONFIRMED,
126 SubscriberEntity::STATUS_UNSUBSCRIBED,
127 ];
128
129 if (!in_array($status, $validStatuses)) {
130 return $data;
131 }
132
133 // Update the subscriber data
134 $data['status'] = $status;
135 $data['source'] = 'administrator';
136
137 return $data;
138 }
139
140 /**
141 * Send confirmation email if needed after user registration
142 *
143 * @param int $userId The WordPress user ID
144 */
145 public function maybeSendConfirmationEmail(int $userId): void {
146 // Only process during user creation in admin
147 if (!$this->isAdminUserCreation()) {
148 return;
149 }
150
151 // Check if our field was submitted and is set to unconfirmed
152 if (
153 !isset($_POST['mailpoet_subscriber_status']) ||
154 $_POST['mailpoet_subscriber_status'] !== SubscriberEntity::STATUS_UNCONFIRMED
155 ) {
156 return;
157 }
158
159 // Find the subscriber
160 $subscriber = $this->subscribersRepository->findOneBy(['wpUserId' => $userId]);
161
162 if (!$subscriber || $subscriber->getStatus() !== SubscriberEntity::STATUS_UNCONFIRMED) {
163 return;
164 }
165
166 // Send confirmation email. Per-list confirmation settings are not resolved
167 // here because admin-created users are subscribed via the WP Users segment.
168 try {
169 $this->confirmationEmailMailer->sendConfirmationEmailOnce($subscriber);
170 } catch (\Exception $e) {
171 // Log the error
172 $logger = $this->loggerFactory->getLogger();
173 $logger->error(
174 __('Failed to send confirmation email for admin-created user', 'mailpoet'),
175 ['user_id' => $userId, 'error' => $e->getMessage()]
176 );
177 }
178 }
179
180 /**
181 * Check if we're in the context of admin user creation
182 *
183 * @return bool
184 */
185 private function isAdminUserCreation(): bool {
186 // Check if we're in admin
187 if (!$this->wp->isAdmin()) {
188 return false;
189 }
190
191 // Check for the WordPress new user admin page
192 global $pagenow;
193 if ($pagenow !== 'user-new.php') {
194 return false;
195 }
196
197 return true;
198 }
199 }
200