| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- <?php
- namespace MailPoet\Subscription;
- if (!defined('ABSPATH')) exit;
- use MailPoet\Config\Renderer as TemplateRenderer;
- use MailPoet\Entities\StatisticsUnsubscribeEntity;
- use MailPoet\Form\AssetsController;
- use MailPoet\Models\Subscriber;
- use MailPoet\Models\SubscriberSegment;
- use MailPoet\Newsletter\Scheduler\WelcomeScheduler;
- use MailPoet\Settings\SettingsController;
- use MailPoet\Statistics\Track\Unsubscribes;
- use MailPoet\Subscribers\LinkTokens;
- use MailPoet\Subscribers\NewSubscriberNotificationMailer;
- use MailPoet\Subscribers\SubscribersRepository;
- use MailPoet\Util\Helpers;
- use MailPoet\WP\Functions as WPFunctions;
- use MailPoetVendor\Carbon\Carbon;
- class Pages {
- const DEMO_EMAIL = 'demo@mailpoet.com';
- const ACTION_CAPTCHA = 'captcha';
- const ACTION_CONFIRM = 'confirm';
- const ACTION_CONFIRM_UNSUBSCRIBE = 'confirm_unsubscribe';
- const ACTION_MANAGE = 'manage';
- const ACTION_UNSUBSCRIBE = 'unsubscribe';
- private $action;
- private $data;
- private $subscriber;
- /** @var NewSubscriberNotificationMailer */
- private $newSubscriberNotificationSender;
- /** @var SettingsController */
- private $settings;
- /** @var WPFunctions */
- private $wp;
- /** @var CaptchaRenderer */
- private $captchaRenderer;
- /** @var WelcomeScheduler */
- private $welcomeScheduler;
- /** @var LinkTokens */
- private $linkTokens;
- /** @var SubscriptionUrlFactory */
- private $subscriptionUrlFactory;
- /** @var AssetsController */
- private $assetsController;
- /** @var TemplateRenderer */
- private $templateRenderer;
- /** @var Unsubscribes */
- private $unsubscribesTracker;
- /** @var ManageSubscriptionFormRenderer */
- private $manageSubscriptionFormRenderer;
- /** @var SubscribersRepository */
- private $subscribersRepository;
- public function __construct(
- NewSubscriberNotificationMailer $newSubscriberNotificationSender,
- WPFunctions $wp,
- SettingsController $settings,
- CaptchaRenderer $captchaRenderer,
- WelcomeScheduler $welcomeScheduler,
- LinkTokens $linkTokens,
- SubscriptionUrlFactory $subscriptionUrlFactory,
- AssetsController $assetsController,
- TemplateRenderer $templateRenderer,
- Unsubscribes $unsubscribesTracker,
- ManageSubscriptionFormRenderer $manageSubscriptionFormRenderer,
- SubscribersRepository $subscribersRepository
- ) {
- $this->wp = $wp;
- $this->newSubscriberNotificationSender = $newSubscriberNotificationSender;
- $this->settings = $settings;
- $this->captchaRenderer = $captchaRenderer;
- $this->welcomeScheduler = $welcomeScheduler;
- $this->linkTokens = $linkTokens;
- $this->subscriptionUrlFactory = $subscriptionUrlFactory;
- $this->assetsController = $assetsController;
- $this->templateRenderer = $templateRenderer;
- $this->unsubscribesTracker = $unsubscribesTracker;
- $this->manageSubscriptionFormRenderer = $manageSubscriptionFormRenderer;
- $this->subscribersRepository = $subscribersRepository;
- }
- public function init($action = false, $data = [], $initShortcodes = false, $initPageFilters = false) {
- $this->action = $action;
- $this->data = $data;
- $this->subscriber = $this->getSubscriber();
- if ($initPageFilters) $this->initPageFilters();
- if ($initShortcodes) $this->initShortcodes();
- return $this;
- }
- private function isPreview() {
- return (array_key_exists('preview', $_GET) || array_key_exists('preview', $this->data));
- }
- public function initPageFilters() {
- $this->wp->addFilter('wp_title', [$this,'setWindowTitle'], 10, 3);
- $this->wp->addFilter('document_title_parts', [$this,'setWindowTitleParts'], 10, 1);
- $this->wp->addFilter('the_title', [$this,'setPageTitle'], 10, 1);
- $this->wp->addFilter('the_content', [$this,'setPageContent'], 10, 1);
- $this->wp->removeAction('wp_head', 'noindex', 1);
- $this->wp->addAction('wp_head', [$this, 'setMetaRobots'], 1);
- }
- public function initShortcodes() {
- $this->wp->addShortcode('mailpoet_manage', [$this, 'getManageLink']);
- $this->wp->addShortcode('mailpoet_manage_subscription', [$this, 'getManageContent']);
- }
- /**
- * @return Subscriber|null
- */
- private function getSubscriber() {
- if (!is_null($this->subscriber)) {
- return $this->subscriber;
- }
- $token = (isset($this->data['token'])) ? $this->data['token'] : null;
- $email = (isset($this->data['email'])) ? $this->data['email'] : null;
- $wpUser = $this->wp->wpGetCurrentUser();
- if (!$email && $wpUser->exists()) {
- $subscriber = Subscriber::where('wp_user_id', $wpUser->ID)->findOne();
- return $subscriber !== false ? $subscriber : null;
- }
- if (!$email) {
- return null;
- }
- $subscriber = Subscriber::where('email', $email)->findOne();
- $subscriberEntity = $subscriber ? $this->subscribersRepository->findOneById($subscriber->id) : null;
- return ($subscriber && $subscriberEntity && $this->linkTokens->verifyToken($subscriberEntity, $token)) ? $subscriber : null;
- }
- public function confirm() {
- $this->subscriber = $this->getSubscriber();
- if ($this->subscriber === null) {
- return false;
- }
- $subscriberData = $this->subscriber->getUnconfirmedData();
- $originalStatus = $this->subscriber->status;
- $this->subscriber->status = Subscriber::STATUS_SUBSCRIBED;
- $this->subscriber->confirmedIp = Helpers::getIP();
- $this->subscriber->confirmedAt = Carbon::createFromTimestamp($this->wp->currentTime('timestamp'));
- $this->subscriber->lastSubscribedAt = Carbon::createFromTimestamp($this->wp->currentTime('timestamp'));
- $this->subscriber->unconfirmedData = null;
- $this->subscriber->save();
- if ($this->subscriber->getErrors() !== false) {
- return false;
- }
- // Schedule welcome emails
- $subscriberSegments = $this->subscriber->segments()->findMany();
- if ($subscriberSegments) {
- $this->welcomeScheduler->scheduleSubscriberWelcomeNotification(
- $this->subscriber->id,
- array_map(function ($segment) {
- return $segment->get('id');
- }, $subscriberSegments)
- );
- }
- // Send new subscriber notification only when status changes to subscribed or there are unconfirmed data to avoid spamming
- if ($originalStatus !== Subscriber::STATUS_SUBSCRIBED || $subscriberData !== null) {
- $this->newSubscriberNotificationSender->send($this->subscriber, $subscriberSegments);
- }
- // Update subscriber from stored data after confirmation
- if (!empty($subscriberData)) {
- Subscriber::createOrUpdate($subscriberData);
- }
- }
- public function unsubscribe() {
- if (!$this->isPreview()
- && ($this->subscriber !== null)
- && ($this->subscriber->status !== Subscriber::STATUS_UNSUBSCRIBED)
- ) {
- if ((bool)$this->settings->get('tracking.enabled') && isset($this->data['queueId'])) {
- $this->unsubscribesTracker->track(
- (int)$this->subscriber->id,
- StatisticsUnsubscribeEntity::SOURCE_NEWSLETTER,
- (int)$this->data['queueId']
- );
- }
- $this->subscriber->status = Subscriber::STATUS_UNSUBSCRIBED;
- $this->subscriber->save();
- SubscriberSegment::unsubscribeFromSegments($this->subscriber);
- }
- }
- public function setMetaRobots() {
- echo '<meta name="robots" content="noindex,nofollow">';
- }
- public function setPageTitle($pageTitle = '') {
- global $post;
- if (
- ($post->post_title !== $this->wp->__('MailPoet Page', 'mailpoet')) // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
- ||
- ($pageTitle !== $this->wp->singlePostTitle('', false))
- ) {
- // when it's a custom page, just return the original page title
- return $pageTitle;
- } elseif ($this->action !== self::ACTION_CAPTCHA && $this->isPreview() === false && $this->subscriber === null) {
- return $this->wp->__("Hmmm... we don't have a record of you.", 'mailpoet');
- } else {
- // when it's our own page, generate page title based on requested action
- switch ($this->action) {
- case self::ACTION_CAPTCHA:
- return $this->captchaRenderer->getCaptchaPageTitle();
- case self::ACTION_CONFIRM:
- return $this->getConfirmTitle();
- case self::ACTION_CONFIRM_UNSUBSCRIBE:
- return $this->getConfirmUnsubscribeTitle();
- case self::ACTION_MANAGE:
- return $this->getManageTitle();
- case self::ACTION_UNSUBSCRIBE:
- return $this->getUnsubscribeTitle();
- }
- }
- }
- public function setPageContent($pageContent = '[mailpoet_page]') {
- // if we're not in preview mode or captcha page and the subscriber does not exist
- if ($this->action !== self::ACTION_CAPTCHA && $this->isPreview() === false && $this->subscriber === null) {
- return $this->wp->__("Your email address doesn't appear in our lists anymore. Sign up again or contact us if this appears to be a mistake.", 'mailpoet');
- }
- $this->assetsController->setupFrontEndDependencies();
- if (strpos($pageContent, '[mailpoet_page]') !== false) {
- $content = '';
- switch ($this->action) {
- case self::ACTION_CAPTCHA:
- $captchaSessionId = isset($this->data['captcha_session_id']) ? $this->data['captcha_session_id'] : null;
- $content = $this->captchaRenderer->getCaptchaPageContent($captchaSessionId);
- break;
- case self::ACTION_CONFIRM:
- $content = $this->getConfirmContent();
- break;
- case self::ACTION_CONFIRM_UNSUBSCRIBE:
- $content = $this->getConfirmUnsubscribeContent();
- break;
- case self::ACTION_MANAGE:
- $content = $this->getManageContent();
- break;
- case self::ACTION_UNSUBSCRIBE:
- $content = $this->getUnsubscribeContent();
- break;
- }
- return str_replace('[mailpoet_page]', trim($content), $pageContent);
- } else {
- return $pageContent;
- }
- }
- public function setWindowTitle($title, $separator, $separatorLocation = 'right') {
- $titleParts = explode(" $separator ", $title);
- if (!is_array($titleParts)) {
- return $title;
- }
- if ($separatorLocation === 'right') {
- // first part
- $titleParts[0] = $this->setPageTitle($titleParts[0]);
- } else {
- // last part
- $lastIndex = count($titleParts) - 1;
- $titleParts[$lastIndex] = $this->setPageTitle($titleParts[$lastIndex]);
- }
- return implode(" $separator ", $titleParts);
- }
- public function setWindowTitleParts($meta = []) {
- $meta['title'] = $this->setPageTitle($meta['title']);
- return $meta;
- }
- private function getConfirmTitle() {
- if ($this->isPreview()) {
- $title = sprintf(
- $this->wp->__("You have subscribed to: %s", 'mailpoet'),
- 'demo 1, demo 2'
- );
- } else {
- $segmentNames = array_map(function($segment) {
- return $segment->name;
- }, $this->subscriber->segments()->findMany());
- if (empty($segmentNames)) {
- $title = $this->wp->__("You are now subscribed!", 'mailpoet');
- } else {
- $title = sprintf(
- $this->wp->__("You have subscribed to: %s", 'mailpoet'),
- join(', ', $segmentNames)
- );
- }
- }
- return $title;
- }
- private function getManageTitle() {
- if ($this->isPreview() || $this->subscriber !== null) {
- return $this->wp->__("Manage your subscription", 'mailpoet');
- }
- }
- private function getUnsubscribeTitle() {
- if ($this->isPreview() || $this->subscriber !== null) {
- return $this->wp->__("You are now unsubscribed.", 'mailpoet');
- }
- }
- private function getConfirmUnsubscribeTitle() {
- if ($this->isPreview() || $this->subscriber !== null) {
- return $this->wp->__('Confirm you want to unsubscribe', 'mailpoet');
- }
- }
- private function getConfirmContent() {
- if ($this->isPreview() || $this->subscriber !== null) {
- return $this->wp->__("Yup, we've added you to our email list. You'll hear from us shortly.", 'mailpoet');
- }
- }
- public function getManageContent() {
- if ($this->isPreview()) {
- $subscriber = Subscriber::create();
- $subscriber->hydrate([
- 'email' => self::DEMO_EMAIL,
- 'first_name' => 'John',
- 'last_name' => 'Doe',
- 'link_token' => 'bfd0889dbc7f081e171fa0cee7401df2',
- ]);
- } else if ($this->subscriber !== null) {
- $subscriber = $this->subscriber
- ->withCustomFields()
- ->withSubscriptions();
- } else {
- return $this->wp->__('Subscription management form is only available to mailing lists subscribers.', 'mailpoet');
- }
- $formStatus = isset($_GET['success']) && $_GET['success']
- ? ManageSubscriptionFormRenderer::FORM_STATE_SUCCESS
- : ManageSubscriptionFormRenderer::FORM_STATE_NOT_SUBMITTED;
- return $this->wp->applyFilters(
- 'mailpoet_manage_subscription_page',
- $this->manageSubscriptionFormRenderer->renderForm($subscriber, $formStatus)
- );
- }
- private function getUnsubscribeContent() {
- $content = '';
- if ($this->isPreview() || $this->subscriber !== null) {
- $content .= '<p>' . __('Accidentally unsubscribed?', 'mailpoet') . ' <strong>';
- $content .= '[mailpoet_manage]';
- $content .= '</strong></p>';
- }
- return $content;
- }
- private function getConfirmUnsubscribeContent() {
- if (!$this->isPreview() && $this->subscriber === null) {
- return '';
- }
- $queueId = isset($this->data['queueId']) ? (int)$this->data['queueId'] : null;
- $subscriberEntity = $this->subscriber ? $this->subscribersRepository->findOneById($this->subscriber->id) : null;
- $unsubscribeUrl = $this->subscriptionUrlFactory->getUnsubscribeUrl($subscriberEntity, $queueId);
- $templateData = [
- 'unsubscribeUrl' => $unsubscribeUrl,
- ];
- return $this->wp->applyFilters(
- 'mailpoet_unsubscribe_confirmation_page',
- $this->templateRenderer->render('subscription/confirm_unsubscribe.html', $templateData),
- $unsubscribeUrl
- );
- }
- public function getManageLink($params) {
- if (!$this->subscriber instanceof Subscriber) return __('Link to subscription management page is only available to mailing lists subscribers.', 'mailpoet');
- // get label or display default label
- $text = (
- isset($params['text'])
- ? htmlspecialchars($params['text'])
- : $this->wp->__('Manage your subscription', 'mailpoet')
- );
- $subscriberEntity = $this->subscribersRepository->findOneById($this->subscriber->id);
- return '<a href="' . $this->subscriptionUrlFactory->getManageUrl($subscriberEntity) . '">' . $text . '</a>';
- }
- }
|