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 / Util / Notices / DisabledMailFunctionNotice.php
mailpoet / lib / Util / Notices Last commit date
AfterMigrationNotice.php 2 years ago BlackFridayNotice.php 2 months ago ChangedTrackingNotice.php 3 years ago DatabaseEngineNotice.php 1 year ago DeprecatedFilterNotice.php 4 years ago DisabledMailFunctionNotice.php 2 months ago DisabledWPCronNotice.php 1 year ago EmailWithInvalidSegmentNotice.php 3 years ago HeadersAlreadySentNotice.php 2 months ago InactiveSubscribersNotice.php 2 years ago PHPVersionWarnings.php 2 months ago PendingApprovalNotice.php 2 years ago PermanentNotices.php 2 months ago PremiumFeaturesAvailableNotice.php 2 years ago SenderDomainAuthenticationNotices.php 5 months ago SendingQueueBodyCleanupNotice.php 2 months ago StuckPostNotificationNotice.php 2 months ago UnauthorizedEmailInNewslettersNotice.php 5 months ago UnauthorizedEmailNotice.php 5 months ago WooCommerceVersionWarning.php 1 year ago WordPressPlaygroundNotice.php 1 year ago index.php 3 years ago
DisabledMailFunctionNotice.php
242 lines
1 <?php declare(strict_types = 1);
2
3 namespace MailPoet\Util\Notices;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\Cron\Workers\SendingQueue\Tasks\Shortcodes;
9 use MailPoet\Doctrine\WPDB\Connection;
10 use MailPoet\Mailer\Mailer;
11 use MailPoet\Mailer\MailerFactory;
12 use MailPoet\Settings\SettingsController;
13 use MailPoet\Util\Helpers;
14 use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
15 use MailPoet\WP\Functions as WPFunctions;
16 use MailPoet\WP\Notice;
17
18 class DisabledMailFunctionNotice {
19
20 const DISABLED_MAIL_FUNCTION_CHECK = 'disabled_mail_function_check';
21
22 const QUEUE_DISABLED_MAIL_FUNCTION_CHECK = 'queue_disabled_mail_function_check';
23
24 /** @var SettingsController */
25 private $settings;
26
27 /** @var WPFunctions */
28 private $wp;
29
30 /** @var SubscribersFeature */
31 private $subscribersFeature;
32
33 /** @var MailerFactory */
34 private $mailerFactory;
35
36 private $isInQueueForChecking = false;
37
38 public function __construct(
39 WPFunctions $wp,
40 SettingsController $settings,
41 SubscribersFeature $subscribersFeature,
42 MailerFactory $mailerFactory
43 ) {
44 $this->settings = $settings;
45 $this->wp = $wp;
46 $this->subscribersFeature = $subscribersFeature;
47 $this->mailerFactory = $mailerFactory;
48 }
49
50 public function init($shouldDisplay): ?string {
51 $shouldDisplay = $shouldDisplay && !Connection::isSQLite() && $this->shouldCheckMisconfiguredFunction() && $this->checkRequirements();
52 if (!$shouldDisplay) {
53 return null;
54 }
55
56 return $this->display();
57 }
58
59 private function checkRequirements(): bool {
60 if ($this->isInQueueForChecking) {
61 $this->settings->set(self::QUEUE_DISABLED_MAIL_FUNCTION_CHECK, false);
62 }
63
64 $sendingMethod = $this->settings->get('mta.method', SettingsController::DEFAULT_SENDING_METHOD);
65 $isPhpMailSendingMethod = $sendingMethod === Mailer::METHOD_PHPMAIL;
66
67 if (!$isPhpMailSendingMethod) {
68 return false; // fails requirements check
69 }
70
71 $functionName = 'mail';
72 $isMailFunctionDisabled = $this->isFunctionDisabled($functionName);
73
74 if ($isMailFunctionDisabled) {
75 $this->settings->set(DisabledMailFunctionNotice::DISABLED_MAIL_FUNCTION_CHECK, true);
76 return true;
77 }
78
79 $isMailFunctionProperlyConfigured = $this->testMailFunctionIsCorrectlyConfigured();
80
81 return !$isMailFunctionProperlyConfigured;
82 }
83
84 /*
85 * Check MisConfigured Function
86 *
87 * This method will cause this class to only display the notice if the settings option
88 *
89 * disabled_mail_function_check === true
90 * or
91 * queue_disabled_mail_function_check === true
92 * or
93 * Totally disabled when wp filter `mailpoet_display_disabled_mail_function_notice` === false
94 *
95 */
96 public function shouldCheckMisconfiguredFunction(): bool {
97 $shouldCheck = $this->wp->applyFilters('mailpoet_display_disabled_mail_function_notice', true);
98 $this->isInQueueForChecking = $this->settings->get(self::QUEUE_DISABLED_MAIL_FUNCTION_CHECK, false);
99
100 return $shouldCheck && (
101 $this->settings->get(self::DISABLED_MAIL_FUNCTION_CHECK, false) ||
102 $this->isInQueueForChecking
103 );
104 }
105
106 public function isFunctionDisabled(string $function): bool {
107 // is_callable() returns false when the function is listed in disable_functions, which PHPStan can't see statically.
108 // @phpstan-ignore-next-line function.alreadyNarrowedType
109 $result = function_exists($function) && is_callable($function, false);
110 return !$result;
111 }
112
113 private function display(): string {
114 $header = $this->getHeader();
115
116 $body = $this->getBody();
117
118 $button = $this->getConnectMailPoetButton();
119
120 $message = $header . $body . $button;
121
122 Notice::displayWarning($message, '', self::DISABLED_MAIL_FUNCTION_CHECK, false);
123
124 return $message;
125 }
126
127 private function getHeader(): string {
128 return '<h4>' . __('Get ready to send your first campaign.', 'mailpoet') . '</h4>';
129 }
130
131 private function getBody(): string {
132 $bodyText = __('Connect your website with MailPoet, and start sending for free. Reach inboxes, not spam boxes. [link]Why am I seeing this?[/link]', 'mailpoet');
133
134 $bodyWithReplacedLink = Helpers::replaceLinkTags($bodyText, 'https://kb.mailpoet.com/article/396-disabled-mail-function', [
135 'target' => '_blank',
136 ]);
137
138 return '<p>' . $bodyWithReplacedLink . '</p>';
139 }
140
141 private function getConnectMailPoetButton(): string {
142 $subscribersCount = $this->subscribersFeature->getSubscribersCount();
143 $buttonLink = "https://account.mailpoet.com/?s={$subscribersCount}&utm_source=mailpoet&utm_medium=plugin&utm_campaign=disabled_mail_function";
144 $link = $this->wp->escAttr($buttonLink);
145 return '<p><a target="_blank" href="' . $link . '" class="button button-primary">' . __('Connect MailPoet', 'mailpoet') . '</a></p>';
146 }
147
148 /*
149 * Test Mail Function Is Correctly Configured
150 *
151 * This is a workaround for detecting the user PHP mail() function is Correctly Configured and not disabled by the host
152 */
153 private function testMailFunctionIsCorrectlyConfigured(): bool {
154 if ($this->settings->get(DisabledMailFunctionNotice::DISABLED_MAIL_FUNCTION_CHECK, false)) {
155 return false; // skip sending mail again
156 }
157
158 $replyToAddress = $this->settings->get('reply_to.address');
159 $senderAddress = $this->settings->get('sender.address');
160
161 $mailBody = "Hi there! \n
162
163 Your website ([site:homepage_link]) sent you this email to confirm that it can send emails.
164 If you're reading this email, then it works! You can now continue sending marketing emails with MailPoet! \n
165
166 MailPoet on [site:homepage_link]";
167
168 $body = Shortcodes::process($mailBody, null, null, null, null);
169
170 $sendTestMailData = [
171 'mailer' => $this->settings->get('mta'),
172 'newsletter' => [
173 'subject' => 'MailPoet can deliver your marketing emails!',
174 'body' => [
175 'html' => nl2br($body),
176 'text' => $body,
177 ],
178 ],
179 'subscriber' => empty($replyToAddress) ? $senderAddress : $replyToAddress,
180 ];
181
182 $sendMailResult = $this->sendTestMail($sendTestMailData);
183
184 if (!$sendMailResult) {
185 // Error with PHP mail() function
186 // keep displaying notice
187 $this->settings->set(DisabledMailFunctionNotice::DISABLED_MAIL_FUNCTION_CHECK, true);
188 }
189
190 return $sendMailResult;
191 }
192
193 /*
194 * Send Test Mail
195 * used to check for valid PHP mail()
196 *
197 * returns true if valid and okay
198 * else returns false if invalid.
199 *
200 * We determine the mail function is invalid by checking against the Exception error thrown by PHPMailer
201 * error message: Could not instantiate mail function.
202 *
203 * if the error is not equal to error message, we consider it okay.
204 */
205 public function sendTestMail($data = []): bool {
206 try {
207 $mailer = $this->mailerFactory->buildMailer(
208 $data['mailer'] ?? null,
209 $data['sender'] ?? null,
210 $data['reply_to'] ?? null
211 );
212 // report this as 'sending_test' in metadata since this endpoint is only used to test sending methods for now
213 $extraParams = [
214 'meta' => [
215 'email_type' => 'sending_test',
216 'subscriber_status' => 'unknown',
217 'subscriber_source' => 'administrator',
218 ],
219 ];
220 $result = $mailer->send($data['newsletter'], $data['subscriber'], $extraParams);
221
222 if ($result['response'] === false) {
223 $errorMessage = $result['error']->getMessage();
224 return !$this->checkForErrorMessage($errorMessage);
225 }
226
227 } catch (\Exception $e) {
228 $errorMessage = $e->getMessage();
229 return !$this->checkForErrorMessage($errorMessage);
230 }
231
232 return true;
233 }
234
235 private function checkForErrorMessage($errorMessage): bool {
236 $phpmailerError = 'Could not instantiate mail function';
237 $substringIndex = stripos($errorMessage, $phpmailerError);
238
239 return $substringIndex !== false;
240 }
241 }
242