| @@ -46,12 +46,30 @@ | ||
| 46 | 46 | } |
| 47 | 47 | |
| 48 | 48 | /** |
| 49 | 49 | * Handle campaign cache |
| 50 | + * | |
| 51 | + * @since 4.18.0 Read the subscriptions cache from the option it is written to; always compute live stats, keep zero rows when a campaign has no donations. | |
| 50 | 52 | * @since 4.8.0 |
| 51 | 53 | */ |
| 52 | 54 | public function handleCache(int $campaignId): void |
| 53 | 55 | { |
| 56 | + // The cache holds live stats only. The queries follow the site's payment mode, so force | |
| 57 | + // live for the duration of the job in case test mode was switched on before it ran. | |
| 58 | + add_filter('give_is_test_mode', '__return_false', PHP_INT_MAX); | |
| 59 | + | |
| 60 | + try { | |
| 61 | + $this->refresh($campaignId); | |
| 62 | + } finally { | |
| 63 | + remove_filter('give_is_test_mode', '__return_false', PHP_INT_MAX); | |
| 64 | + } | |
| 65 | + } | |
| 66 | + | |
| 67 | + /** | |
| 68 | + * @since 4.18.0 | |
| 69 | + */ | |
| 70 | + private function refresh(int $campaignId): void | |
| 71 | + { | |
| 54 | 72 | $campaign = Campaign::find($campaignId); |
| 55 | 73 | |
| 56 | 74 | if (!$campaign) { |
| 57 | 75 | return; |
| @@ -57,9 +75,9 @@ | ||
| 57 | 75 | return; |
| 58 | 76 | } |
| 59 | 77 | |
| 60 | 78 | $campaignsData = get_option('give_campaigns_data', []); |
| 61 | - $campaignsSubscriptionData = get_option('give_campaigns_subscription_data', []); | |
| 79 | + $campaignsSubscriptionData = get_option('give_campaigns_subscriptions_data', []); | |
| 62 | 80 | |
| 63 | 81 | // Prefill cache structure to ensure keys exist |
| 64 | 82 | $campaignsData = array_merge([ |
| 65 | 83 | 'amounts' => [], |
| @@ -81,9 +99,9 @@ | ||
| 81 | 99 | foreach ($campaignsData['amounts'] as $i => $data) { |
| 82 | 100 | if ($data['campaign_id'] == $campaign->id) { |
| 83 | 101 | $isCached = true; |
| 84 | 102 | |
| 85 | - $campaignsData['amounts'][$i] = $donations->collectIntendedAmounts()[0]; | |
| 103 | + $campaignsData['amounts'][$i] = $this->row($donations->collectIntendedAmounts(), $campaign->id, 'sum'); | |
| 86 | 104 | break; |
| 87 | 105 | } |
| 88 | 106 | } |
| 89 | 107 | |
| @@ -88,9 +106,9 @@ | ||
| 88 | 106 | } |
| 89 | 107 | |
| 90 | 108 | foreach ($campaignsData['donationsCount'] as $i => $data) { |
| 91 | 109 | if ($data['campaign_id'] == $campaign->id) { |
| 92 | - $campaignsData['donationsCount'][$i] = $donations->collectDonations()[0]; | |
| 110 | + $campaignsData['donationsCount'][$i] = $this->row($donations->collectDonations(), $campaign->id, 'count'); | |
| 93 | 111 | break; |
| 94 | 112 | } |
| 95 | 113 | } |
| 96 | 114 | |
| @@ -95,9 +113,9 @@ | ||
| 95 | 113 | } |
| 96 | 114 | |
| 97 | 115 | foreach ($campaignsData['donorsCount'] as $i => $data) { |
| 98 | 116 | if ($data['campaign_id'] == $campaign->id) { |
| 99 | - $campaignsData['donorsCount'][$i] = $donations->collectDonors()[0]; | |
| 117 | + $campaignsData['donorsCount'][$i] = $this->row($donations->collectDonors(), $campaign->id, 'count'); | |
| 100 | 118 | break; |
| 101 | 119 | } |
| 102 | 120 | } |
| 103 | 121 | |
| @@ -110,9 +128,9 @@ | ||
| 110 | 128 | foreach ($campaignsSubscriptionData['amounts'] as $i => $data) { |
| 111 | 129 | if ($data['campaign_id'] == $campaign->id) { |
| 112 | 130 | $isSubscriptionCached = true; |
| 113 | 131 | |
| 114 | - $campaignsSubscriptionData['amounts'][$i] = $subscriptions->collectInitialAmounts()[0]; | |
| 132 | + $campaignsSubscriptionData['amounts'][$i] = $this->row($subscriptions->collectInitialAmounts(), $campaign->id, 'sum'); | |
| 115 | 133 | break; |
| 116 | 134 | } |
| 117 | 135 | } |
| 118 | 136 | |
| @@ -117,9 +135,9 @@ | ||
| 117 | 135 | } |
| 118 | 136 | |
| 119 | 137 | foreach ($campaignsSubscriptionData['donationsCount'] as $i => $data) { |
| 120 | 138 | if ($data['campaign_id'] == $campaign->id) { |
| 121 | - $campaignsSubscriptionData['donationsCount'][$i] = $subscriptions->collectDonations()[0]; | |
| 139 | + $campaignsSubscriptionData['donationsCount'][$i] = $this->row($subscriptions->collectDonations(), $campaign->id, 'count'); | |
| 122 | 140 | break; |
| 123 | 141 | } |
| 124 | 142 | } |
| 125 | 143 | |
| @@ -124,9 +142,9 @@ | ||
| 124 | 142 | } |
| 125 | 143 | |
| 126 | 144 | foreach ($campaignsSubscriptionData['donorsCount'] as $i => $data) { |
| 127 | 145 | if ($data['campaign_id'] == $campaign->id) { |
| 128 | - $campaignsSubscriptionData['donorsCount'][$i] = $subscriptions->collectDonors()[0]; | |
| 146 | + $campaignsSubscriptionData['donorsCount'][$i] = $this->row($subscriptions->collectDonors(), $campaign->id, 'count'); | |
| 129 | 147 | break; |
| 130 | 148 | } |
| 131 | 149 | } |
| 132 | 150 | } |
| @@ -163,9 +181,9 @@ | ||
| 163 | 181 | if (defined('GIVE_RECURRING_VERSION')) { |
| 164 | 182 | update_option('give_campaigns_subscriptions_data', [ |
| 165 | 183 | 'amounts' => array_merge( |
| 166 | 184 | $campaignsSubscriptionData['amounts'] ?? [], |
| 167 | - $subscriptions->collectIntendedAmounts() | |
| 185 | + $subscriptions->collectInitialAmounts() | |
| 168 | 186 | ), |
| 169 | 187 | 'donationsCount' => array_merge( |
| 170 | 188 | $campaignsSubscriptionData['donationsCount'] ?? [], |
| 171 | 189 | $subscriptions->collectDonations() |
| @@ -175,6 +193,17 @@ | ||
| 175 | 193 | $subscriptions->collectDonors() |
| 176 | 194 | ), |
| 177 | 195 | ]); |
| 178 | 196 | } |
| 197 | + } | |
| 198 | + | |
| 199 | + /** | |
| 200 | + * The aggregate queries return no row for a campaign with no donations. Keep a zero row so the | |
| 201 | + * campaign stays cached instead of turning into a null row and a PHP warning. | |
| 202 | + * | |
| 203 | + * @since 4.18.0 | |
| 204 | + */ | |
| 205 | + private function row($rows, int $campaignId, string $column): array | |
| 206 | + { | |
| 207 | + return $rows[0] ?? ['campaign_id' => (string)$campaignId, $column => 0]; | |
| 179 | 208 | } |
| 180 | 209 | } |