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 / Automation / Integrations / MailPoet / Templates / TemplatesFactory.php
mailpoet / lib / Automation / Integrations / MailPoet / Templates Last commit date
EmailFactory.php 2 months ago TemplateEmailPreviewRenderer.php 1 month ago TemplatesFactory.php 1 month ago index.php 3 years ago
TemplatesFactory.php
952 lines
1 <?php declare(strict_types = 1);
2
3 namespace MailPoet\Automation\Integrations\MailPoet\Templates;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\Automation\Engine\Data\Automation;
9 use MailPoet\Automation\Engine\Data\AutomationTemplate;
10 use MailPoet\Automation\Engine\Templates\AutomationBuilder;
11 use MailPoet\Automation\Integrations\WooCommerce\WooCommerce;
12 use MailPoet\Config\Env;
13 use MailPoet\WooCommerce\Helper as WooCommerceHelper;
14 use MailPoet\WooCommerce\WooCommerceBookings\Helper as WooCommerceBookingsHelper;
15 use MailPoet\WooCommerce\WooCommerceSubscriptions\Helper as WooCommerceSubscriptions;
16
17 class TemplatesFactory {
18 private const MIN_WOOCOMMERCE_VERSION_FOR_GENERATED_COUPON_BLOCK = '10.8.0';
19
20 /** @var AutomationBuilder */
21 private $builder;
22
23 /** @var WooCommerce */
24 private $woocommerce;
25
26 /** @var WooCommerceSubscriptions */
27 private $woocommerceSubscriptions;
28
29 /** @var EmailFactory */
30 private $emailFactory;
31
32 /** @var WooCommerceBookingsHelper */
33 private $woocommerceBookingsHelper;
34
35 /** @var WooCommerceHelper */
36 private $woocommerceHelper;
37
38 public function __construct(
39 AutomationBuilder $builder,
40 WooCommerce $woocommerce,
41 WooCommerceSubscriptions $woocommerceSubscriptions,
42 EmailFactory $emailFactory,
43 WooCommerceBookingsHelper $woocommerceBookingsHelper,
44 WooCommerceHelper $woocommerceHelper
45 ) {
46 $this->builder = $builder;
47 $this->woocommerce = $woocommerce;
48 $this->woocommerceSubscriptions = $woocommerceSubscriptions;
49 $this->emailFactory = $emailFactory;
50 $this->woocommerceBookingsHelper = $woocommerceBookingsHelper;
51 $this->woocommerceHelper = $woocommerceHelper;
52 }
53
54 public function createTemplates(): array {
55 $templates = [
56 $this->createSubscriberWelcomeEmailTemplate(),
57 $this->createUserWelcomeEmailTemplate(),
58 $this->createSubscriberWelcomeSeriesTemplate(),
59 $this->createUserWelcomeSeriesTemplate(),
60 ];
61
62 if ($this->woocommerce->isWooCommerceActive()) {
63 $templates[] = $this->createFirstPurchaseTemplate();
64 $templates[] = $this->createThankLoyalCustomersTemplate();
65 $templates[] = $this->createAbandonedCartTemplate();
66 $templates[] = $this->createAbandonedCartCampaignTemplate();
67 $templates[] = $this->createPurchasedProductTemplate();
68 $templates[] = $this->createPurchasedProductWithTagTemplate();
69 $templates[] = $this->createPurchasedInCategoryTemplate();
70 if ($this->woocommerceHelper->wcSupportsOrderReviewUrl()) {
71 $templates[] = $this->createAskForReviewTemplate();
72 }
73 $templates[] = $this->createFollowUpPositiveReviewTemplate();
74 $templates[] = $this->createFollowUpNegativeReviewTemplate();
75 if ($this->woocommerceSubscriptions->isWooCommerceSubscriptionsActive()) {
76 $templates[] = $this->createFollowUpAfterSubscriptionPurchaseTemplate();
77 $templates[] = $this->createFollowUpAfterSubscriptionRenewalTemplate();
78 $templates[] = $this->createFollowUpAfterFailedRenewalTemplate();
79 $templates[] = $this->createFollowUpOnChurnedSubscriptionTemplate();
80 $templates[] = $this->createFollowUpWhenTrialEndsTemplate();
81 $templates[] = $this->createWinBackChurnedSubscribersTemplate();
82 }
83 if ($this->woocommerceBookingsHelper->isWooCommerceBookingsActive()) {
84 $templates[] = $this->createWcBookingAbandonedSpotTemplate();
85 $templates[] = $this->createWcBookingNewBookingFollowUpTemplate();
86 $templates[] = $this->createWcBookingPreVisitReminderTemplate();
87 $templates[] = $this->createWcBookingPreVisitDripTemplate();
88 $templates[] = $this->createWcBookingPostVisitReviewTemplate();
89 $templates[] = $this->createWcBookingNextBookingNudgeTemplate();
90 }
91 }
92
93 $templates[] = $this->createBirthdayEmailTemplate();
94
95 return $templates;
96 }
97
98 private function createBirthdayEmailTemplate(): AutomationTemplate {
99 $usesDiscountPattern = $this->woocommerce->isWooCommerceActive() && $this->supportsGeneratedCouponBlock();
100
101 return new AutomationTemplate(
102 'birthday-email',
103 'celebrations',
104 __('Birthday email', 'mailpoet'),
105 __('Send a birthday email to your subscribers on their special day.', 'mailpoet'),
106 function (bool $preview = false) use ($usesDiscountPattern): Automation {
107 $emailArgs = $this->createBlockEditorEmailArgs(
108 $preview,
109 $usesDiscountPattern ? 'birthday-email-with-discount' : 'birthday-email-content',
110 $usesDiscountPattern ? __('A birthday treat from us', 'mailpoet') : __('Happy birthday!', 'mailpoet'),
111 $usesDiscountPattern ? __('A birthday treat from us', 'mailpoet') : __('Happy birthday!', 'mailpoet'),
112 $usesDiscountPattern ? __('Enjoy 10% off your next order', 'mailpoet') : __('Wishing you a wonderful day', 'mailpoet'),
113 'birthday-email'
114 );
115
116 return $this->builder->createFromSequence(
117 __('Birthday email', 'mailpoet'),
118 [
119 ['key' => 'mailpoet:annual-date'],
120 ['key' => 'mailpoet:send-email', 'args' => $emailArgs],
121 ]
122 );
123 },
124 [
125 'automationSteps' => 1,
126 ],
127 AutomationTemplate::TYPE_PREMIUM,
128 'heart'
129 );
130 }
131
132 private function createSubscriberWelcomeEmailTemplate(): AutomationTemplate {
133 return new AutomationTemplate(
134 'subscriber-welcome-email',
135 'welcome',
136 __('Welcome new subscribers', 'mailpoet'),
137 __(
138 'Send a welcome email when someone subscribes to your list. Optionally, you can choose to send this email after a specified period.',
139 'mailpoet'
140 ),
141 function (bool $preview = false): Automation {
142 $emailArgs = $this->createBlockEditorEmailArgs(
143 $preview,
144 'welcome-email-content',
145 __('Welcome email', 'mailpoet'),
146 __('Welcome to our community!', 'mailpoet'),
147 __('Thanks for subscribing', 'mailpoet'),
148 'subscriber-welcome-email'
149 );
150
151 return $this->builder->createFromSequence(
152 __('Welcome new subscribers', 'mailpoet'),
153 [
154 ['key' => 'mailpoet:someone-subscribes'],
155 ['key' => 'core:delay', 'args' => ['delay' => 1, 'delay_type' => 'MINUTES']],
156 ['key' => 'mailpoet:send-email', 'args' => $emailArgs],
157 ],
158 [
159 'mailpoet:run-once-per-subscriber' => true,
160 ]
161 );
162 },
163 [
164 'automationSteps' => 1, // trigger and all delay steps are excluded
165 ],
166 AutomationTemplate::TYPE_DEFAULT,
167 'megaphone',
168 'wordpress',
169 true
170 );
171 }
172
173 private function createUserWelcomeEmailTemplate(): AutomationTemplate {
174 return new AutomationTemplate(
175 'user-welcome-email',
176 'welcome',
177 __('Welcome new WordPress users', 'mailpoet'),
178 __(
179 'Send a welcome email when a new WordPress user registers to your website. Optionally, you can choose to send this email after a specified period.',
180 'mailpoet'
181 ),
182 function (bool $preview = false): Automation {
183 $emailArgs = $this->createBlockEditorEmailArgs(
184 $preview,
185 'welcome-email-content',
186 __('Welcome email', 'mailpoet'),
187 __('Welcome to our community!', 'mailpoet'),
188 __('Thanks for joining us', 'mailpoet'),
189 'user-welcome-email'
190 );
191
192 return $this->builder->createFromSequence(
193 __('Welcome new WordPress users', 'mailpoet'),
194 [
195 ['key' => 'mailpoet:wp-user-registered'],
196 ['key' => 'core:delay', 'args' => ['delay' => 1, 'delay_type' => 'MINUTES']],
197 ['key' => 'mailpoet:send-email', 'args' => $emailArgs],
198 ],
199 [
200 'mailpoet:run-once-per-subscriber' => true,
201 ]
202 );
203 },
204 [
205 'automationSteps' => 1, // trigger and all delay steps are excluded
206 ],
207 AutomationTemplate::TYPE_DEFAULT,
208 'megaphone'
209 );
210 }
211
212 private function createSubscriberWelcomeSeriesTemplate(): AutomationTemplate {
213 return new AutomationTemplate(
214 'subscriber-welcome-series',
215 'welcome',
216 __('Welcome series for new subscribers', 'mailpoet'),
217 __(
218 'Welcome new subscribers and start building a relationship with them. Send an email immediately after someone subscribes to your list to introduce your brand and a follow-up two days later to keep the conversation going.',
219 'mailpoet'
220 ),
221 function (): Automation {
222 return $this->builder->createFromSequence(
223 __('Welcome series for new subscribers', 'mailpoet'),
224 []
225 );
226 },
227 [
228 'automationSteps' => 2, // trigger and all delay steps are excluded
229 ],
230 AutomationTemplate::TYPE_PREMIUM,
231 'megaphone'
232 );
233 }
234
235 private function createUserWelcomeSeriesTemplate(): AutomationTemplate {
236 return new AutomationTemplate(
237 'user-welcome-series',
238 'welcome',
239 __('Welcome series for new WordPress users', 'mailpoet'),
240 __(
241 'Welcome new WordPress users to your site. Send an email immediately after a WordPress user registers. Send a follow-up email two days later with more in-depth information.',
242 'mailpoet'
243 ),
244 function (): Automation {
245 return $this->builder->createFromSequence(
246 __('Welcome series for new WordPress users', 'mailpoet'),
247 []
248 );
249 },
250 [
251 'automationSteps' => 2, // trigger and all delay steps are excluded
252 ],
253 AutomationTemplate::TYPE_PREMIUM,
254 'megaphone'
255 );
256 }
257
258 private function createFirstPurchaseTemplate(): AutomationTemplate {
259 return new AutomationTemplate(
260 'first-purchase',
261 'purchase',
262 __('Celebrate first-time buyers', 'mailpoet'),
263 __(
264 'Welcome your first-time customers by sending an email with a special offer for their next purchase. Make them feel appreciated within your brand.',
265 'mailpoet'
266 ),
267 function (bool $preview = false): Automation {
268 $emailArgs = $this->createBlockEditorEmailArgs(
269 $preview,
270 'first-purchase-thank-you',
271 __('First purchase thank you', 'mailpoet'),
272 __('Thank you for your first order!', 'mailpoet'),
273 __('Welcome to the family! Check out what’s next for you.', 'mailpoet'),
274 'first-purchase'
275 );
276
277 return $this->builder->createFromSequence(
278 __('Celebrate first-time buyers', 'mailpoet'),
279 [
280 [
281 'key' => 'woocommerce:order-completed',
282 'filters' => [
283 'operator' => 'and',
284 'groups' => [
285 [
286 'operator' => 'and',
287 'filters' => [
288 ['field' => 'woocommerce:order:is-first-order', 'condition' => 'is', 'value' => true],
289 ],
290 ],
291 ],
292 ],
293 ],
294 [
295 'key' => 'mailpoet:send-email',
296 'args' => $emailArgs,
297 ],
298 ],
299 [
300 'mailpoet:run-once-per-subscriber' => true,
301 ]
302 );
303 },
304 [
305 'automationSteps' => 1, // trigger and all delay steps are excluded
306 ],
307 AutomationTemplate::TYPE_DEFAULT,
308 'people',
309 'wordpress',
310 true
311 );
312 }
313
314 private function createThankLoyalCustomersTemplate(): AutomationTemplate {
315 return new AutomationTemplate(
316 'thank-loyal-customers',
317 'purchase',
318 __('Thank loyal customers', 'mailpoet'),
319 __(
320 'These are your most important customers. Make them feel special by sending a thank you note for supporting your brand.',
321 'mailpoet'
322 ),
323 function (bool $preview = false): Automation {
324 $emailArgs = $this->createBlockEditorEmailArgs(
325 $preview,
326 'post-purchase-thank-you',
327 __('Thank you for your loyalty', 'mailpoet'),
328 __('Thank you for your loyalty', 'mailpoet'),
329 __('We appreciate your continued support', 'mailpoet'),
330 'thank-loyal-customers'
331 );
332
333 return $this->builder->createFromSequence(
334 __('Thank loyal customers', 'mailpoet'),
335 [
336 [
337 'key' => 'woocommerce:order-completed',
338 'filters' => [
339 'operator' => 'and',
340 'groups' => [
341 [
342 'operator' => 'and',
343 'filters' => [
344 [
345 'field' => 'woocommerce:customer:order-count',
346 'condition' => 'greater-than',
347 'value' => 5,
348 'params' => ['in_the_last' => ['number' => 365, 'unit' => 'days']],
349 ],
350 ],
351 ],
352 ],
353 ],
354 ],
355 ['key' => 'core:delay', 'args' => ['delay' => 1, 'delay_type' => 'DAYS']],
356 [
357 'key' => 'mailpoet:send-email',
358 'args' => $emailArgs,
359 ],
360 ]
361 );
362 },
363 [
364 'automationSteps' => 1, // trigger and all delay steps are excluded
365 ],
366 AutomationTemplate::TYPE_PREMIUM,
367 'people'
368 );
369 }
370
371 private function createAbandonedCartTemplate(): AutomationTemplate {
372 return new AutomationTemplate(
373 'abandoned-cart',
374 'abandoned-cart',
375 __('Abandoned cart reminder', 'mailpoet'),
376 __(
377 'Nudge your shoppers to complete the purchase after they have added a product to the cart but haven’t completed the order.',
378 'mailpoet'
379 ),
380 function (bool $preview = false): Automation {
381 $emailArgs = $this->createBlockEditorEmailArgs(
382 $preview,
383 'abandoned-cart-content',
384 __('Abandoned cart reminder', 'mailpoet'),
385 __('You left something behind!', 'mailpoet'),
386 __('Complete your purchase today', 'mailpoet'),
387 'abandoned-cart'
388 );
389
390 return $this->builder->createFromSequence(
391 __('Abandoned cart reminder', 'mailpoet'),
392 [
393 ['key' => 'woocommerce:abandoned-cart'],
394 [
395 'key' => 'mailpoet:send-email',
396 'args' => $emailArgs,
397 ],
398 ]
399 );
400 },
401 [
402 'automationSteps' => 1, // trigger and all delay steps are excluded
403 ],
404 AutomationTemplate::TYPE_DEFAULT,
405 Env::$assetsUrl . '/img/icons/cart.svg',
406 'svg',
407 true
408 );
409 }
410
411 private function createAbandonedCartCampaignTemplate(): AutomationTemplate {
412 return new AutomationTemplate(
413 'abandoned-cart-campaign',
414 'abandoned-cart',
415 __('Abandoned cart campaign', 'mailpoet'),
416 __(
417 'Encourage your potential customers to finalize their purchase when they have added items to their cart but haven’t finished the order yet. Offer a coupon code as a last resort to convert them to customers.',
418 'mailpoet'
419 ),
420 function (): Automation {
421 return $this->builder->createFromSequence(
422 __('Abandoned cart campaign', 'mailpoet'),
423 []
424 );
425 },
426 [
427 'automationSteps' => 5, // trigger and all delay steps are excluded
428 ],
429 AutomationTemplate::TYPE_PREMIUM,
430 Env::$assetsUrl . '/img/icons/cart.svg',
431 'svg'
432 );
433 }
434
435 private function createPurchasedProductTemplate(): AutomationTemplate {
436 return new AutomationTemplate(
437 'purchased-product',
438 'purchase',
439 __('Purchased a product', 'mailpoet'),
440 __(
441 'Share care instructions or simply thank the customer for making an order.',
442 'mailpoet'
443 ),
444 function (bool $preview = false): Automation {
445 $emailArgs = $this->createBlockEditorEmailArgs(
446 $preview,
447 'product-purchase-follow-up',
448 __('Important information about your order', 'mailpoet'),
449 __('Important information about your order', 'mailpoet'),
450 __('A few details about your purchase', 'mailpoet'),
451 'purchased-product'
452 );
453
454 return $this->builder->createFromSequence(
455 __('Purchased a product', 'mailpoet'),
456 [
457 [
458 'key' => 'woocommerce:buys-a-product',
459 ],
460 [
461 'key' => 'mailpoet:send-email',
462 'args' => $emailArgs,
463 ],
464 ]
465 );
466 },
467 [
468 'automationSteps' => 1, // trigger and all delay steps are excluded
469 ],
470 AutomationTemplate::TYPE_DEFAULT,
471 'store'
472 );
473 }
474
475 private function createPurchasedProductWithTagTemplate(): AutomationTemplate {
476 return new AutomationTemplate(
477 'purchased-product-with-tag',
478 'purchase',
479 __('Purchased a product with a tag', 'mailpoet'),
480 __(
481 'Share care instructions or simply thank the customer for making an order.',
482 'mailpoet'
483 ),
484 function (bool $preview = false): Automation {
485 $emailArgs = $this->createBlockEditorEmailArgs(
486 $preview,
487 'tag-purchase-follow-up',
488 __('Important information about your order', 'mailpoet'),
489 __('Important information about your order', 'mailpoet'),
490 __('A few details about your purchase', 'mailpoet'),
491 'purchased-product-with-tag'
492 );
493
494 return $this->builder->createFromSequence(
495 __('Purchased a product with a tag', 'mailpoet'),
496 [
497 [
498 'key' => 'woocommerce:buys-from-a-tag',
499 ],
500 [
501 'key' => 'mailpoet:send-email',
502 'args' => $emailArgs,
503 ],
504 ]
505 );
506 },
507 [
508 'automationSteps' => 1, // trigger and all delay steps are excluded
509 ],
510 AutomationTemplate::TYPE_DEFAULT,
511 'store'
512 );
513 }
514
515 private function createPurchasedInCategoryTemplate(): AutomationTemplate {
516 return new AutomationTemplate(
517 'purchased-in-category',
518 'purchase',
519 __('Purchased in a category', 'mailpoet'),
520 __(
521 'Share care instructions or simply thank the customer for making an order.',
522 'mailpoet'
523 ),
524 function (bool $preview = false): Automation {
525 $emailArgs = $this->createBlockEditorEmailArgs(
526 $preview,
527 'category-purchase-follow-up',
528 __('Important information about your order', 'mailpoet'),
529 __('Important information about your order', 'mailpoet'),
530 __('A few details about your purchase', 'mailpoet'),
531 'purchased-in-category'
532 );
533
534 return $this->builder->createFromSequence(
535 __('Purchased in a category', 'mailpoet'),
536 [
537 [
538 'key' => 'woocommerce:buys-from-a-category',
539 ],
540 [
541 'key' => 'mailpoet:send-email',
542 'args' => $emailArgs,
543 ],
544 ]
545 );
546 },
547 [
548 'automationSteps' => 1, // trigger and all delay steps are excluded
549 ],
550 AutomationTemplate::TYPE_DEFAULT,
551 'store'
552 );
553 }
554
555 private function createAskForReviewTemplate(): AutomationTemplate {
556 return new AutomationTemplate(
557 'ask-for-review',
558 'review',
559 __('Ask to leave a review post-purchase', 'mailpoet'),
560 __(
561 'Encourage your customers to leave a review a few days after their purchase. Show them their opinion matters.',
562 'mailpoet'
563 ),
564 function (): Automation {
565 return $this->builder->createFromSequence(
566 __('Ask to leave a review post-purchase', 'mailpoet'),
567 []
568 );
569 },
570 [
571 'automationSteps' => 2, // trigger and all delay steps are excluded
572 ],
573 AutomationTemplate::TYPE_PREMIUM,
574 'starFilled'
575 );
576 }
577
578 private function createFollowUpPositiveReviewTemplate(): AutomationTemplate {
579 return new AutomationTemplate(
580 'follow-up-positive-review',
581 'review',
582 __('Follow up on a positive review (4-5 stars)', 'mailpoet'),
583 __(
584 'Thank your happy customers for their feedback and let them know you appreciate their support.',
585 'mailpoet'
586 ),
587 function (): Automation {
588 return $this->builder->createFromSequence(
589 __('Follow up on a positive review (4-5 stars)', 'mailpoet'),
590 []
591 );
592 },
593 [
594 'automationSteps' => 1, // trigger and all delay steps are excluded
595 ],
596 AutomationTemplate::TYPE_PREMIUM,
597 'starFilled'
598 );
599 }
600
601 private function createFollowUpNegativeReviewTemplate(): AutomationTemplate {
602 return new AutomationTemplate(
603 'follow-up-negative-review',
604 'review',
605 __('Follow up on a negative review (1-2 stars)', 'mailpoet'),
606 __(
607 'Reach out to unhappy customers and show you care. Offer help or gather more feedback to improve.',
608 'mailpoet'
609 ),
610 function (): Automation {
611 return $this->builder->createFromSequence(
612 __('Follow up on a negative review (1-2 stars)', 'mailpoet'),
613 []
614 );
615 },
616 [
617 'automationSteps' => 1, // trigger and all delay steps are excluded
618 ],
619 AutomationTemplate::TYPE_PREMIUM,
620 'starFilled'
621 );
622 }
623
624 private function createFollowUpAfterSubscriptionPurchaseTemplate(): AutomationTemplate {
625 return new AutomationTemplate(
626 'follow-up-after-subscription-purchase',
627 'subscriptions',
628 __('Follow up after a subscription purchase', 'mailpoet'),
629 __(
630 'Thank new subscribers and let them know what to expect. A warm welcome goes a long way.',
631 'mailpoet'
632 ),
633 function (): Automation {
634 return $this->builder->createFromSequence(
635 __('Follow up after a subscription purchase', 'mailpoet'),
636 []
637 );
638 },
639 [
640 'automationSteps' => 1, // trigger and all delay steps are excluded
641 ],
642 AutomationTemplate::TYPE_PREMIUM,
643 'payment'
644 );
645 }
646
647 private function createFollowUpAfterSubscriptionRenewalTemplate(): AutomationTemplate {
648 return new AutomationTemplate(
649 'follow-up-after-subscription-renewal',
650 'subscriptions',
651 __('Follow up after a subscription renewal', 'mailpoet'),
652 __(
653 'Reinforce the value of your subscription by reminding customers what they’re getting after every renewal.',
654 'mailpoet'
655 ),
656 function (): Automation {
657 return $this->builder->createFromSequence(
658 __('Follow up after a subscription renewal', 'mailpoet'),
659 []
660 );
661 },
662 [
663 'automationSteps' => 1, // trigger and all delay steps are excluded
664 ],
665 AutomationTemplate::TYPE_PREMIUM,
666 'payment'
667 );
668 }
669
670 private function createFollowUpAfterFailedRenewalTemplate(): AutomationTemplate {
671 return new AutomationTemplate(
672 'follow-up-after-failed-renewal',
673 'subscriptions',
674 __('Follow up after failed renewal', 'mailpoet'),
675 __(
676 'Help customers fix failed payments and continue their subscription without disruption.',
677 'mailpoet'
678 ),
679 function (): Automation {
680 return $this->builder->createFromSequence(
681 __('Follow up after failed renewal', 'mailpoet'),
682 []
683 );
684 },
685 [
686 'automationSteps' => 1, // trigger and all delay steps are excluded
687 ],
688 AutomationTemplate::TYPE_PREMIUM,
689 'payment'
690 );
691 }
692
693 private function createFollowUpOnChurnedSubscriptionTemplate(): AutomationTemplate {
694 return new AutomationTemplate(
695 'follow-up-on-churned-subscription',
696 'subscriptions',
697 __('Follow up on churned subscription', 'mailpoet'),
698 __(
699 'Reach out to subscribers who canceled and ask for their feedback to help improve your service.',
700 'mailpoet'
701 ),
702 function (): Automation {
703 return $this->builder->createFromSequence(
704 __('Follow up on churned subscription', 'mailpoet'),
705 []
706 );
707 },
708 [
709 'automationSteps' => 1, // trigger and all delay steps are excluded
710 ],
711 AutomationTemplate::TYPE_PREMIUM,
712 'payment'
713 );
714 }
715
716 private function createFollowUpWhenTrialEndsTemplate(): AutomationTemplate {
717 return new AutomationTemplate(
718 'follow-up-when-trial-ends',
719 'subscriptions',
720 __('Follow up when trial ends', 'mailpoet'),
721 __(
722 'Check in with customers after their trial ends. Encourage them to keep enjoying the benefits of their subscription.',
723 'mailpoet'
724 ),
725 function (): Automation {
726 return $this->builder->createFromSequence(
727 __('Follow up when trial ends', 'mailpoet'),
728 []
729 );
730 },
731 [
732 'automationSteps' => 1, // trigger and all delay steps are excluded
733 ],
734 AutomationTemplate::TYPE_PREMIUM,
735 'payment'
736 );
737 }
738
739 private function createWinBackChurnedSubscribersTemplate(): AutomationTemplate {
740 return new AutomationTemplate(
741 'win-back-churned-subscribers',
742 'subscriptions',
743 __('Win back churned subscribers', 'mailpoet'),
744 __(
745 'Re-engage former subscribers by showing what’s new and why it’s worth coming back.',
746 'mailpoet'
747 ),
748 function (): Automation {
749 return $this->builder->createFromSequence(
750 __('Win back churned subscribers', 'mailpoet'),
751 []
752 );
753 },
754 [
755 'automationSteps' => 2, // trigger and all delay steps are excluded
756 ],
757 AutomationTemplate::TYPE_PREMIUM,
758 'payment'
759 );
760 }
761
762 private function createWcBookingAbandonedSpotTemplate(): AutomationTemplate {
763 return new AutomationTemplate(
764 'wc-booking-abandoned-spot',
765 'bookings',
766 __('Abandoned booking reminder', 'mailpoet'),
767 __(
768 'Remind customers who left a booking in their cart to complete their reservation.',
769 'mailpoet'
770 ),
771 function (): Automation {
772 return $this->builder->createFromSequence(
773 __('Abandoned booking reminder', 'mailpoet'),
774 []
775 );
776 },
777 [
778 'automationSteps' => 1, // trigger and all delay steps are excluded
779 ],
780 AutomationTemplate::TYPE_PREMIUM,
781 'calendar'
782 );
783 }
784
785 private function createWcBookingNewBookingFollowUpTemplate(): AutomationTemplate {
786 return new AutomationTemplate(
787 'wc-booking-new-booking-follow-up',
788 'bookings',
789 __('Follow-up after a new booking', 'mailpoet'),
790 __(
791 'Send a confirmation email after a new booking is created.',
792 'mailpoet'
793 ),
794 function (): Automation {
795 return $this->builder->createFromSequence(
796 __('Follow-up after a new booking', 'mailpoet'),
797 []
798 );
799 },
800 [
801 'automationSteps' => 1, // trigger and all delay steps are excluded
802 ],
803 AutomationTemplate::TYPE_PREMIUM,
804 'calendar'
805 );
806 }
807
808 private function createWcBookingPreVisitReminderTemplate(): AutomationTemplate {
809 return new AutomationTemplate(
810 'wc-booking-pre-visit-reminder',
811 'bookings',
812 __('Pre-visit reminder', 'mailpoet'),
813 __(
814 'Send a reminder before a booking starts. Customize the timing in the trigger settings.',
815 'mailpoet'
816 ),
817 function (): Automation {
818 return $this->builder->createFromSequence(
819 __('Pre-visit reminder', 'mailpoet'),
820 []
821 );
822 },
823 [
824 'automationSteps' => 1, // trigger and all delay steps are excluded
825 ],
826 AutomationTemplate::TYPE_PREMIUM,
827 'calendar'
828 );
829 }
830
831 private function createWcBookingPreVisitDripTemplate(): AutomationTemplate {
832 return new AutomationTemplate(
833 'wc-booking-pre-visit-drip',
834 'bookings',
835 __('Educational drip after booking', 'mailpoet'),
836 __(
837 'Send a series of emails after a booking is created to help customers prepare for their visit.',
838 'mailpoet'
839 ),
840 function (): Automation {
841 return $this->builder->createFromSequence(
842 __('Educational drip after booking', 'mailpoet'),
843 []
844 );
845 },
846 [
847 'automationSteps' => 2, // trigger and all delay steps are excluded
848 ],
849 AutomationTemplate::TYPE_PREMIUM,
850 'calendar'
851 );
852 }
853
854 private function createWcBookingPostVisitReviewTemplate(): AutomationTemplate {
855 return new AutomationTemplate(
856 'wc-booking-post-visit-review',
857 'bookings',
858 __('Post-booking review request', 'mailpoet'),
859 __(
860 'Ask for feedback after a booking is completed.',
861 'mailpoet'
862 ),
863 function (): Automation {
864 return $this->builder->createFromSequence(
865 __('Post-booking review request', 'mailpoet'),
866 []
867 );
868 },
869 [
870 'automationSteps' => 1, // trigger and all delay steps are excluded
871 ],
872 AutomationTemplate::TYPE_PREMIUM,
873 'calendar'
874 );
875 }
876
877 private function createWcBookingNextBookingNudgeTemplate(): AutomationTemplate {
878 return new AutomationTemplate(
879 'wc-booking-next-booking-nudge',
880 'bookings',
881 __('Next booking nudge', 'mailpoet'),
882 __(
883 'Encourage customers to rebook after their booking is completed.',
884 'mailpoet'
885 ),
886 function (): Automation {
887 return $this->builder->createFromSequence(
888 __('Next booking nudge', 'mailpoet'),
889 []
890 );
891 },
892 [
893 'automationSteps' => 1, // trigger and all delay steps are excluded
894 ],
895 AutomationTemplate::TYPE_PREMIUM,
896 'calendar'
897 );
898 }
899
900 private function supportsGeneratedCouponBlock(): bool {
901 $wooCommerceVersion = $this->woocommerceHelper->getWooCommerceVersion();
902 if (!$wooCommerceVersion) {
903 return false;
904 }
905
906 $numericVersionLength = strspn($wooCommerceVersion, '0123456789.');
907 $numericVersion = substr($wooCommerceVersion, 0, $numericVersionLength);
908 if ($numericVersion === '') {
909 return false;
910 }
911
912 return version_compare($numericVersion, self::MIN_WOOCOMMERCE_VERSION_FOR_GENERATED_COUPON_BLOCK, '>=');
913 }
914
915 /**
916 * @return array<string, mixed>
917 */
918 private function createBlockEditorEmailArgs(
919 bool $preview,
920 string $pattern,
921 string $name,
922 string $subject,
923 string $preheader,
924 string $templateSlug
925 ): array {
926 $args = [
927 'name' => $name,
928 'subject' => $subject,
929 'preheader' => $preheader,
930 ];
931
932 if ($preview) {
933 $args['pattern'] = $pattern;
934 return $args;
935 }
936
937 $emailIds = $this->emailFactory->createBlockEditorEmail([
938 'pattern' => $pattern,
939 'subject' => $subject,
940 'preheader' => $preheader,
941 ]);
942 if (
943 !is_array($emailIds)
944 || !is_int($emailIds['email_id'] ?? null)
945 || !is_int($emailIds['email_wp_post_id'] ?? null)
946 ) {
947 throw new \RuntimeException(sprintf('Could not create the %s block editor email.', $templateSlug));
948 }
949 return array_merge($args, $emailIds);
950 }
951 }
952