sendNotifications($transaction, $goal, $payload, 'succeeded'); } public function applyRefundedNotifications(DonationTransaction $transaction, ?DonationGoal $goal, array $payload): array { if (!empty($payload['donation_refunded_notifications_sent'])) { return $payload; } return $this->sendNotifications($transaction, $goal, $payload, 'refunded'); } private function sendNotifications(DonationTransaction $transaction, ?DonationGoal $goal, array $payload, string $mode): array { $space = Space::findOne(['contentcontainer_id' => (int)$transaction->contentcontainer_id]); if (!$space instanceof Space) { return $payload; } $goal = $goal instanceof DonationGoal ? $goal : DonationGoal::findOne([ 'id' => (int)$transaction->goal_id, 'contentcontainer_id' => (int)$transaction->contentcontainer_id, ]); $goalTitle = $goal instanceof DonationGoal ? (string)$goal->title : Yii::t('DonationsModule.base', 'Donation Goal #{id}', ['id' => (int)$transaction->goal_id]); $amountLabel = number_format((float)$transaction->amount, 2) . ' ' . strtoupper((string)$transaction->currency); $originator = $this->findUser((int)$transaction->donor_user_id); $managerRecipients = $this->privilegedUsersForSpace($space); $donorRecipient = $originator; $sent = 0; $failures = 0; $send = function (User $recipient, bool $isDonorRecipient) use ($mode, $space, $goalTitle, $amountLabel, $originator, &$sent, &$failures): void { try { $notification = $mode === 'refunded' ? DonationRefundedNotification::instance() : DonationSucceededNotification::instance(); if ($originator instanceof User && !$isDonorRecipient) { $notification->from($originator); } $notification->spaceGuid = (string)$space->guid; $notification->goalTitle = $goalTitle; $notification->amountLabel = $amountLabel; $notification->payload([ 'spaceGuid' => $notification->spaceGuid, 'goalTitle' => $notification->goalTitle, 'amountLabel' => $notification->amountLabel, ]); $notification->send($recipient); $sent++; } catch (\Throwable $e) { Yii::warning([ 'message' => 'Could not send donation notification.', 'mode' => $mode, 'transaction_id' => (int)$transaction->id, 'recipient_id' => (int)$recipient->id, 'exception' => $e->getMessage(), ], 'donations.notifications'); $failures++; } }; if ($donorRecipient instanceof User) { $send($donorRecipient, true); } foreach ($managerRecipients as $recipient) { if ($donorRecipient instanceof User && (int)$recipient->id === (int)$donorRecipient->id) { continue; } $send($recipient, false); } $prefix = $mode === 'refunded' ? 'donation_refunded_notifications' : 'donation_succeeded_notifications'; $payload[$prefix . '_sent'] = 1; $payload[$prefix . '_sent_count'] = $sent; $payload[$prefix . '_failed_count'] = $failures; $payload[$prefix . '_at'] = date('c'); return $payload; } private function findUser(int $userId): ?User { if ($userId <= 0) { return null; } $user = User::findOne(['id' => $userId]); if (!$user instanceof User || (int)$user->status !== User::STATUS_ENABLED) { return null; } return $user; } private function privilegedUsersForSpace(Space $space): array { $recipients = []; foreach ($space->getPrivilegedGroupUsers() as $users) { foreach ($users as $user) { if ($user instanceof User && (int)$user->status === User::STATUS_ENABLED) { $recipients[(int)$user->id] = $user; } } } if (empty($recipients)) { $owner = $space->getOwnerUser()->one(); if ($owner instanceof User && (int)$owner->status === User::STATUS_ENABLED) { $recipients[(int)$owner->id] = $owner; } } return array_values($recipients); } }