PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / trunk
MailPoet – Newsletters, Email Marketing, and Automation vtrunk
5.36.1 5.36.0 5.35.1 5.35.0 5.34.3 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 / Comment.php
mailpoet / lib / Subscription Last commit date
AdminUserSubscription.php 3 months ago Blacklist.php 1 year ago Comment.php 1 week ago Form.php 1 month ago Manage.php 1 month ago ManageSubscriptionFormRenderer.php 2 weeks ago Pages.php 6 days ago Registration.php 1 week ago SubscriptionUrlFactory.php 1 month ago Throttling.php 3 months ago index.php 3 years ago
Comment.php
188 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\Entities\SubscriberEntity;
9 use MailPoet\Settings\SettingsController;
10 use MailPoet\Subscribers\SubscriberActions;
11 use MailPoet\Subscribers\TrackingConsentCapture;
12 use MailPoet\WP\Functions as WPFunctions;
13
14 class Comment {
15 const SPAM = 'spam';
16 const APPROVED = 1;
17 const PENDING_APPROVAL = 0;
18
19 /**
20 * Comment meta remembering the tracking-consent choice while a comment waits
21 * for moderation. The subscribe is deferred to approval, which happens in a
22 * later request with no POST data, so the choice has to be stored with the
23 * comment rather than re-read.
24 */
25 const TRACKING_CONSENT_META = 'mailpoet_tracking_consent';
26
27 /** @var SettingsController */
28 private $settings;
29
30 /** @var SubscriberActions */
31 private $subscriberActions;
32
33 /** @var TrackingConsentCapture */
34 private $trackingConsentCapture;
35
36 public function __construct(
37 SettingsController $settings,
38 SubscriberActions $subscriberActions,
39 TrackingConsentCapture $trackingConsentCapture
40 ) {
41 $this->settings = $settings;
42 $this->subscriberActions = $subscriberActions;
43 $this->trackingConsentCapture = $trackingConsentCapture;
44 }
45
46 public function extendLoggedInForm($field) {
47 $field .= $this->getSubscriptionField();
48 return $field;
49 }
50
51 public function extendLoggedOutForm() {
52 // The method returns escaped content
53 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
54 echo $this->getSubscriptionField();
55 }
56
57 /**
58 * Returns escaped HTML for the subscription field.
59 *
60 * @return string
61 */
62 private function getSubscriptionField(): string {
63 $label = $this->settings->get(
64 'subscribe.on_comment.label',
65 __('Yes, please add me to your mailing list.', 'mailpoet')
66 );
67
68 return '<p class="comment-form-mailpoet">
69 <label for="mailpoet_subscribe_on_comment">
70 <input
71 type="checkbox"
72 id="mailpoet_subscribe_on_comment"
73 value="1"
74 name="mailpoet[subscribe_on_comment]"
75 />&nbsp;' . esc_html($label) . '
76 </label>
77 </p>' . $this->getTrackingConsentField();
78 }
79
80 /**
81 * A second, independent checkbox. Consent to open and click tracking is never
82 * inferred from the subscribe box above it, and it is only shown on sites
83 * that chose to ask. Never pre-ticked: a pre-ticked consent box is not valid
84 * consent (CJEU Planet49).
85 */
86 private function getTrackingConsentField(): string {
87 if (!$this->trackingConsentCapture->isCaptureEnabled()) {
88 return '';
89 }
90 $copy = $this->trackingConsentCapture->getCopy(
91 SubscriberEntity::TRACKING_CONSENT_METHOD_COMMENT
92 );
93
94 return '<p class="comment-form-mailpoet-tracking-consent">
95 <label for="mailpoet_tracking_consent">
96 <input
97 type="checkbox"
98 id="mailpoet_tracking_consent"
99 value="1"
100 name="mailpoet[tracking_consent]"
101 />&nbsp;' . esc_html($copy) . '
102 </label>
103 </p>';
104 }
105
106 public function onSubmit($commentId, $commentStatus) {
107 if ($commentStatus === Comment::SPAM) return;
108
109 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- type narrowing only, value is read as bool
110 $mailpoetPost = isset($_POST['mailpoet']) && is_array($_POST['mailpoet']) ? $_POST['mailpoet'] : [];
111 if (
112 isset($mailpoetPost['subscribe_on_comment'])
113 && (bool)$mailpoetPost['subscribe_on_comment'] === true
114 ) {
115 $trackingConsent = !empty($mailpoetPost['tracking_consent']);
116 if ($commentStatus === Comment::PENDING_APPROVAL) {
117 // add a comment meta to remember to subscribe the user
118 // once the comment gets approved
119 WPFunctions::get()->addCommentMeta(
120 $commentId,
121 'mailpoet',
122 'subscribe_on_comment',
123 true
124 );
125 // Approval runs in a later request with no POST data, so the consent
126 // choice is stored alongside it rather than re-read then.
127 WPFunctions::get()->addCommentMeta(
128 $commentId,
129 self::TRACKING_CONSENT_META,
130 $trackingConsent ? '1' : '0',
131 true
132 );
133 } elseif ($commentStatus === Comment::APPROVED) {
134 $this->subscribeAuthorOfComment($commentId, $trackingConsent);
135 }
136 }
137 }
138
139 public function onStatusUpdate($commentId, $action) {
140 if ($action === 'approve') {
141 // check if the comment's author wants to subscribe
142 $doSubscribe = (
143 WPFunctions::get()->getCommentMeta(
144 $commentId,
145 'mailpoet',
146 true
147 ) === 'subscribe_on_comment'
148 );
149
150 if ($doSubscribe === true) {
151 $trackingConsent = WPFunctions::get()->getCommentMeta(
152 $commentId,
153 self::TRACKING_CONSENT_META,
154 true
155 ) === '1';
156 $this->subscribeAuthorOfComment($commentId, $trackingConsent);
157
158 WPFunctions::get()->deleteCommentMeta($commentId, 'mailpoet');
159 WPFunctions::get()->deleteCommentMeta($commentId, self::TRACKING_CONSENT_META);
160 }
161 }
162 }
163
164 private function subscribeAuthorOfComment($commentId, bool $trackingConsent = false) {
165 $segmentIds = $this->settings->get('subscribe.on_comment.segments', []);
166
167 if (!empty($segmentIds)) {
168 $comment = WPFunctions::get()->getComment($commentId);
169 $email = $comment->comment_author_email; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
170 $method = SubscriberEntity::TRACKING_CONSENT_METHOD_COMMENT;
171 $consentData = $this->trackingConsentCapture->getConsentData(
172 $trackingConsent,
173 $method,
174 $this->trackingConsentCapture->getCopy($method),
175 $this->trackingConsentCapture->isNewSubscriber($email)
176 );
177
178 $this->subscriberActions->subscribe(
179 array_merge([
180 'email' => $email,
181 'first_name' => $comment->comment_author, // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
182 ], $consentData),
183 $segmentIds
184 );
185 }
186 }
187 }
188