From d3ca5ce9810d2aac9f800ea565ff4f146db9ec6c Mon Sep 17 00:00:00 2001 From: Spine Date: Mon, 8 Sep 2025 12:21:58 +0000 Subject: [PATCH] show how many tokens a user has been gifted --- app/BonusItem.php | 20 ++++++++++---------- app/User/Bonus.php | 29 +++++++++++++++++++++++++++++ templates/user/header.twig | 24 +++++++++++++++++------- tests/phpunit/BonusTest.php | 24 ++++++++++++++++++++---- 4 files changed, 76 insertions(+), 21 deletions(-) diff --git a/app/BonusItem.php b/app/BonusItem.php index 12fbe863b..9b5c34816 100644 --- a/app/BonusItem.php +++ b/app/BonusItem.php @@ -144,7 +144,7 @@ class BonusItem extends \Gazelle\BaseObject { AND ub.user_id = ? ', $this->amount(), $price, $price, $user->id ); - if (self::$db->affected_rows() != 2) { + if (self::$db->affected_rows() != 1 + ($price === 0 ? 0 : 1)) { return Enum\BonusItemPurchaseStatus::insufficientFunds; } } elseif (str_starts_with($this->label(), 'other-')) { @@ -178,13 +178,14 @@ class BonusItem extends \Gazelle\BaseObject { other_uf.tokens = other_uf.tokens + ?, ub.points = ub.points - ? WHERE noFL.UserID IS NULL - AND ub.points >= ? - AND other.Enabled = '1' + AND other.Enabled = ? AND other.ID = ? AND self.ID = ? - ", $this->amount(), $price, $price, $receiver->id, $user->id + AND ub.points >= ? + ", $this->amount(), $price, + Enum\UserStatus::enabled->value, $receiver->id, $user->id, $price ); - if (self::$db->affected_rows() != 2) { + if (self::$db->affected_rows() != 1 + ($price === 0 ? 0 : 1)) { return Enum\BonusItemPurchaseStatus::insufficientFunds; } $amount = $this->amount(); @@ -213,8 +214,7 @@ class BonusItem extends \Gazelle\BaseObject { AND ub.user_id = ? ', $price, $price, $user->id ); - $rows = self::$db->affected_rows(); - if (($price > 0 && $rows !== 2) || ($price === 0 && $rows !== 1)) { + if (self::$db->affected_rows() != 1 + ($price === 0 ? 0 : 1)) { self::$db->rollback(); return Enum\BonusItemPurchaseStatus::insufficientFunds; } @@ -238,7 +238,7 @@ class BonusItem extends \Gazelle\BaseObject { AND ub.user_id = ? ', $price, $price, $user->id ); - if (self::$db->affected_rows() != 1) { + if ($price > 0 && self::$db->affected_rows() != 1) { self::$db->rollback(); return Enum\BonusItemPurchaseStatus::insufficientFunds; } @@ -270,7 +270,7 @@ class BonusItem extends \Gazelle\BaseObject { AND ub.user_id = ? ', $price, $price, $user->id ); - if (self::$db->affected_rows() != 2) { + if (self::$db->affected_rows() != 1 + ($price === 0 ? 0 : 1)) { return Enum\BonusItemPurchaseStatus::insufficientFunds; } break; @@ -284,7 +284,7 @@ class BonusItem extends \Gazelle\BaseObject { AND ub.user_id = ? ', $price, $price, $user->id ); - if (self::$db->affected_rows() != 1) { + if ($price > 0 && self::$db->affected_rows() != 1) { self::$db->rollback(); return Enum\BonusItemPurchaseStatus::insufficientFunds; } diff --git a/app/User/Bonus.php b/app/User/Bonus.php index 3173ad585..e25ee6fbd 100644 --- a/app/User/Bonus.php +++ b/app/User/Bonus.php @@ -40,6 +40,35 @@ class Bonus extends \Gazelle\BaseUser { ); } + /** + * @return array + */ + public function tokenExchange(): array { + return array_map( + 'intval', + self::$db->rowAssoc(" + WITH sent(n) AS ( + SELECT sum(bi.Amount) + FROM bonus_history bh + INNER JOIN bonus_item bi ON (bi.ID = bh.ItemID) + WHERE bh.OtherUserID IS NOT NULL + AND bh.UserID = ? + ), + recv(n) AS ( + SELECT sum(bi.Amount) + FROM bonus_history bh + INNER JOIN bonus_item bi ON (bi.ID = bh.ItemID) + WHERE OtherUserID = ? + ) + SELECT coalesce(recv.n, 0) AS received, + coalesce(sent.n, 0) AS sent + FROM sent + CROSS JOIN recv + ", $this->user->id, $this->user->id + ) + ); + } + public function otherLatest(\Gazelle\User $other): array { return self::$db->rowAssoc(" SELECT bi.Title AS title, diff --git a/templates/user/header.twig b/templates/user/header.twig index c8a3bf55b..3932e0fef 100644 --- a/templates/user/header.twig +++ b/templates/user/header.twig @@ -89,19 +89,29 @@
    {% for item in freeleech.offer %} -
  • -
  • +
  • + +
  • {% endfor %}

  • {% if freeleech.latest %} {% set when = freeleech.latest.purchase_date|time_diff %} -
  • - You gave them {{ freeleech.latest.title|trim(' to Other') }} {{ when|raw }} -{%- if 'Just now' in when %}. Your generosity is most appreciated!{% endif -%} +
  • You gave them {{ freeleech.latest.title|trim(' to Other') }} {{ + when|raw }}{% if 'Just now' in when %}. Your generosity is most appreciated!{% endif -%}
  • +{% endif %} +{% set exchange = bonus.tokenExchange %} +{% if exchange.received > exchange.sent %} +{% set net = exchange.received - exchange.sent %} +
  • Total benefits: {{ + net | number_format }} token{{ net|plural }}
  • {% endif %}
diff --git a/tests/phpunit/BonusTest.php b/tests/phpunit/BonusTest.php index 850851412..bf3d19d8e 100644 --- a/tests/phpunit/BonusTest.php +++ b/tests/phpunit/BonusTest.php @@ -194,6 +194,23 @@ class BonusTest extends TestCase { 'bonus-points-spent', ); + $this->assertEquals( + BonusItemPurchaseStatus::success, + $other1->purchase( + $this->userList['receiver'], + 0, + ['receiver' => $user], + ), + 'bonus-item-receiver-give' + ); + $this->assertEquals( + [ + "received" => 50, + "sent" => 1, + ], + (new User\Bonus($this->userList['receiver'])->tokenExchange()), + 'bonus-token-exchange', + ); $latest = $giver->otherLatest($this->userList['receiver']); $this->assertEquals('50 Freeleech Tokens to Other', $latest['title'], 'bonus-item-given'); @@ -287,16 +304,15 @@ class BonusTest extends TestCase { 'bonus-item-free-title-yes-bb', ); - $userBonus = new User\Bonus($user); - $history = $userBonus->purchaseHistory(); + $history = $giver->purchaseHistory(); $this->assertCount(8, $history, 'bonus-history-count'); $this->assertEquals( ['id', 'title', 'total', 'cost'], array_keys(current($history)), 'bonus-history-shape', ); - $this->assertCount(0, $userBonus->seedList(5, 0), 'bonus-history-seedlist'); - $this->assertCount(0, $userBonus->poolHistory(), 'bonus-history-pool'); + $this->assertCount(0, $giver->seedList(5, 0), 'bonus-history-seedlist'); + $this->assertCount(0, $giver->poolHistory(), 'bonus-history-pool'); // Here is as good a place as any $this->assertEquals(0, $manager->discount(), 'bonus-discount');