From 2a96cf3766af421070b6ed5010538b1b10da207f Mon Sep 17 00:00:00 2001 From: Kamil Date: Wed, 6 Apr 2022 12:17:02 +0200 Subject: [PATCH] Initial commit --- Block/PreferencesForm.php | 51 ++++++ Controller/Preferences/AddInterest.php | 83 +++++++++ Controller/Preferences/Index.php | 173 ++++++++++++++++++ Controller/Subscribe/Index.php | 152 +++++++++++++++ README.md | 9 + composer.json | 22 +++ etc/frontend/routes.xml | 8 + etc/module.xml | 8 + registration.php | 7 + .../layout/newsletter_preferences_index.xml | 12 ++ .../frontend/templates/preferences/form.phtml | 171 +++++++++++++++++ 11 files changed, 696 insertions(+) create mode 100644 Block/PreferencesForm.php create mode 100644 Controller/Preferences/AddInterest.php create mode 100644 Controller/Preferences/Index.php create mode 100644 Controller/Subscribe/Index.php create mode 100644 README.md create mode 100644 composer.json create mode 100644 etc/frontend/routes.xml create mode 100644 etc/module.xml create mode 100644 registration.php create mode 100644 view/frontend/layout/newsletter_preferences_index.xml create mode 100644 view/frontend/templates/preferences/form.phtml diff --git a/Block/PreferencesForm.php b/Block/PreferencesForm.php new file mode 100644 index 0000000..305678e --- /dev/null +++ b/Block/PreferencesForm.php @@ -0,0 +1,51 @@ +storeManager = $context->getStoreManager(); + $this->mailchimpData = $mailchimpData; + } + + public function getStoreId(): int + { + return $this->storeManager->getStore()->getId(); + } + + public function getInterest(): array + { + return $this->mailchimpData->getInterest($this->getStoreId()); + } + + public function getMergeFields(): array + { + $api = $this->mailchimpData->getApi($this->getStoreId()); + $listId = $this->mailchimpData->getDefaultList(); + /** @var \Mailchimp_ListsMergeFields **/ + $mergeApi = $api->lists->mergeFields; + + $mergeFields = $mergeApi->getAll($listId, "merge_fields")["merge_fields"]; + usort($mergeFields, function ($a, $b) { + return $a['display_order'] - $b['display_order']; + }); + + return $mergeFields; + } +} diff --git a/Controller/Preferences/AddInterest.php b/Controller/Preferences/AddInterest.php new file mode 100644 index 0000000..7454ef5 --- /dev/null +++ b/Controller/Preferences/AddInterest.php @@ -0,0 +1,83 @@ +context = $context; + $this->mailchimpData = $mailchimpData; + $this->storeManager = $storeManager; + } + + public function execute() + { + $params = $this->getRequest()->getParams(); + $member = $params['memberId'] ?? null; + $interest = $params['interestId'] ?? null; + + $storeId = $this->storeManager->getStore()->getId(); + + $api = $this->mailchimpData->getApi($storeId); + $listId = $this->mailchimpData->getDefaultList(); + + if (!$member || !$interest) { + $this->messageManager->addWarning(__("This link is incorrect. You can subscribe from this page")); + + return $this->_redirect("newsletter/preferences"); + } + + /** @var \Mailchimp_ListsMembers **/ + $members = $api->lists->members; + $search = $members->getAll($listId, null, null, 1, null, null, null, null, null, null, null, $member); + $member = count($search['members']) === 1 ? $search['members'][0] : null; + + if (!$member) { + $this->messageManager->addWarning(__("Subscriber information was not found. You can subscribe from this page")); + + return $this->_redirect("newsletter/preferences"); + } + + $interests = $member['interests']; + + if (!isset($interests[$interest])) { + $this->messageManager->addWarning(__("Failed to update interests. You can do it from this page")); + + return $this->_redirect("newsletter/preferences", ["memberId" => $member["unique_email_id"]]); + } + + $interests[$interest] = true; + + try { + $update = $members->update($listId, $member['id'], null, null, null, $interests); + } catch (\Exception $e) { + $this->messageManager->addError(__("Something went wrong while saving your information.")); + + return $this->_redirect("newsletter/preferences", ["memberId" => $member["unique_email_id"]]); + } + + $this->messageManager->addSuccess(__("Your preference was updated. You can add more interests on this page")); + + return $this->_redirect("newsletter/preferences", ["memberId" => $member["unique_email_id"]]); + } +} diff --git a/Controller/Preferences/Index.php b/Controller/Preferences/Index.php new file mode 100644 index 0000000..6222a46 --- /dev/null +++ b/Controller/Preferences/Index.php @@ -0,0 +1,173 @@ +context = $context; + $this->pageFactory = $pageFactory; + $this->mailchimpData = $mailchimpData; + $this->storeManager = $storeManager; + $this->formKeyValidator = $formKeyValidator; + $this->logger = $logger; + } + + public function execute() + { + $params = $this->getRequest()->getParams(); + $member = $params['memberId'] ?? null; + + $storeId = $this->getStoreId(); + + $api = $this->mailchimpData->getApi($storeId); + $listId = $this->mailchimpData->getDefaultList(); + + /** @var \Mailchimp_ListsMembers **/ + $members = $api->lists->members; + + if ($member) { + $search = $members->getAll($listId, null, null, 1, null, null, null, null, null, null, null, $member); + + $member = count($search['members']) === 1 ? $search['members'][0] : null; + } + + if (!$member) { + $this->messageManager->addWarning(__("We were not able to find your details, but you can subscribe from this page.")); + + return $this->_redirect("newsletter/subscribe"); + } + + $resultPage = $this->pageFactory->create(); + $block = $resultPage->getLayout()->getBlock('newsletter.preferences_form'); + + if ($block) { + $block->setMember($member); + } + + if (!$this->getRequest()->isPost()) { + return $resultPage; + } + + if (!$this->formKeyValidator->validate($this->getRequest())) { + $this->messageManager->addWarning(__("Invalid form security key. Please try again")); + + return $resultPage; + } + + + $errors = []; + + $post = $this->getRequest()->getParam("member", []); + + $post['interest'] = $post['interest'] ?? []; + + if (is_array($post['interest'])) { + $interests = $member['interests'] ?? $this->getInterests(); + + foreach ($interests as $interest => $isInterested) { + $interests[$interest] = in_array($interest, $post['interest']); + } + } + + if (!$member && (!$post['email'] || !filter_var($post['email'], FILTER_VALIDATE_EMAIL))) { + $errors['email'] = [__("Please enter valid email address")]; + } + + $postMergeFields = is_array($post['data']) ? $post['data'] : null; + + foreach ($this->getMergeFields() as $mergeField) { + $tag = $mergeField["tag"]; + + if ($mergeField['public'] === false) { + if (array_key_exists($tag, $postMergeFields)) { + unset($postMergeFields[$tag]); + } + + continue; + } + + if ($mergeField['required'] === false) { + continue; + } + + if (empty($postMergeFields[$tag])) { + $errors["data[${tag}]"] = [__("This field is required")]; + } + } + + if (empty($errors)) { + try { + $saved = $member + ? $members->update($listId, $member['id'], null, "subscribed", $postMergeFields, $interests) + : $members->add($listId, "subscribed", $post['email'], null, $postMergeFields, $interests); + + $this->messageManager->addSuccess(__("Your preferences were successfully saved!")); + + return $this->_redirect("newsletter/preferences", ["memberId" => $saved["unique_email_id"]]); + } catch (\Exception $e) { + $this->messageManager->addError(__("Something went wrong while saving your information.")); + $this->logger->error($e->getMessage()); + } + } else { + $this->messageManager->addError(__("Please correct errors in form and try again")); + } + + $block->setPostData($post); + $block->setErrors($errors); + + return $resultPage; + } + + private function getStoreId(): int + { + return $this->storeManager->getStore()->getId(); + } + + private function getInterests(): array + { + return $this->mailchimpData->getInterest($this->getStoreId()); + } + + private function getMergeFields(): array + { + $api = $this->mailchimpData->getApi($this->getStoreId()); + $listId = $this->mailchimpData->getDefaultList(); + /** @var \Mailchimp_ListsMergeFields **/ + $mergeApi = $api->lists->mergeFields; + + $mergeFields = $mergeApi->getAll($listId, "merge_fields")["merge_fields"]; + + return $mergeFields; + } +} diff --git a/Controller/Subscribe/Index.php b/Controller/Subscribe/Index.php new file mode 100644 index 0000000..6ec374c --- /dev/null +++ b/Controller/Subscribe/Index.php @@ -0,0 +1,152 @@ +context = $context; + $this->pageFactory = $pageFactory; + $this->mailchimpData = $mailchimpData; + $this->storeManager = $storeManager; + $this->formKeyValidator = $formKeyValidator; + $this->logger = $logger; + } + + public function execute() + { + $params = $this->getRequest()->getParams(); + $member = $params['memberId'] ?? null; + + $storeId = $this->storeManager->getStore()->getId(); + + $api = $this->mailchimpData->getApi($storeId); + $listId = $this->mailchimpData->getDefaultList(); + + /** @var \Mailchimp_ListsMembers **/ + $members = $api->lists->members; + + if ($member) { + $search = $members->getAll($listId, null, null, 1, null, null, null, null, null, null, null, $member); + + $member = count($search['members']) === 1 ? $search['members'][0] : null; + + if (!$member) { + $this->messageManager->addWarning(__("We were not able to find your details, but you can subscribe from this page.")); + } + } + + $resultPage = $this->pageFactory->create(); + $block = $resultPage->getLayout()->getBlock('newsletter.preferences_form'); + + if ($this->getRequest()->isPost()) { + if (!$this->formKeyValidator->validate($this->getRequest())) { + $this->messageManager->addWarning(__("Invalid form security key. Please try again")); + } else { + $errors = []; + + $post = $this->getRequest()->getParam("member", []); + + $mergeFields = is_array($post['data']) ? $post['data'] : null; + + $post['interest'] = $post['interest'] ?? []; + + if (is_array($post['interest'])) { + $interests = $member['interests'] ?? $this->getInterests(); + + foreach ($interests as $interest => $isInterested) { + $interests[$interest] = in_array($interest, $post['interest']); + } + } + + if (!$member && (!$post['email'] || !filter_var($post['email'], FILTER_VALIDATE_EMAIL))) { + $errors['email'] = [__("Please enter valid email address")]; + } + + if (empty($errors)) { + try { + $saved = $member + ? $members->update($listId, $member['id'], null, "subscribed", $mergeFields, $interests) + : $members->add($listId, "subscribed", $post['email'], null, $mergeFields, $interests); + + $this->messageManager->addSuccess(__("Your preferences were successfully saved!")); + + return $this->_redirect("newsletter/preferences", ["memberId" => $saved["unique_email_id"]]); + } catch (\Exception $e) { + $this->messageManager->addError(__("Something went wrong while saving your information.")); + $this->logger->error($e->getMessage()); + } + } else { + $this->messageManager->addError(__("Please correct errors in form and try again")); + } + + $block->setPostData($post); + $block->setErrors($errors); + } + } + + if ($block) { + if ($member) { + $block->setMember($member); + } + } + + if (!$member) { + $resultPage->getConfig()->getTitle()->set(__("Subscribe to Newsletter")); + } + + return $resultPage; + } + + private function getStoreId(): int + { + return $this->storeManager->getStore()->getId(); + } + + private function getInterests(): array + { + return $this->mailchimpData->getInterest($this->getStoreId()); + } + + private function getMergeFields(): array + { + $api = $this->mailchimpData->getApi($this->getStoreId()); + $listId = $this->mailchimpData->getDefaultList(); + /** @var \Mailchimp_ListsMergeFields **/ + $mergeApi = $api->lists->mergeFields; + + $mergeFields = $mergeApi->getAll($listId, "merge_fields")["merge_fields"]; + + return $mergeFields; + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..3a56b27 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# Kingfisher Direct - Mailchimp Extras + +> A Magento 2 module to extend Mailchimp integration provided by +> official Mailchimp extension + +## Extra Functionalities + +- Adds Mailchimp driven preferences form +- Adds a route to add interest to subscriber diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..d5f014d --- /dev/null +++ b/composer.json @@ -0,0 +1,22 @@ +{ + "name": "kingfisherdirect/magento2-mailchimp-extras", + "type": "magento2-module", + "license": "MIT", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "KingfisherDirect\\MailchimpExtras\\": "" + } + }, + "authors": [ + { + "name": "Kamil", + "email": "kamil@kingfisherdirect.co.uk" + } + ], + "require": { + "mailchimp/mc-magento2": "^102.3" + } +} diff --git a/etc/frontend/routes.xml b/etc/frontend/routes.xml new file mode 100644 index 0000000..d85e643 --- /dev/null +++ b/etc/frontend/routes.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/etc/module.xml b/etc/module.xml new file mode 100644 index 0000000..80e6b9a --- /dev/null +++ b/etc/module.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/registration.php b/registration.php new file mode 100644 index 0000000..7ef0860 --- /dev/null +++ b/registration.php @@ -0,0 +1,7 @@ + + + + + Marketing Preference Center + + + + + + + diff --git a/view/frontend/templates/preferences/form.phtml b/view/frontend/templates/preferences/form.phtml new file mode 100644 index 0000000..bba740a --- /dev/null +++ b/view/frontend/templates/preferences/form.phtml @@ -0,0 +1,171 @@ +getMember(); +$fields = $block->getMergeFields(); +$interests = $block->getInterest(); +$postData = $block->getPostData(); +$errors = $block->getErrors() ?? []; + +$memberData = $member ? $member['merge_fields'] : []; +$memberInterests = $member ? $member['interests'] : []; +?> + +
+
+ +
+ +
+ " + class="control " + required + data-validate='{"validate-email": true}' /> +
+ +
+ +
+ +
+ +
+ + + + + +
+ +
+ +

+ + By submitting your details, you are giving your consent to receive updates on new product launches, useful guides and fantastic offers from us. If you wish to stop receiving these you can unsubscribe at any time. + +

+ +

+ + For more information on how we use your data please see our ">privacy policy. + +

+