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 / Config / Shortcodes.php
mailpoet / lib / Config Last commit date
PopulatorData 2 months ago AccessControl.php 2 years ago Activator.php 2 months ago AssetsLoader.php 2 weeks ago Capabilities.php 2 months ago Changelog.php 2 months ago DeactivationPoll.php 3 years ago DeferredAdminNotices.php 2 months ago Env.php 6 months ago Hooks.php 1 month ago HooksWooCommerce.php 1 month ago Initializer.php 1 month ago Installer.php 10 months ago Localizer.php 3 years ago Menu.php 1 month ago PersonalDataErasers.php 1 month ago PersonalDataExporters.php 1 month ago PluginActivatedHook.php 3 years ago Populator.php 2 weeks ago PrivacyPolicy.php 1 month ago Renderer.php 1 year ago RendererFactory.php 3 years ago RequirementsChecker.php 2 months ago Router.php 2 months ago ServicesChecker.php 3 years ago Shortcodes.php 1 month ago SilentUpgraderSkin.php 3 years ago SubscriberChangesNotifier.php 2 months ago TranslationUpdater.php 3 months ago TwigEnvironment.php 1 year ago TwigFileSystemCache.php 3 years ago Updater.php 4 days ago index.php 3 years ago
Shortcodes.php
323 lines
1 <?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
2
3 namespace MailPoet\Config;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\Entities\NewsletterEntity;
9 use MailPoet\Entities\SendingQueueEntity;
10 use MailPoet\Entities\SubscriberEntity;
11 use MailPoet\Form\Widget;
12 use MailPoet\Newsletter\Embed\NewsletterEmbedService;
13 use MailPoet\Newsletter\NewslettersRepository;
14 use MailPoet\Newsletter\Sharing\ShareVisibility;
15 use MailPoet\Newsletter\Shortcodes\Categories\Date;
16 use MailPoet\Newsletter\Shortcodes\Categories\Link;
17 use MailPoet\Newsletter\Shortcodes\Categories\Newsletter;
18 use MailPoet\Newsletter\Shortcodes\Categories\Site;
19 use MailPoet\Newsletter\Shortcodes\Categories\Subscriber as SubscriberCategory;
20 use MailPoet\Newsletter\Shortcodes\Shortcodes as NewsletterShortcodes;
21 use MailPoet\Newsletter\Url as NewsletterUrl;
22 use MailPoet\Segments\SegmentSubscribersRepository;
23 use MailPoet\Subscribers\SubscribersRepository;
24 use MailPoet\Subscription\Pages;
25 use MailPoet\WP\Functions as WPFunctions;
26 use MailPoetVendor\Carbon\CarbonImmutable;
27
28 class Shortcodes {
29 const DEFAULT_ARCHIVE_LIMIT = 100;
30
31 /** @var Pages */
32 private $subscriptionPages;
33
34 /** @var WPFunctions */
35 private $wp;
36
37 /** @var SegmentSubscribersRepository */
38 private $segmentSubscribersRepository;
39
40 /** @var SubscribersRepository */
41 private $subscribersRepository;
42
43 /** @var NewsletterUrl */
44 private $newsletterUrl;
45
46 /** @var NewslettersRepository */
47 private $newslettersRepository;
48
49 /** @var ShareVisibility */
50 private $shareVisibility;
51
52 /** @var Date */
53 private $dateCategory;
54
55 /** @var Link */
56 private $linkCategory;
57
58 /** @var Newsletter */
59 private $newsletterCategory;
60
61 /** @var SubscriberCategory */
62 private $subscriberCategory;
63
64 /** @var Site */
65 private $siteCategory;
66
67 /** @var NewsletterEmbedService */
68 private $newsletterEmbedService;
69
70 public function __construct(
71 Pages $subscriptionPages,
72 WPFunctions $wp,
73 SegmentSubscribersRepository $segmentSubscribersRepository,
74 SubscribersRepository $subscribersRepository,
75 NewsletterUrl $newsletterUrl,
76 NewslettersRepository $newslettersRepository,
77 ShareVisibility $shareVisibility,
78 Date $dateCategory,
79 Link $linkCategory,
80 Newsletter $newsletterCategory,
81 SubscriberCategory $subscriberCategory,
82 Site $siteCategory,
83 NewsletterEmbedService $newsletterEmbedService
84 ) {
85 $this->subscriptionPages = $subscriptionPages;
86 $this->wp = $wp;
87 $this->segmentSubscribersRepository = $segmentSubscribersRepository;
88 $this->subscribersRepository = $subscribersRepository;
89 $this->newsletterUrl = $newsletterUrl;
90 $this->newslettersRepository = $newslettersRepository;
91 $this->shareVisibility = $shareVisibility;
92 $this->dateCategory = $dateCategory;
93 $this->linkCategory = $linkCategory;
94 $this->newsletterCategory = $newsletterCategory;
95 $this->subscriberCategory = $subscriberCategory;
96 $this->siteCategory = $siteCategory;
97 $this->newsletterEmbedService = $newsletterEmbedService;
98 }
99
100 public function init() {
101 // form widget shortcode
102 $this->wp->addShortcode('mailpoet_form', [$this, 'formWidget']);
103
104 // subscribers count shortcode
105 $this->wp->addShortcode('mailpoet_subscribers_count', [
106 $this, 'getSubscribersCount',
107 ]);
108 $this->wp->addShortcode('wysija_subscribers_count', [
109 $this, 'getSubscribersCount',
110 ]);
111
112 // archives page
113 $this->wp->addShortcode('mailpoet_archive', [
114 $this, 'getArchive',
115 ]);
116 $this->wp->addShortcode('mailpoet_newsletter', [
117 $this, 'getNewsletterEmbed',
118 ]);
119
120 $this->wp->addFilter('mailpoet_archive_email_processed_date', [
121 $this, 'renderArchiveDate',
122 ], 2);
123 $this->wp->addFilter('mailpoet_archive_email_subject_line', [
124 $this, 'renderArchiveSubject',
125 ], 2, 3);
126
127 // initialize subscription pages data
128 $this->subscriptionPages->init();
129 // initialize subscription management shortcodes
130 $this->subscriptionPages->initShortcodes();
131 }
132
133 public function getNewsletterEmbed($params = []): string {
134 if (!is_array($params)) {
135 $params = [];
136 }
137
138 return $this->newsletterEmbedService->render([
139 'newsletterId' => $params['id'] ?? null,
140 'height' => $params['height'] ?? null,
141 'width' => $params['width'] ?? null,
142 'showFallbackLink' => $params['show_fallback_link'] ?? true,
143 'fallbackLinkAlignment' => $params['fallback_link_alignment'] ?? 'center',
144 'iframeAlignment' => $params['iframe_alignment'] ?? 'center',
145 'showEmailBackground' => $params['show_email_background'] ?? true,
146 ]);
147 }
148
149 public function formWidget($params = []) {
150 // IMPORTANT: fixes conflict with MagicMember
151 $this->wp->removeShortcode('user_list');
152
153 if (isset($params['id']) && (int)$params['id'] > 0) {
154 $formWidget = new Widget();
155 return $formWidget->widget([
156 'form' => (int)$params['id'],
157 'form_type' => 'shortcode',
158 ]);
159 }
160 }
161
162 public function getSubscribersCount($params) {
163 if (!empty($params['segments'])) {
164 $segmentIds = array_map(function($segmentId) {
165 return (int)trim($segmentId);
166 }, explode(',', $params['segments']));
167 }
168
169 if (empty($segmentIds)) {
170 return $this->wp->numberFormatI18n(
171 $this->subscribersRepository->countBy(['status' => SubscriberEntity::STATUS_SUBSCRIBED, 'deletedAt' => null])
172 );
173 } else {
174 return $this->wp->numberFormatI18n(
175 $this->segmentSubscribersRepository->getSubscribersCountBySegmentIds($segmentIds, SubscriberEntity::STATUS_SUBSCRIBED)
176 );
177 }
178 }
179
180 public function getArchive($params = '') {
181 $html = '';
182
183 $parsedParams = $this->getParsedArchiveParams($params);
184 $newsletters = $this->newslettersRepository->getArchives($parsedParams);
185
186 $subscriber = $this->subscribersRepository->getCurrentWPUser();
187
188 if (empty($newsletters)) {
189 return $this->wp->applyFilters(
190 'mailpoet_archive_no_newsletters',
191 __('Oops! There are no newsletters to display.', 'mailpoet')
192 );
193 } else {
194 $title = $this->wp->applyFilters('mailpoet_archive_title', '');
195 if (!empty($title) && is_scalar($title)) {
196 $html .= '<h3 class="mailpoet_archive_title">' . (string)$title . '</h3>';
197 }
198 $html .= '<ul class="mailpoet_archive">';
199 foreach ($newsletters as $newsletter) {
200 $queue = $newsletter->getLatestQueue();
201 $processedDate = $this->wp->applyFilters('mailpoet_archive_email_processed_date', $newsletter);
202 $subjectLine = $this->wp->applyFilters('mailpoet_archive_email_subject_line', $newsletter, $subscriber, $queue);
203
204 $html .= '<li>' .
205 '<span class="mailpoet_archive_date">' .
206 (is_scalar($processedDate) ? (string)$processedDate : '') .
207 '</span>
208 <span class="mailpoet_archive_subject">' .
209 (is_scalar($subjectLine) ? (string)$subjectLine : '') .
210 '</span>
211 </li>';
212 }
213 $html .= '</ul>';
214 }
215 return $html;
216 }
217
218 public function getParsedArchiveParams($params): array {
219 $parsedParams = [
220 'startDate' => null,
221 'endDate' => null,
222 'segmentIds' => [],
223 'subjectContains' => '',
224 'limit' => self::DEFAULT_ARCHIVE_LIMIT,
225 ];
226
227 if (!is_array($params)) {
228 return $parsedParams;
229 }
230
231 if (!empty($params['segments']) && is_string($params['segments'])) {
232 $parsedParams['segmentIds'] = array_map(function($segmentId) {
233 return (int)trim($segmentId);
234 }, explode(',', $params['segments']));
235 }
236
237 if (isset($params['start_date']) && is_string($params['start_date']) && $params['start_date'] !== '') {
238 try {
239 $parsedParams['startDate'] = new CarbonImmutable(trim($params['start_date']));
240 } catch (\Throwable $throwable) {
241 // Don't error out if invalid date
242 }
243 }
244
245 if (isset($params['end_date']) && is_string($params['end_date']) && $params['end_date'] !== '') {
246 try {
247 $parsedParams['endDate'] = new CarbonImmutable(trim($params['end_date']));
248 } catch (\Throwable $throwable) {
249 // Don't error out if invalid date
250 }
251 }
252
253 $lastDays = $params['in_the_last_days'] ?? null;
254 if (is_scalar($lastDays) && $lastDays > 0) {
255 $parsedParams['endDate'] = null;
256 $parsedParams['startDate'] = CarbonImmutable::now()->subDays(intval($lastDays))->startOfDay();
257 }
258
259 if (isset($params['subject_contains']) && is_string($params['subject_contains']) && $params['subject_contains'] !== '') {
260 $parsedParams['subjectContains'] = trim($params['subject_contains']);
261 }
262
263 $limit = $params['limit'] ?? null;
264 if (is_scalar($limit) && intval($limit) > 0) {
265 $parsedParams['limit'] = intval($limit);
266 }
267
268 return $parsedParams;
269 }
270
271 public function renderArchiveDate(NewsletterEntity $newsletter) {
272 $timestamp = null;
273 $processedAt = $newsletter->getProcessedAt();
274
275 if (!is_null($processedAt)) {
276 $timestamp = $processedAt->getTimestamp();
277 }
278
279 return $this->wp->dateI18n(
280 $this->wp->getOption('date_format'),
281 $timestamp
282 );
283 }
284
285 public function renderArchiveSubject(NewsletterEntity $newsletter, ?SubscriberEntity $subscriber, ?SendingQueueEntity $queue) {
286 if (is_null($subscriber)) {
287 $subscriber = new SubscriberEntity();
288 }
289
290 /**
291 * An ugly workaround to make sure state is not shared via NewsletterShortcodes service
292 * This should be replaced with injected service when state is removed from this service
293 * (i.e. after https://mailpoet.atlassian.net/browse/MAILPOET-4087 is done and merged to master)
294 */
295 $shortcodeProcessor = new NewsletterShortcodes(
296 $this->dateCategory,
297 $this->linkCategory,
298 $this->newsletterCategory,
299 $this->subscriberCategory,
300 $this->siteCategory,
301 $this->wp
302 );
303
304 $shortcodeProcessor->setNewsletter($newsletter);
305
306 $shortcodeProcessor->setSubscriber($subscriber);
307 $shortcodeProcessor->setQueue($queue);
308 $subject = (string)$shortcodeProcessor->replace($queue ? $queue->getNewsletterRenderedSubject() : '');
309 if ($newsletter->getType() === NewsletterEntity::TYPE_STANDARD && $this->shareVisibility->canShare($newsletter)) {
310 $previewUrl = $this->newsletterUrl->getPublicShareUrl($newsletter);
311 $linkTitle = __('Read in a new tab', 'mailpoet');
312 } else {
313 $previewUrl = $this->newsletterUrl->getViewInBrowserUrl($newsletter, $subscriber, $queue);
314 $linkTitle = __('Preview in a new tab', 'mailpoet');
315 }
316
317 return '<a href="' . $this->wp->escUrl($previewUrl) . '" target="_blank" rel="noopener noreferrer" title="'
318 . $this->wp->escAttr($linkTitle) . '">'
319 . $this->wp->escHtml($subject) .
320 '</a>';
321 }
322 }
323