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 / Newsletter / ViewInBrowser / ViewInBrowserController.php
mailpoet / lib / Newsletter / ViewInBrowser Last commit date
ViewInBrowserController.php 1 month ago ViewInBrowserRenderer.php 2 months ago index.php 3 years ago
ViewInBrowserController.php
156 lines
1 <?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
2
3 namespace MailPoet\Newsletter\ViewInBrowser;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\EmailEditor\Integrations\MailPoet\DependencyNotice;
9 use MailPoet\Entities\SubscriberEntity;
10 use MailPoet\Newsletter\NewslettersRepository;
11 use MailPoet\Newsletter\Sending\SendingQueuesRepository;
12 use MailPoet\Newsletter\Sharing\ShareMetadataBuilder;
13 use MailPoet\Newsletter\Sharing\ShareVisibility;
14 use MailPoet\Newsletter\Url as NewsletterUrl;
15 use MailPoet\Subscribers\LinkTokens;
16 use MailPoet\Subscribers\SubscribersRepository;
17
18 class ViewInBrowserController {
19 /** @var LinkTokens */
20 private $linkTokens;
21
22 /** @var NewsletterUrl */
23 private $newsletterUrl;
24
25 /** @var ViewInBrowserRenderer */
26 private $viewInBrowserRenderer;
27
28 /** @var SubscribersRepository */
29 private $subscribersRepository;
30
31 /** @var SendingQueuesRepository */
32 private $sendingQueuesRepository;
33
34 /** @var NewslettersRepository */
35 private $newslettersRepository;
36
37 /** @var DependencyNotice */
38 private $dependencyNotice;
39
40 /** @var ShareVisibility */
41 private $shareVisibility;
42
43 /** @var ShareMetadataBuilder */
44 private $shareMetadataBuilder;
45
46 public function __construct(
47 LinkTokens $linkTokens,
48 NewsletterUrl $newsletterUrl,
49 NewslettersRepository $newslettersRepository,
50 ViewInBrowserRenderer $viewInBrowserRenderer,
51 SendingQueuesRepository $sendingQueuesRepository,
52 DependencyNotice $dependencyNotice,
53 SubscribersRepository $subscribersRepository,
54 ShareVisibility $shareVisibility,
55 ShareMetadataBuilder $shareMetadataBuilder
56 ) {
57 $this->linkTokens = $linkTokens;
58 $this->viewInBrowserRenderer = $viewInBrowserRenderer;
59 $this->subscribersRepository = $subscribersRepository;
60 $this->sendingQueuesRepository = $sendingQueuesRepository;
61 $this->newsletterUrl = $newsletterUrl;
62 $this->dependencyNotice = $dependencyNotice;
63 $this->newslettersRepository = $newslettersRepository;
64 $this->shareVisibility = $shareVisibility;
65 $this->shareMetadataBuilder = $shareMetadataBuilder;
66 }
67
68 public function view(array $data) {
69 $data = $this->newsletterUrl->transformUrlDataObject($data);
70 $isPreview = !empty($data['preview']);
71 $newsletter = $this->getNewsletter($data);
72 $subscriber = $this->getSubscriber($data);
73 if ($newsletter->getWpPostId() && $this->dependencyNotice->checkDependenciesAndEventuallyShowNotice()) {
74 return '';
75 }
76
77 // if queue and subscriber exist, subscriber must have received the newsletter
78 $queue = isset($data['queue_id']) ? $this->sendingQueuesRepository->findOneById($data['queue_id']) : null;
79 if (!$isPreview && $queue && $subscriber->getId() && !$this->sendingQueuesRepository->isSubscriberProcessed($queue, $subscriber)) {
80 throw new \InvalidArgumentException("Subscriber did not receive the newsletter yet");
81 }
82
83 $html = $this->viewInBrowserRenderer->render($isPreview, $newsletter, $subscriber, $queue);
84 if (!empty($data['embed_hide_background'])) {
85 // Public embed URLs may request this cosmetic-only presentation variant.
86 $html = $this->hideEmbedBackground($html);
87 }
88 if (!$isPreview && $this->shareVisibility->canShare($newsletter)) {
89 $publicUrl = $this->newsletterUrl->getPublicShareUrl($newsletter);
90 // Pass $publicUrl as both the share target and the replaceState target so the
91 // tokenised view-in-browser URL is scrubbed from the address bar on load.
92 return $this->shareMetadataBuilder->injectShareToolbar($html, $newsletter, $publicUrl, $publicUrl);
93 }
94 return $html;
95 }
96
97 private function hideEmbedBackground(string $html): string {
98 $style = '<style id="mailpoet-newsletter-embed-background">html,body{background:transparent!important;}body{padding:0!important;}</style>';
99 $headPosition = stripos($html, '</head>');
100 if ($headPosition !== false) {
101 return substr_replace($html, $style, $headPosition, 0);
102 }
103
104 $matches = [];
105 if (preg_match('/<html\b[^>]*>/i', $html, $matches, PREG_OFFSET_CAPTURE)) {
106 $position = $matches[0][1] + strlen($matches[0][0]);
107 return substr_replace($html, $style, $position, 0);
108 }
109
110 return $style . $html;
111 }
112
113 private function getNewsletter(array $data) {
114 // newsletter - ID is mandatory, hash must be set and valid
115 if (empty($data['newsletter_id'])) {
116 throw new \InvalidArgumentException("Missing 'newsletter_id'");
117 }
118 if (empty($data['newsletter_hash'])) {
119 throw new \InvalidArgumentException("Missing 'newsletter_hash'");
120 }
121
122 $newsletter = $this->newslettersRepository->findOneById($data['newsletter_id']);
123 if (!$newsletter) {
124 throw new \InvalidArgumentException("Invalid 'newsletter_id'");
125 }
126
127 if ($data['newsletter_hash'] !== $newsletter->getHash()) {
128 throw new \InvalidArgumentException("Invalid 'newsletter_hash'");
129 }
130 return $newsletter;
131 }
132
133 private function getSubscriber(array $data): SubscriberEntity {
134 // subscriber is optional; if exists, token must validate
135 $subscriber = null;
136 if (!empty($data['subscriber_id'])) {
137 $subscriber = $this->subscribersRepository->findOneById($data['subscriber_id']);
138 }
139 if ($subscriber && empty($data['subscriber_token'])) {
140 throw new \InvalidArgumentException("Missing 'subscriber_token'");
141 }
142
143 if ($subscriber && !$this->linkTokens->verifyToken($subscriber, $data['subscriber_token'])) {
144 throw new \InvalidArgumentException("Invalid 'subscriber_token'");
145 }
146
147 // if this is a preview and subscriber does not exist,
148 // attempt to set subscriber to the current logged-in WP user
149 if (!$subscriber && !empty($data['preview'])) {
150 $subscriber = $this->subscribersRepository->getCurrentWPUser();
151 }
152
153 return $subscriber ?? new SubscriberEntity();
154 }
155 }
156