PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.3
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.3
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / app / Services / Integrations / MailChimp / MailChimpSubscriber.php

MailChimpSubscriber.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.3, at app/Services/Integrations/MailChimp/MailChimpSubscriber.php

326 lines 11.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\App\Services\Integrations\MailChimp;
4
5 use FluentForm\App\Services\ConditionAssesor;
6 use FluentForm\App\Services\Integrations\LogResponseTrait;
7 use FluentForm\Framework\Helpers\ArrayHelper;
8
9 trait MailChimpSubscriber
10 {
11 use LogResponseTrait;
12
13 /**
14 * Enabled MailChimp feed settings.
15 *
16 * @var array $feeds
17 */
18 protected $feeds = [];
19
20 /**
21 * Required for api response logging
22 *
23 * @var string
24 */
25 protected $metaKey = 'fluentform_mailchimp_feed';
26
27 /**
28 * Form input data.
29 *
30 * @param array $formData
31 */
32 public function setApplicableFeeds($formData)
33 {
34 $feeds = $this->getAll();
35
36 foreach ($feeds as $feed) {
37 if ($this->isApplicable($feed, $formData)) {
38 $email = ArrayHelper::get(
39 $formData,
40 ArrayHelper::get($feed->formattedValue, 'fieldEmailAddress')
41 );
42
43 if (is_string($email) && is_email($email)) {
44 $feed->formattedValue['fieldEmailAddress'] = $email;
45
46 $this->feeds[] = $feed;
47 }
48 }
49 }
50 }
51
52 /**
53 * Determine if the feed is eligible to be applied.
54 *
55 * @param $feed
56 * @param $formData
57 *
58 * @return bool
59 */
60 public function isApplicable(&$feed, &$formData)
61 {
62 return ArrayHelper::get($feed->formattedValue, 'enabled') &&
63 ArrayHelper::get($feed->formattedValue, 'list_id') &&
64 ConditionAssesor::evaluate($feed->formattedValue, $formData);
65 }
66
67 /**
68 * Subscribe a user to the list on form submission.
69 *
70 * @param $feed
71 * @param $formData
72 * @param $entry
73 * @param $form
74 *
75 * @return array|bool|false
76 *
77 * @throws \Exception
78 */
79 public function subscribe($feed, $formData, $entry, $form)
80 {
81 $feedData = $feed['processedValues'];
82
83 if (! is_email($feedData['fieldEmailAddress'])) {
84 $feedData['fieldEmailAddress'] = ArrayHelper::get($formData, $feedData['fieldEmailAddress']);
85 }
86
87 if (! is_email($feedData['fieldEmailAddress'])) {
88 return false;
89 }
90
91 $mergeFields = array_filter(ArrayHelper::get($feedData, 'merge_fields'));
92 $status = ArrayHelper::isTrue($feedData, 'doubleOptIn') ? 'pending' : 'subscribed';
93
94 $listId = $feedData['list_id'];
95
96 $arguments = [
97 'email_address' => $feedData['fieldEmailAddress'],
98 'status_if_new' => $status,
99 'double_optin' => ArrayHelper::isTrue($feedData, 'doubleOptIn'),
100 'vip' => ArrayHelper::isTrue($feedData, 'markAsVIP'),
101 ];
102
103 if ($mergeFields) {
104 // Process merge field for address
105 $mergeFieldsSettings = $this->findMergeFields(
106 ArrayHelper::get($feed, 'settings.list_id')
107 );
108
109 foreach ($mergeFieldsSettings as $fieldSettings) {
110 if (
111 'address' == $fieldSettings['type'] ||
112 'birthday' == $fieldSettings['type'] ||
113 'date' == $fieldSettings['type']
114 ) {
115 $fieldName = $fieldSettings['tag'];
116
117 $formFieldName = ArrayHelper::get($feed, 'settings.merge_fields.' . $fieldName);
118
119 if ($formFieldName) {
120 preg_match('/{+(.*?)}/', $formFieldName, $matches);
121
122 $formFieldName = substr($matches[1], strlen('inputs.'));
123
124 $formFieldValue = ArrayHelper::get($formData, $formFieldName);
125
126 if ($formFieldValue) {
127 if (is_array($formFieldValue) && 'address' == $fieldSettings['type']) {
128 $mergeFields[$fieldName] = [
129 'addr1' => ArrayHelper::get($formFieldValue, 'address_line_1'),
130 'city' => ArrayHelper::get($formFieldValue, 'city'),
131 'state' => ArrayHelper::get($formFieldValue, 'state'),
132 'zip' => ArrayHelper::get($formFieldValue, 'zip'),
133 'country' => ArrayHelper::get($formFieldValue, 'country'),
134 ];
135
136 if (ArrayHelper::exists($formFieldValue, 'address_line_2')) {
137 $mergeFields[$fieldName]['addr2'] = ArrayHelper::get($formFieldValue, 'address_line_2');
138 }
139 }
140 elseif ('birthday' == $fieldSettings['type']) {
141 $mergeFields[$fieldName] = date('d/m', strtotime($formFieldValue));
142 } else {
143 $date = \DateTime::createFromFormat('d/m/Y', $formFieldValue) ?: \DateTime::createFromFormat('m/d/Y', $formFieldValue);
144
145 if ($date) {
146 $mergeFields[$fieldName] = $date->format('Y-m-d\T00:00:00.001\Z');
147 }
148 }
149 }
150 }
151 }
152 }
153
154 $arguments['merge_fields'] = (object) $mergeFields;
155 }
156
157 if ($entry->ip) {
158 $ipAddress = $entry->ip;
159
160 // sometimes server returns multiple IP addresses with comma separated value
161 // from multiple IP, getting the first one
162 if (strpos($ipAddress, ',') !== false) {
163 $ipArray = explode(',', $ipAddress);
164 $ipAddress = trim($ipArray[0]);
165 }
166
167 $arguments['ip_signup'] = $ipAddress;
168 }
169
170 $tags = $this->getSelectedTagIds($feedData, $formData, 'tags');
171 if (! is_array($tags)) {
172 $tags = explode(',', $tags);
173 }
174
175 $tags = array_map('trim', $tags);
176 $tags = array_filter($tags);
177
178 //explode dynamic commas values to array
179 $tagsFormatted = [];
180 foreach ($tags as $tag) {
181 if (false !== strpos($tag, ',')) {
182 $innerTags = explode(',', $tag);
183 foreach ($innerTags as $t) {
184 $tagsFormatted[] = $t;
185 }
186 } else {
187 $tagsFormatted[] = $tag;
188 }
189 }
190 if ($tags) {
191 $arguments['tags'] = array_map('trim', $tagsFormatted);
192 }
193
194 $note = '';
195 if ($feedData['note']) {
196 $note = esc_attr($feedData['note']);
197 }
198
199 $arguments['interests'] = [];
200
201 $contactHash = md5(strtolower($arguments['email_address']));
202
203 $existingMember = $this->getMemberByEmail($listId, $arguments['email_address']);
204
205 $isNew = true;
206 if (!empty($existingMember['id'])) {
207 $isNew = false;
208 if (ArrayHelper::isTrue($feedData, 'resubscribe')) {
209 //for resubscribing unsubscribed contact ; status = subscribed || pending
210 $arguments['status'] = $status;
211 }
212 // We have members so we can merge the values
213 $status = apply_filters_deprecated(
214 'fluentform_mailchimp_keep_existing_interests',
215 [
216 true,
217 $form->id
218 ],
219 FLUENTFORM_FRAMEWORK_UPGRADE,
220 'fluentform/mailchimp_keep_existing_interests',
221 'Use fluentform/mailchimp_keep_existing_interests instead of fluentform_mailchimp_keep_existing_interests.'
222 );
223 if (apply_filters('fluentform/mailchimp_keep_existing_interests', $status, $form->id)) {
224 $arguments['interests'] = ArrayHelper::get($existingMember, 'interests', []);
225 }
226
227 if (ArrayHelper::exists($arguments, 'tags')) {
228 $isExistingTags = apply_filters_deprecated(
229 'fluentform_mailchimp_keep_existing_tags',
230 [
231 true,
232 $form->id
233 ],
234 FLUENTFORM_FRAMEWORK_UPGRADE,
235 'fluentform/mailchimp_keep_existing_tags',
236 'Use fluentform/mailchimp_keep_existing_tags instead of fluentform_mailchimp_keep_existing_tags.'
237 );
238 if (apply_filters('fluentform/mailchimp_keep_existing_tags', $isExistingTags, $form->id)) {
239 $tags = ArrayHelper::get($existingMember, 'tags', []);
240 $tagNames = [];
241 foreach ($tags as $tag) {
242 $tagNames[] = $tag['name'];
243 }
244 $allTags = wp_parse_args($arguments['tags'], $tagNames);
245 $arguments['tags'] = array_unique($allTags);
246 }
247 }
248 }
249
250 if (
251 ArrayHelper::get($feedData, 'interest_group.sub_category') &&
252 ArrayHelper::get($feedData, 'interest_group.category')
253 ) {
254 $interestGroup = ArrayHelper::get($feedData, 'interest_group.sub_category');
255 $arguments['interests'][$interestGroup] = true;
256 }
257
258 $arguments = array_filter($arguments);
259 $settings = get_option('_fluentform_mailchimp_details');
260 $MailChimp = new MailChimp($settings['apiKey']);
261 $endPoint = 'lists/' . $listId . '/members/' . $contactHash;
262
263 $result = $MailChimp->put($endPoint, $arguments);
264
265 if (is_array($result) && isset($result['status']) && 400 == $result['status']) {
266 if (ArrayHelper::exists($result, 'errors')) {
267 $errors = ArrayHelper::get($result, 'errors');
268 return new \WP_Error(423, $errors);
269 }
270 return new \WP_Error(423, $result['detail']);
271 }
272
273 if ($result && ! is_wp_error($result) && isset($result['id'])) {
274 $noteEnpoint = 'lists/' . $listId . '/members/' . $contactHash . '/notes';
275 if ($note) {
276 $MailChimp->post($noteEnpoint, [
277 'note' => $note,
278 ]);
279 }
280
281 // Let's sync the tags
282 if (! $isNew && ArrayHelper::exists($arguments, 'tags')) {
283 $currentTags = [];
284 foreach ($result['tags'] as $tag) {
285 $currentTags[] = $tag['name'];
286 }
287 $newTags = $arguments['tags'];
288 sort($newTags);
289 sort($currentTags);
290
291 if ($newTags != $currentTags) {
292 $tagEnpoint = 'lists/' . $listId . '/members/' . $contactHash . '/tags';
293 if ($newTags) {
294 $formattedtags = [];
295 foreach ($newTags as $tag) {
296 $formattedtags[] = [
297 'name' => $tag,
298 'status' => 'active',
299 ];
300 }
301 $MailChimp->post($tagEnpoint, [
302 'tags' => $formattedtags,
303 ]);
304 }
305 }
306 }
307 return true;
308 }
309
310 return $result;
311 }
312
313 /**
314 * Get a specific MailChimp list member.
315 *
316 */
317 public function getMemberByEmail($list_id, $email_address)
318 {
319 $settings = get_option('_fluentform_mailchimp_details');
320 $MailChimp = new MailChimp($settings['apiKey']);
321 // Prepare subscriber hash.
322 $subscriber_hash = md5(strtolower($email_address));
323 return $MailChimp->get('lists/' . $list_id . '/members/' . $subscriber_hash);
324 }
325 }
326