PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.7.0
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.7.0
1.7.0 1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 All 50 releases
fluent-cart / app / Events / ReviewReplied.php

ReviewReplied.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.7.0, at app/Events/ReviewReplied.php

117 lines 3.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App\Events;
4
5 use FluentCart\App\Models\ProductReview;
6
7 /**
8 * The store replied to a review — fluent_cart/review_replied.
9 *
10 * Fired once per store reply, from the two places that write one: a moderator
11 * answering a single review, and a bulk reply. Only after the reply's
12 * transaction has committed — a listener that sends mail inside a transaction
13 * that later rolls back announces a reply that does not exist. Never for a
14 * customer's own follow-up: that is not the store speaking.
15 *
16 * As with approval, this is the event as it happened. The job it queues
17 * re-reads the reply and its review and fires fluent_cart/review_replied_done
18 * only if both are still published — the hook the reviewer's email, and any
19 * integration, should hang on.
20 */
21 class ReviewReplied extends EventDispatcher
22 {
23 public string $hook = 'fluent_cart/review_replied';
24
25 protected array $listeners = [];
26
27 public ProductReview $reply;
28
29 /** @var ProductReview|null the review being answered, when the caller already holds it */
30 protected ?ProductReview $review;
31
32 /** @var mixed the product, when the caller already holds it */
33 protected $product;
34
35 /**
36 * @param ProductReview $reply the store's reply
37 * @param ProductReview|null $review the review it answers, if already loaded
38 * @param mixed $product the product, if already loaded
39 */
40 public function __construct(ProductReview $reply, ?ProductReview $review = null, $product = null)
41 {
42 $this->reply = $reply;
43 $this->review = $review;
44 $this->product = $product;
45 }
46
47 /**
48 * Dispatch for a row that has just been written, if it is a store reply.
49 * Every dispatch site asks the same question, so it is asked here.
50 *
51 * The writers of a reply hold its review and product already — the
52 * single reply loaded the parent to answer it, the bulk reply loaded
53 * every parent it was given. Passed in, so a batch of fifty does not
54 * make a hundred queries to look up what the caller just had.
55 *
56 * @param ProductReview $reply the persisted row, as saved and committed
57 * @param ProductReview|null $review the review it answers, if already loaded
58 * @param mixed $product the product, if already loaded
59 */
60 public static function dispatchIfStoreReply(ProductReview $reply, ?ProductReview $review = null, $product = null): void
61 {
62 if (!$reply->parent_id || !$reply->is_admin_reply) {
63 return;
64 }
65
66 (new static($reply, $review, $product))->dispatch();
67 }
68
69 public function toArray(): array
70 {
71 // What the caller handed over is used as is; only what it did not is
72 // looked up, and once.
73 if (!$this->review) {
74 $this->review = ProductReview::query()->find((int) $this->reply->parent_id);
75 }
76
77 if (!$this->product) {
78 $this->product = $this->review ? $this->review->product : null;
79 }
80
81 return [
82 'reply' => $this->reply,
83 // The review being answered — whose author is the one to tell.
84 'review' => $this->review,
85 'product' => $this->product,
86 ];
87 }
88
89 public function getActivityEventModel()
90 {
91 return $this->reply;
92 }
93
94 public function shouldCreateActivity(): bool
95 {
96 return false;
97 }
98
99 /**
100 * The settled half, off the request — see ReviewApproved::afterDispatch()
101 * for the shape, and fluent_cart/review_replied_done for the hook that
102 * consumers should use.
103 */
104 public function afterDispatch()
105 {
106 if (!function_exists('as_enqueue_async_action')) {
107 return;
108 }
109
110 as_enqueue_async_action('fluent_cart/review_replied_async_private_handle', [
111 [
112 'reply_id' => (int) $this->reply->id,
113 ],
114 ], 'fluent-cart');
115 }
116 }
117