147 lines
5.2 KiB
PHP
147 lines
5.2 KiB
PHP
<?php
|
|
|
|
namespace humhub\modules\donations\services;
|
|
|
|
use humhub\modules\donations\models\DonationGoal;
|
|
use humhub\modules\donations\models\DonationTransaction;
|
|
use humhub\modules\donations\notifications\DonationRefundedNotification;
|
|
use humhub\modules\donations\notifications\DonationSucceededNotification;
|
|
use humhub\modules\space\models\Space;
|
|
use humhub\modules\user\models\User;
|
|
use Yii;
|
|
|
|
class DonationNotificationService
|
|
{
|
|
public function applySucceededNotifications(DonationTransaction $transaction, ?DonationGoal $goal, array $payload): array
|
|
{
|
|
if (!empty($payload['donation_succeeded_notifications_sent'])) {
|
|
return $payload;
|
|
}
|
|
|
|
return $this->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);
|
|
}
|
|
}
|