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 / ReviewApproved.php

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

109 lines 3.4 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\Helpers\Status;
6 use FluentCart\App\Models\ProductReview;
7
8 /**
9 * A review became approved — fluent_cart/review_approved.
10 *
11 * Fired once per transition into the approved status, on every path that can
12 * make one: a moderator approving a single review, a bulk approve, a review
13 * born approved because the store auto-approves, and a moderator writing one
14 * by hand. Never for a reply: a reply is the store's own words and has no
15 * moderation state worth announcing.
16 *
17 * It is the transition that fires, not the state. A review approved, held
18 * back and approved again fires twice, and that is correct for an event —
19 * the notification built on it is what has to send once, and it keeps its
20 * own claim for that (see ProductReviewService::claimApprovalNotice()).
21 */
22 class ReviewApproved extends EventDispatcher
23 {
24 public string $hook = 'fluent_cart/review_approved';
25
26 protected array $listeners = [];
27
28 public ProductReview $review;
29
30 public function __construct(ProductReview $review)
31 {
32 $this->review = $review;
33 }
34
35 /**
36 * Dispatch for a review that has just been written or transitioned, if it
37 * is one this event is about. Every dispatch site asks the same question,
38 * so the question is asked here.
39 *
40 * @param ProductReview $review the persisted row, as saved
41 * @param string|null $previousStatus the status before this write; null for a new row
42 */
43 public static function dispatchIfApproved(ProductReview $review, $previousStatus = null): void
44 {
45 if ($review->parent_id) {
46 return;
47 }
48
49 if ($review->status !== Status::REVIEW_APPROVED) {
50 return;
51 }
52
53 if ($previousStatus === Status::REVIEW_APPROVED) {
54 return;
55 }
56
57 (new static($review))->dispatch();
58 }
59
60 public function toArray(): array
61 {
62 // Only if the caller did not bring it: a bulk approve eager-loads the
63 // product for the whole batch, and fifty dispatches must not turn
64 // that into fifty lookups.
65 $this->review->loadMissing('product');
66
67 return [
68 'review' => $this->review,
69 'product' => $this->review->product,
70 ];
71 }
72
73 public function getActivityEventModel()
74 {
75 return $this->review;
76 }
77
78 public function shouldCreateActivity(): bool
79 {
80 return false;
81 }
82
83 /**
84 * The settled half of the approval, off the request.
85 *
86 * The hook this event fires is the transition, as it happened. What most
87 * consumers want is the transition once the dust has settled — the media
88 * hooks done, the row re-read, the review still approved — and that is
89 * fluent_cart/review_approved_done, fired by the job queued here. The
90 * same split as order_paid and order_paid_done: the event says it
91 * happened, the job says it stuck.
92 *
93 * 3rd party devs: hang integrations on fluent_cart/review_approved_done,
94 * not on this event's own hook.
95 */
96 public function afterDispatch()
97 {
98 if (!function_exists('as_enqueue_async_action')) {
99 return;
100 }
101
102 as_enqueue_async_action('fluent_cart/review_approved_async_private_handle', [
103 [
104 'review_id' => (int) $this->review->id,
105 ],
106 ], 'fluent-cart');
107 }
108 }
109