| @@ -635,10 +635,123 @@ | ||
| 635 | 635 | 'is_default_body' => 'yes', |
| 636 | 636 | 'email_body' => '', |
| 637 | 637 | ] |
| 638 | 638 | ], |
| 639 | + 'review_submitted_admin' => [ | |
| 640 | + 'event' => 'review_created', | |
| 641 | + 'group' => 'review', | |
| 642 | + 'group_label' => __('Review Actions', 'fluent-cart'), | |
| 643 | + 'title' => __('Send mail to admin when a new review is submitted', 'fluent-cart'), | |
| 644 | + 'description' => __('Email admin when a customer submits a new review.', 'fluent-cart'), | |
| 645 | + 'recipient' => 'admin', | |
| 646 | + 'smartcode_groups' => [], | |
| 647 | + 'template_path' => 'review.submitted.admin', | |
| 648 | + 'is_async' => false, | |
| 649 | + 'pre_header' => __('A new product review has been submitted.', 'fluent-cart'), | |
| 650 | + 'settings' => [ | |
| 651 | + 'active' => 'yes', | |
| 652 | + 'subject' => __('New Review Submitted', 'fluent-cart'), | |
| 653 | + 'is_default_body' => 'yes', | |
| 654 | + 'email_body' => '', | |
| 655 | + ] | |
| 656 | + ], | |
| 657 | + 'review_approved_customer' => [ | |
| 658 | + // The settled hook, not the transition: fired from a queued | |
| 659 | + // job once the review has been re-read and is still approved, | |
| 660 | + // the way order_paid_done is to order_paid. A bulk approve is | |
| 661 | + // fifty of these, and none of them is sent inside that request. | |
| 662 | + 'event' => 'review_approved_done', | |
| 663 | + 'group' => 'review', | |
| 664 | + 'group_label' => __('Review Actions', 'fluent-cart'), | |
| 665 | + 'title' => __('Send mail to the reviewer when their review is approved', 'fluent-cart'), | |
| 666 | + 'description' => __('Email the customer who wrote a review once it is approved and visible on the product page.', 'fluent-cart'), | |
| 667 | + 'recipient' => 'customer', | |
| 668 | + // Declared, because the customer recipient resolves through an | |
| 669 | + // order and a review has none. The resolver behind this code is | |
| 670 | + // the one every review notification uses. | |
| 671 | + 'to' => '{{review.recipient_email}}', | |
| 672 | + 'smartcode_groups' => [], | |
| 673 | + 'template_path' => 'review.approved.customer', | |
| 674 | + 'is_async' => false, | |
| 675 | + 'pre_header' => __('Your review is now live.', 'fluent-cart'), | |
| 676 | + 'settings' => [ | |
| 677 | + 'active' => 'yes', | |
| 678 | + 'subject' => __('Your review of {{review.product_title}} is now live', 'fluent-cart'), | |
| 679 | + 'is_default_body' => 'yes', | |
| 680 | + 'email_body' => '', | |
| 681 | + ] | |
| 682 | + ], | |
| 683 | + 'review_replied_customer' => [ | |
| 684 | + // Fired from a queued job once the reply and the review it | |
| 685 | + // answers have both been re-read and are still published. | |
| 686 | + 'event' => 'review_replied_done', | |
| 687 | + 'group' => 'review', | |
| 688 | + 'group_label' => __('Review Actions', 'fluent-cart'), | |
| 689 | + 'title' => __('Send mail to the reviewer when the store replies to their review', 'fluent-cart'), | |
| 690 | + 'description' => __('Email the customer who wrote a review when the store posts a reply to it.', 'fluent-cart'), | |
| 691 | + 'recipient' => 'customer', | |
| 692 | + // The review's author, resolved the way every review | |
| 693 | + // notification resolves it — {{review.*}} is the review being | |
| 694 | + // answered, not the reply. | |
| 695 | + 'to' => '{{review.recipient_email}}', | |
| 696 | + 'smartcode_groups' => [], | |
| 697 | + 'template_path' => 'review.replied.customer', | |
| 698 | + 'is_async' => false, | |
| 699 | + 'pre_header' => __('The store has replied to your review.', 'fluent-cart'), | |
| 700 | + 'settings' => [ | |
| 701 | + 'active' => 'yes', | |
| 702 | + 'subject' => __('{{settings.store_name}} replied to your review of {{review.product_title}}', 'fluent-cart'), | |
| 703 | + 'is_default_body' => 'yes', | |
| 704 | + 'email_body' => '', | |
| 705 | + ] | |
| 706 | + ], | |
| 639 | 707 | ]; |
| 640 | 708 | |
| 709 | + } | |
| 710 | + | |
| 711 | + /** | |
| 712 | + * The names of the notifications that would send for an event — the same | |
| 713 | + * gate getNotificationsOfEvent() applies, without rendering a body. | |
| 714 | + * | |
| 715 | + * For a caller that only needs to know whether, and which, before it | |
| 716 | + * commits to something — a once-only lease, say — and will render at | |
| 717 | + * send time through mailByEmailName(). Rendering here as well would draw | |
| 718 | + * every template twice per send. | |
| 719 | + * | |
| 720 | + * Kept in step with getNotificationsOfEvent(): the four conditions below | |
| 721 | + * are that method's, in the same order. | |
| 722 | + * | |
| 723 | + * @param string $event | |
| 724 | + * @return string[] notification names, in registry order | |
| 725 | + */ | |
| 726 | + public static function activeNotificationNamesOfEvent($event): array | |
| 727 | + { | |
| 728 | + $mailingSettings = static::getSettings(); | |
| 729 | + $names = []; | |
| 730 | + | |
| 731 | + foreach (static::getNotifications() as $key => $notification) { | |
| 732 | + if (Arr::get($notification, 'event') !== $event) { | |
| 733 | + continue; | |
| 734 | + } | |
| 735 | + | |
| 736 | + $settings = Arr::get($notification, 'settings'); | |
| 737 | + if (!in_array($notification['event'], ['order_placed_offline', 'renewal_reminder_overdue']) && Arr::get($settings, 'active') !== 'yes') { | |
| 738 | + continue; | |
| 739 | + } | |
| 740 | + | |
| 741 | + $recipient = Arr::get($notification, 'recipient'); | |
| 742 | + if (!Arr::get($notification, 'to') && !in_array($recipient, ['admin', 'customer', 'user', 'subscriber'])) { | |
| 743 | + continue; | |
| 744 | + } | |
| 745 | + | |
| 746 | + if (empty(static::resolveRecipientTemplate($notification, $mailingSettings))) { | |
| 747 | + continue; | |
| 748 | + } | |
| 749 | + | |
| 750 | + $names[] = (string) $key; | |
| 751 | + } | |
| 752 | + | |
| 753 | + return $names; | |
| 641 | 754 | } |
| 642 | 755 | |
| 643 | 756 | public static function getNotificationsOfEvent($event, $viewData): array |
| 644 | 757 | { |