chore: bootstrap module from working instance and add install guide
This commit is contained in:
435
Events.php
Normal file
435
Events.php
Normal file
@@ -0,0 +1,435 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\modules\donations;
|
||||
|
||||
use humhub\modules\donations\events\DonationSettlementEvent;
|
||||
use humhub\modules\donations\models\DonationGoal;
|
||||
use humhub\modules\donations\models\DonationTransaction;
|
||||
use humhub\modules\donations\services\DonationAnimalIntegrationService;
|
||||
use humhub\modules\donations\services\DonationNotificationService;
|
||||
use humhub\modules\space\models\Space;
|
||||
use humhub\modules\user\models\User;
|
||||
use Yii;
|
||||
use yii\helpers\Html;
|
||||
|
||||
class Events
|
||||
{
|
||||
public static function onSpaceMenuInit($event): void
|
||||
{
|
||||
$space = $event->sender->space ?? null;
|
||||
if ($space === null || !$space->moduleManager->isEnabled('donations')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event->sender->addItem([
|
||||
'label' => Yii::t('DonationsModule.base', 'My Donations'),
|
||||
'group' => 'modules',
|
||||
'url' => $space->createUrl('/donations/donations/index'),
|
||||
'icon' => '<i class="fa fa-heart"></i>',
|
||||
'sortOrder' => 120,
|
||||
'isActive' => (
|
||||
Yii::$app->controller
|
||||
&& Yii::$app->controller->module
|
||||
&& Yii::$app->controller->module->id === 'donations'
|
||||
&& Yii::$app->controller->id === 'donations'
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function onRescueSettingsMenuInit($event): void
|
||||
{
|
||||
$space = $event->sender->space ?? null;
|
||||
if ($space === null || !$space->moduleManager->isEnabled('donations')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event->sender->addItem([
|
||||
'label' => Yii::t('DonationsModule.base', 'Donations'),
|
||||
'url' => $space->createUrl('/donations/settings'),
|
||||
'sortOrder' => 400,
|
||||
'isActive' => (
|
||||
Yii::$app->controller
|
||||
&& Yii::$app->controller->module
|
||||
&& Yii::$app->controller->module->id === 'donations'
|
||||
&& Yii::$app->controller->id === 'settings'
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function onSpaceAdminMenuInitFallback($event): void
|
||||
{
|
||||
$space = $event->sender->space ?? null;
|
||||
if ($space === null || !$space->moduleManager->isEnabled('donations')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($space->moduleManager->isEnabled('rescue_foundation') || !$space->isAdmin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event->sender->addItem([
|
||||
'label' => Yii::t('DonationsModule.base', 'Donations'),
|
||||
'group' => 'admin',
|
||||
'url' => $space->createUrl('/donations/settings'),
|
||||
'icon' => '<i class="fa fa-heart"></i>',
|
||||
'sortOrder' => 620,
|
||||
'isActive' => (
|
||||
Yii::$app->controller
|
||||
&& Yii::$app->controller->module
|
||||
&& Yii::$app->controller->module->id === 'donations'
|
||||
&& Yii::$app->controller->id === 'settings'
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function onDonationTransactionSucceeded($event): void
|
||||
{
|
||||
if (!$event instanceof DonationSettlementEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
$payload = is_array($event->payload) ? $event->payload : [];
|
||||
|
||||
$animalIntegration = new DonationAnimalIntegrationService();
|
||||
$payload = $animalIntegration->applySucceededIntegration($event->transaction, $event->goal, $payload);
|
||||
|
||||
$notificationIntegration = new DonationNotificationService();
|
||||
$payload = $notificationIntegration->applySucceededNotifications($event->transaction, $event->goal, $payload);
|
||||
|
||||
$event->payload = $payload;
|
||||
}
|
||||
|
||||
public static function onDonationTransactionRefunded($event): void
|
||||
{
|
||||
if (!$event instanceof DonationSettlementEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
$payload = is_array($event->payload) ? $event->payload : [];
|
||||
|
||||
$animalIntegration = new DonationAnimalIntegrationService();
|
||||
$payload = $animalIntegration->applyRefundedIntegration($event->transaction, $event->goal, $payload);
|
||||
|
||||
$notificationIntegration = new DonationNotificationService();
|
||||
$payload = $notificationIntegration->applyRefundedNotifications($event->transaction, $event->goal, $payload);
|
||||
|
||||
$event->payload = $payload;
|
||||
}
|
||||
|
||||
public static function onAnimalTileOverlayRender($event): void
|
||||
{
|
||||
$hookClass = 'humhub\\modules\\animal_management\\events\\AnimalTileRenderEvent';
|
||||
if (!class_exists($hookClass) || !$event instanceof $hookClass) {
|
||||
return;
|
||||
}
|
||||
|
||||
$space = $event->contentContainer ?? null;
|
||||
if (!$space instanceof Space || !$space->moduleManager->isEnabled('donations')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Yii::$app->db->schema->getTableSchema(DonationGoal::tableName(), true) === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$goal = $event->existingDonationGoal ?? null;
|
||||
if (!$goal instanceof DonationGoal) {
|
||||
$goal = DonationGoal::find()
|
||||
->where([
|
||||
'contentcontainer_id' => (int)$space->contentcontainer_id,
|
||||
'goal_type' => DonationGoal::TYPE_ANIMAL,
|
||||
'target_animal_id' => (int)($event->animal->id ?? 0),
|
||||
])
|
||||
->orderBy(['is_active' => SORT_DESC, 'id' => SORT_DESC])
|
||||
->one();
|
||||
}
|
||||
|
||||
if (!$goal instanceof DonationGoal) {
|
||||
return;
|
||||
}
|
||||
|
||||
$target = (float)$goal->target_amount;
|
||||
$current = max(0.0, (float)$goal->current_amount);
|
||||
$isFunded = $target > 0 && $current >= $target;
|
||||
|
||||
$percent = $target > 0 ? min(100.0, round(($current / $target) * 100, 1)) : 0.0;
|
||||
$percentLabel = rtrim(rtrim(number_format($percent, 1, '.', ''), '0'), '.') . '%';
|
||||
$targetLabel = '$' . number_format(round(max(0.0, $target)), 0);
|
||||
$currentLabel = '$' . number_format(round($current), 0);
|
||||
$statusColor = $isFunded ? '#4ce083' : '#ff6666';
|
||||
|
||||
$goalToggleInputId = 'donation-goal-toggle-' . (int)($event->animal->id ?? 0);
|
||||
$quickDonateToggleInputId = 'donation-goal-quick-toggle-' . (int)($event->animal->id ?? 0);
|
||||
$goalCardId = 'donation-goal-card-' . (int)($event->animal->id ?? 0);
|
||||
$donorPanelId = 'donation-goal-donors-panel-' . (int)($event->animal->id ?? 0);
|
||||
$quickDonatePanelId = 'donation-goal-quick-panel-' . (int)($event->animal->id ?? 0);
|
||||
$donorPagerWrapId = 'donation-goal-donors-pager-' . (int)($event->animal->id ?? 0);
|
||||
$donorPagerName = 'donation-goal-donors-page-' . (int)($event->animal->id ?? 0);
|
||||
|
||||
$donorRows = [];
|
||||
if (Yii::$app->db->schema->getTableSchema(DonationTransaction::tableName(), true) !== null) {
|
||||
$transactions = DonationTransaction::find()
|
||||
->where([
|
||||
'contentcontainer_id' => (int)$space->contentcontainer_id,
|
||||
'goal_id' => (int)$goal->id,
|
||||
'status' => DonationTransaction::STATUS_SUCCEEDED,
|
||||
])
|
||||
->orderBy(['id' => SORT_DESC])
|
||||
->limit(200)
|
||||
->all();
|
||||
|
||||
$totalsByUser = [];
|
||||
$anonymousTotal = 0.0;
|
||||
foreach ($transactions as $transaction) {
|
||||
$amount = max(0.0, (float)$transaction->amount);
|
||||
if ($amount <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((int)$transaction->is_anonymous === 1 || (int)$transaction->donor_user_id <= 0) {
|
||||
$anonymousTotal += $amount;
|
||||
continue;
|
||||
}
|
||||
|
||||
$userId = (int)$transaction->donor_user_id;
|
||||
$totalsByUser[$userId] = ($totalsByUser[$userId] ?? 0.0) + $amount;
|
||||
}
|
||||
|
||||
if (!empty($totalsByUser)) {
|
||||
arsort($totalsByUser);
|
||||
$users = User::find()
|
||||
->where(['id' => array_keys($totalsByUser)])
|
||||
->indexBy('id')
|
||||
->all();
|
||||
|
||||
foreach ($totalsByUser as $userId => $totalAmount) {
|
||||
$user = $users[$userId] ?? null;
|
||||
if (!$user instanceof User) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$avatarUrl = (string)$user->getProfileImage()->getUrl();
|
||||
$profileUrl = (string)$user->getUrl();
|
||||
$displayName = (string)$user->getDisplayName();
|
||||
$amountText = '$' . number_format(round($totalAmount), 0);
|
||||
|
||||
$donorRows[] =
|
||||
'<a href="' . Html::encode($profileUrl) . '" style="display:flex;align-items:center;gap:8px;padding:6px 0;color:#fff;text-decoration:none;">'
|
||||
. '<img src="' . Html::encode($avatarUrl) . '" alt="" style="width:22px;height:22px;border-radius:999px;border:1px solid rgba(255,255,255,0.35);object-fit:cover;">'
|
||||
. '<span style="font-size:14px;opacity:0.95;">' . Html::encode($displayName) . '</span>'
|
||||
. '<span style="margin-left:auto;font-size:14px;font-weight:700;white-space:nowrap;">' . Html::encode($amountText) . '</span>'
|
||||
. '</a>';
|
||||
}
|
||||
}
|
||||
|
||||
if ($anonymousTotal > 0) {
|
||||
$donorRows[] =
|
||||
'<div style="display:flex;align-items:center;gap:8px;padding:6px 0;color:#fff;">'
|
||||
. '<span style="width:22px;height:22px;border-radius:999px;border:1px solid rgba(255,255,255,0.35);display:inline-flex;align-items:center;justify-content:center;background:rgba(255,255,255,0.12);">'
|
||||
. '<i class="fa fa-user" style="font-size:11px;"></i>'
|
||||
. '</span>'
|
||||
. '<span style="font-size:14px;opacity:0.95;">' . Html::encode(Yii::t('DonationsModule.base', 'Anonymous')) . '</span>'
|
||||
. '<span style="margin-left:auto;font-size:14px;font-weight:700;white-space:nowrap;">$' . Html::encode(number_format(round($anonymousTotal), 0)) . '</span>'
|
||||
. '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
$donorPageRows = empty($donorRows)
|
||||
? ['<div style="font-size:13px;color:rgba(255,255,255,0.9);">' . Html::encode(Yii::t('DonationsModule.base', 'No donations yet.')) . '</div>']
|
||||
: $donorRows;
|
||||
|
||||
$donorPageSize = 25;
|
||||
$donorPages = array_chunk($donorPageRows, $donorPageSize);
|
||||
$donorTotalPages = max(1, count($donorPages));
|
||||
|
||||
$donorPagesHtml = '';
|
||||
foreach ($donorPages as $pageIndex => $pageRows) {
|
||||
$pageNumber = $pageIndex + 1;
|
||||
$donorPagesHtml .= '<div data-donor-page="' . (int)$pageNumber . '" style="display:' . ($pageNumber === 1 ? 'block' : 'none') . ';">'
|
||||
. implode('', $pageRows)
|
||||
. '</div>';
|
||||
}
|
||||
$donorPagerCss = '#'. Html::encode($donorPagerWrapId) . ' [data-donor-page],#' . Html::encode($donorPagerWrapId) . ' [data-donor-controls-page]{display:none;}';
|
||||
$donorPagerRadioInputsHtml = '';
|
||||
$donorPagerTopControlsHtml = '';
|
||||
$donorPagerBottomControlsHtml = '';
|
||||
|
||||
foreach ($donorPages as $pageIndex => $pageRows) {
|
||||
$pageNumber = $pageIndex + 1;
|
||||
$radioId = $donorPagerName . '-' . (int)$pageNumber;
|
||||
$prevRadioId = $donorPagerName . '-' . (int)max(1, $pageNumber - 1);
|
||||
$nextRadioId = $donorPagerName . '-' . (int)min($donorTotalPages, $pageNumber + 1);
|
||||
|
||||
$donorPagerRadioInputsHtml .= '<input type="radio" id="' . Html::encode($radioId) . '" name="' . Html::encode($donorPagerName) . '" style="display:none;" ' . ($pageNumber === 1 ? 'checked' : '') . '>';
|
||||
|
||||
$prevControl = $pageNumber > 1
|
||||
? '<label for="' . Html::encode($prevRadioId) . '" style="display:inline-block;border:1px solid rgba(255,255,255,0.25);background:rgba(255,255,255,0.08);color:#fff;border-radius:4px;padding:2px 7px;font-size:12px;cursor:pointer;">' . Html::encode(Yii::t('DonationsModule.base', 'Previous')) . '</label>'
|
||||
: '<span style="display:inline-block;border:1px solid rgba(255,255,255,0.2);background:rgba(255,255,255,0.05);color:rgba(255,255,255,0.45);border-radius:4px;padding:2px 7px;font-size:12px;">' . Html::encode(Yii::t('DonationsModule.base', 'Previous')) . '</span>';
|
||||
|
||||
$nextControl = $pageNumber < $donorTotalPages
|
||||
? '<label for="' . Html::encode($nextRadioId) . '" style="display:inline-block;border:1px solid rgba(255,255,255,0.25);background:rgba(255,255,255,0.08);color:#fff;border-radius:4px;padding:2px 7px;font-size:12px;cursor:pointer;">' . Html::encode(Yii::t('DonationsModule.base', 'Next')) . '</label>'
|
||||
: '<span style="display:inline-block;border:1px solid rgba(255,255,255,0.2);background:rgba(255,255,255,0.05);color:rgba(255,255,255,0.45);border-radius:4px;padding:2px 7px;font-size:12px;">' . Html::encode(Yii::t('DonationsModule.base', 'Next')) . '</span>';
|
||||
|
||||
$pageLabel = Html::encode('Page ' . $pageNumber . ' / ' . $donorTotalPages);
|
||||
$controlsHtml = '<div data-donor-controls-page="' . (int)$pageNumber . '" style="align-items:center;justify-content:space-between;gap:6px;">'
|
||||
. $prevControl
|
||||
. '<span style="font-size:12px;color:rgba(255,255,255,0.9);">' . $pageLabel . '</span>'
|
||||
. $nextControl
|
||||
. '</div>';
|
||||
|
||||
$donorPagerTopControlsHtml .= $controlsHtml;
|
||||
$donorPagerBottomControlsHtml .= $controlsHtml;
|
||||
|
||||
$donorPagerCss .= '#' . Html::encode($radioId) . ':checked ~ [data-donor-top-controls] [data-donor-controls-page="' . (int)$pageNumber . '"]{display:flex;}';
|
||||
$donorPagerCss .= '#' . Html::encode($radioId) . ':checked ~ [data-donor-pages] [data-donor-page="' . (int)$pageNumber . '"]{display:block;}';
|
||||
$donorPagerCss .= '#' . Html::encode($radioId) . ':checked ~ [data-donor-bottom-controls] [data-donor-controls-page="' . (int)$pageNumber . '"]{display:flex;}';
|
||||
}
|
||||
|
||||
$goalToggleCss = '<style>'
|
||||
. '#' . Html::encode($goalToggleInputId) . ':checked ~ #' . Html::encode($donorPanelId) . '{display:block !important;opacity:1 !important;pointer-events:auto !important;}'
|
||||
. '#' . Html::encode($quickDonateToggleInputId) . ':checked ~ #' . Html::encode($quickDonatePanelId) . '{display:flex !important;opacity:1 !important;pointer-events:auto !important;}'
|
||||
. '#' . Html::encode($quickDonatePanelId) . ' input[name="amount"]::-webkit-outer-spin-button,#' . Html::encode($quickDonatePanelId) . ' input[name="amount"]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0;}'
|
||||
. '[data-animal-tile-overlay-stack]:has(#' . Html::encode($goalToggleInputId) . ':checked),'
|
||||
. '[data-animal-tile-overlay-stack]:has(#' . Html::encode($quickDonateToggleInputId) . ':checked)'
|
||||
. '{top:12px !important;bottom:12px !important;display:flex !important;flex-direction:column !important;justify-content:flex-start !important;}'
|
||||
. '[data-animal-tile-overlay-stack]:has(#' . Html::encode($goalToggleInputId) . ':checked) #' . Html::encode($goalCardId) . ','
|
||||
. '[data-animal-tile-overlay-stack]:has(#' . Html::encode($quickDonateToggleInputId) . ':checked) #' . Html::encode($goalCardId)
|
||||
. '{background:rgba(7,10,16,0.34) !important;border-color:rgba(255,255,255,0.24) !important;}'
|
||||
. $donorPagerCss
|
||||
. '</style>';
|
||||
|
||||
$quickDonateHeaderTemplate = (string)Yii::$app->getModule('donations')->settings->contentContainer($space)
|
||||
->get('animal_donation_form_header', Yii::t('DonationsModule.base', 'Your Donation directly supports [animal-name]'));
|
||||
$quickDonateHeaderTemplate = trim($quickDonateHeaderTemplate);
|
||||
if ($quickDonateHeaderTemplate === '') {
|
||||
$quickDonateHeaderTemplate = Yii::t('DonationsModule.base', 'Your Donation directly supports [animal-name]');
|
||||
}
|
||||
$quickDonateHeaderText = str_replace('[animal-name]', (string)$event->animal->getDisplayName(), $quickDonateHeaderTemplate);
|
||||
|
||||
$quickDonateActionUrl = $space->createUrl('/donations/donations/donate');
|
||||
$quickDonatePanelHtml = '<div id="' . Html::encode($quickDonatePanelId) . '" style="display:none;opacity:0;pointer-events:none;margin:8px 12px 0;padding:20px 20px;border-radius:7px;background:rgba(0,0,0,0.28);border:1px solid rgba(255,255,255,0.15);overflow:hidden;max-width:fit-content;width:fit-content;justify-self:center;align-self:center;">'
|
||||
. '<form method="post" action="' . Html::encode($quickDonateActionUrl) . '" style="margin:0;display:flex;flex-direction:column;align-items:center;text-align:center;">'
|
||||
. Html::hiddenInput(Yii::$app->request->csrfParam, Yii::$app->request->getCsrfToken())
|
||||
. Html::hiddenInput('goal_id', (int)$goal->id)
|
||||
. '<div style="margin:0 0 8px 0;font-size:13px;font-weight:700;color:#fff;text-align:center;hyphens:none;word-break:normal;overflow-wrap:normal;white-space:normal;">' . Html::encode($quickDonateHeaderText) . '</div>'
|
||||
. '<div style="display:flex;align-items:center;justify-content:center;gap:6px;margin-bottom:8px;">'
|
||||
. '<label style="margin:0;font-size:24px;font-weight:700;color:#fff;line-height:1;">$</label>'
|
||||
. '<input type="number" step="0.01" min="0.01" name="amount" required class="form-control input-sm" style="width:100px;max-width:100px;min-width:100px;background:rgba(54,209,124,0.32) !important;border:1px solid rgba(54,209,124,0.72) !important;border-radius:999px !important;color:#f8fafc !important;-webkit-text-fill-color:#f8fafc;box-shadow:none !important;font-size:24px;font-weight:700;line-height:1.15;text-align:center;padding:4px 10px;appearance:textfield;-moz-appearance:textfield;overflow:hidden;">'
|
||||
. '</div>'
|
||||
. '<div style="display:flex;align-items:center;justify-content:center;gap:14px;flex-wrap:wrap;margin-bottom:8px;">'
|
||||
. '<label style="margin:0;display:flex;align-items:center;gap:6px;color:#fff;font-size:13px;cursor:pointer;">'
|
||||
. '<input type="radio" name="mode" value="one_time" checked>'
|
||||
. Html::encode(Yii::t('DonationsModule.base', 'One Time'))
|
||||
. '</label>'
|
||||
. '<label style="margin:0;display:flex;align-items:center;gap:6px;color:#fff;font-size:13px;cursor:pointer;">'
|
||||
. '<input type="radio" name="mode" value="recurring">'
|
||||
. Html::encode(Yii::t('DonationsModule.base', 'Recurring'))
|
||||
. '</label>'
|
||||
. '</div>'
|
||||
. '<label style="margin:0 0 10px 0;display:flex;align-items:center;justify-content:center;gap:6px;color:#fff;font-size:13px;cursor:pointer;">'
|
||||
. '<input type="checkbox" name="is_anonymous" value="1">'
|
||||
. Html::encode(Yii::t('DonationsModule.base', 'Donate anonymously'))
|
||||
. '</label>'
|
||||
. '<div style="display:flex;align-items:center;gap:8px;justify-content:center;">'
|
||||
. '<button type="submit" name="provider" value="paypal" class="btn btn-sm" style="min-width:92px;border:1px solid rgba(255,255,255,0.28);background:rgba(255,255,255,0.12);color:#fff;">PayPal</button>'
|
||||
. '<button type="submit" name="provider" value="stripe" class="btn btn-sm" style="min-width:92px;border:1px solid rgba(255,255,255,0.28);background:rgba(255,255,255,0.12);color:#fff;">Stripe</button>'
|
||||
. '</div>'
|
||||
. '</form>'
|
||||
. '</div>';
|
||||
|
||||
$donorPanelHtml = $goalToggleCss
|
||||
. '<input type="checkbox" id="' . Html::encode($goalToggleInputId) . '" style="display:none;" onchange="if(this.checked){var q=document.getElementById(\'' . Html::encode($quickDonateToggleInputId) . '\');if(q){q.checked=false;}}">'
|
||||
. '<input type="checkbox" id="' . Html::encode($quickDonateToggleInputId) . '" style="display:none;" onchange="if(this.checked){var g=document.getElementById(\'' . Html::encode($goalToggleInputId) . '\');if(g){g.checked=false;}}">'
|
||||
. '<div id="' . Html::encode($donorPanelId) . '" style="display:none;opacity:0;pointer-events:none;margin-top:8px;padding:8px 10px;border-radius:7px;background:rgba(0,0,0,0.28);border:1px solid rgba(255,255,255,0.15);overflow:hidden;max-height:calc(100% - 98px);">'
|
||||
. '<div id="' . Html::encode($donorPagerWrapId) . '">'
|
||||
. $donorPagerRadioInputsHtml
|
||||
. '<div data-donor-top-controls style="' . ($donorTotalPages > 1 ? 'margin-bottom:6px;' : 'display:none;') . '">' . $donorPagerTopControlsHtml . '</div>'
|
||||
. '<div data-donor-pages data-donor-list-scroll style="overflow-y:auto;max-height:calc(100% - 72px);">' . $donorPagesHtml . '</div>'
|
||||
. '<div data-donor-bottom-controls style="' . ($donorTotalPages > 1 ? 'margin-top:6px;' : 'display:none;') . '">' . $donorPagerBottomControlsHtml . '</div>'
|
||||
. '</div>'
|
||||
. '</div>';
|
||||
|
||||
$goalLabelHtml = '<label for="' . Html::encode($goalToggleInputId) . '" style="margin:0;cursor:pointer;font-weight:700;color:rgba(255,255,255,0.98);pointer-events:auto;position:relative;z-index:4;">'
|
||||
. Html::encode(Yii::t('DonationsModule.base', 'Goal'))
|
||||
. '</label>';
|
||||
|
||||
$percentColor = $percent >= 100.0 ? '#4ce083' : '#ffffff';
|
||||
|
||||
$currentAmountHtml = '<span style="font-weight:700;color:#ffffff;white-space:nowrap;">' . Html::encode($currentLabel) . '</span>';
|
||||
|
||||
$targetAmountNumberLabel = ltrim($targetLabel, '$');
|
||||
if ($targetAmountNumberLabel === '') {
|
||||
$targetAmountNumberLabel = $targetLabel;
|
||||
}
|
||||
|
||||
$targetAmountInnerHtml = '<span style="display:inline-flex;align-items:flex-end;gap:2px;line-height:1;">'
|
||||
. '<span style="font-size:13px;line-height:1;transform:translateY(-0.36em);">$</span>'
|
||||
. '<span style="font-size:21px;line-height:1;">' . Html::encode($targetAmountNumberLabel) . '</span>'
|
||||
. '</span>';
|
||||
|
||||
$donateCtaHtml = '<span style="display:inline-flex;align-items:center;justify-content:center;height:16px;padding:4px 14px;border-radius:999px;border:1px solid rgba(30,164,95,0.62);background:linear-gradient(90deg,#36d17c,#1ea45f);color:#000000;font-size:12px;font-weight:800;letter-spacing:.08em;line-height:1;text-transform:uppercase;box-shadow:0 0 0 1px rgba(255,255,255,0.2),0 0 10px rgba(54,209,124,0.62),0 0 18px rgba(30,164,95,0.46);text-shadow:0 0 2px rgba(255,255,255,0.28);">'
|
||||
. Html::encode(Yii::t('DonationsModule.base', 'Donate'))
|
||||
. '</span>';
|
||||
|
||||
$targetAmountHtml = '<span style="margin-left:auto;font-weight:700;color:' . $statusColor . ';white-space:nowrap;display:inline-flex;align-items:flex-end;">' . $targetAmountInnerHtml . '</span>';
|
||||
if (!empty($event->showDonationSettingsButton) && !empty($event->donationToggleInputId)) {
|
||||
$toggleInputId = (string)$event->donationToggleInputId;
|
||||
$inlineFormId = (string)($event->donationInlineFormId ?? '');
|
||||
$targetOnClick = '';
|
||||
if ($inlineFormId !== '') {
|
||||
$targetOnClick = ' onclick="var c=document.getElementById(\'' . Html::encode($toggleInputId) . '\');var f=document.getElementById(\'' . Html::encode($inlineFormId) . '\');if(c&&f){window.setTimeout(function(){f.style.display=c.checked?\'block\':\'none\';},0);}"';
|
||||
}
|
||||
|
||||
$targetAmountHtml = '<label for="' . Html::encode($toggleInputId) . '" class="js-animal-donation-inline-toggle"'
|
||||
. ' data-toggle-id="#' . Html::encode($toggleInputId) . '"'
|
||||
. ($inlineFormId !== '' ? ' data-form-id="#' . Html::encode($inlineFormId) . '"' : '')
|
||||
. $targetOnClick
|
||||
. ' style="margin:0 0 0 auto;cursor:pointer;font-weight:700;color:' . $statusColor . ';pointer-events:auto;position:relative;z-index:4;text-decoration:none;white-space:nowrap;display:inline-flex;align-items:flex-end;">'
|
||||
. $targetAmountInnerHtml
|
||||
. '</label>';
|
||||
}
|
||||
|
||||
$event->addHtml(
|
||||
'<div id="' . Html::encode($goalCardId) . '" style="display:block;position:relative;overflow:visible;width:100%;padding:7px 8px;border-radius:8px;background:rgba(7,10,16,0.16);border:1px solid rgba(255,255,255,0.14);box-sizing:border-box;transition:background 140ms ease,border-color 140ms ease;">'
|
||||
. '<div style="position:relative;">'
|
||||
. '<label for="' . Html::encode($quickDonateToggleInputId) . '" style="position:absolute;inset:0;z-index:2;cursor:pointer;"></label>'
|
||||
. '<div style="position:relative;z-index:3;display:flex;gap:8px;align-items:flex-end;font-size:16.5px;color:rgba(255,255,255,0.95);pointer-events:none;">'
|
||||
. $goalLabelHtml
|
||||
. $targetAmountHtml
|
||||
. '</div>'
|
||||
. '<div style="margin-top:5px;height:7px;border-radius:999px;overflow:hidden;background:rgba(255,255,255,0.22);pointer-events:none;">'
|
||||
. '<span style="display:block;height:100%;width:' . Html::encode((string)$percent) . '%;background:linear-gradient(90deg,#36d17c,#1ea45f);"></span>'
|
||||
. '</div>'
|
||||
. '<div style="margin-top:4px;display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:end;column-gap:10px;font-size:16.5px;font-weight:700;pointer-events:none;">'
|
||||
. $currentAmountHtml
|
||||
. $donateCtaHtml
|
||||
. '<span style="justify-self:end;white-space:nowrap;text-align:right;color:' . $percentColor . ';">' . Html::encode($percentLabel) . '</span>'
|
||||
. '</div>'
|
||||
. '</div>'
|
||||
. $donorPanelHtml
|
||||
. $quickDonatePanelHtml
|
||||
. '</div>'
|
||||
);
|
||||
}
|
||||
|
||||
public static function onAnimalTileSizeResolve($event): void
|
||||
{
|
||||
$hookClass = 'humhub\\modules\\animal_management\\events\\AnimalTileSizeEvent';
|
||||
if (!class_exists($hookClass) || !$event instanceof $hookClass) {
|
||||
return;
|
||||
}
|
||||
|
||||
$space = $event->contentContainer ?? null;
|
||||
if (!$space instanceof Space || !$space->moduleManager->isEnabled('donations')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$settings = Yii::$app->getModule('donations')->settings->contentContainer($space);
|
||||
$extraHeight = max(0, (int)$settings->get('animal_tile_extra_height_px', 0));
|
||||
if ($extraHeight <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event->addAdditionalHeightPx($extraHeight);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user