PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.15.0
GiveWP – Donation Plugin and Fundraising Platform v4.15.0
4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / src / DonationForms / Repositories / DonationFormDataRepository.php
give / src / DonationForms / Repositories Last commit date
DonationFormDataRepository.php 1 year ago DonationFormRepository.php 10 months ago
DonationFormDataRepository.php
273 lines
1 <?php
2
3 namespace Give\DonationForms\Repositories;
4
5
6 use Give\Campaigns\CampaignsDataQuery;
7 use Give\Campaigns\ValueObjects\CampaignGoalType;
8 use Give\DonationForms\DonationFormDataQuery;
9 use Give\DonationForms\V2\Models\DonationForm;
10 use Give\DonationForms\ValueObjects\GoalSource;
11 use Give\DonationForms\ValueObjects\GoalType;
12 use Give\Framework\Database\DB;
13
14 /**
15 * @since 4.3.0
16 *
17 * Used to optimize the donation forms list table performance and to avoid n+1 problems.
18 */
19 class DonationFormDataRepository
20 {
21 private array $formAmounts = [];
22 private array $campaignAmounts = [];
23 private array $formSubscriptionAmounts = [];
24 private array $campaignSubscriptionAmounts = [];
25 private array $formDonationsCount = [];
26 private array $campaignDonationsCount = [];
27 private array $formSubscriptionDonationsCount = [];
28 private array $campaignSubscriptionDonationsCount = [];
29 private array $formDonorsCount = [];
30 private array $campaignDonorsCount = [];
31 private array $formSubscriptionDonorsCount = [];
32 private array $campaignSubscriptionDonorsCount = [];
33
34 /**
35 * @param DonationForm[] $forms
36 *
37 * @return DonationFormDataRepository
38 */
39 public static function forms(array $forms): DonationFormDataRepository
40 {
41 $self = new self();
42
43 $formsUsingFormGoal = [];
44 $formsUsingCampaignGoal = [];
45
46 foreach ($forms as $form) {
47 if ($form->goalSettings->goalSource === GoalSource::CAMPAIGN) {
48 $formsUsingCampaignGoal[] = $form->id;
49 } else {
50 $formsUsingFormGoal[] = $form->id;
51 }
52 }
53
54 if ( ! empty($formsUsingFormGoal)) {
55 $self->setFormsGoals($formsUsingFormGoal);
56 }
57
58 if ( ! empty($formsUsingCampaignGoal)) {
59 $self->setFormsCampaignGoals($formsUsingCampaignGoal);
60 }
61
62 return $self;
63 }
64
65
66 /**
67 * @since 4.3.0
68 */
69 public function setFormsGoals(array $ids): void
70 {
71 $donations = DonationFormDataQuery::donations($ids);
72
73 $this->formAmounts = $donations->collectIntendedAmounts();
74 $this->formDonationsCount = $donations->collectDonations();
75 $this->formDonorsCount = $donations->collectDonors();
76
77 // Set subscriptions data
78 if (defined('GIVE_RECURRING_VERSION')) {
79 $subscriptions = DonationFormDataQuery::subscriptions($ids);
80
81 $this->formSubscriptionAmounts = $subscriptions->collectInitialAmounts();
82 $this->formSubscriptionDonationsCount = $subscriptions->collectDonations();
83 $this->formSubscriptionDonorsCount = $subscriptions->collectDonors();
84 }
85 }
86
87 /**
88 * @since 4.3.0
89 */
90 public function setFormsCampaignGoals(array $ids): void
91 {
92 $campaigns = DB::table('give_campaign_forms')
93 ->distinct()
94 ->select(['campaign_id', 'id'])
95 ->whereIn('form_id', $ids)
96 ->getAll();
97
98 $ids = array_map(function ($campaign) {
99 return (int)$campaign->id;
100 }, $campaigns);
101
102 $donations = CampaignsDataQuery::donations($ids);
103
104 $this->campaignAmounts = $donations->collectIntendedAmounts();
105 $this->campaignDonationsCount = $donations->collectDonations();
106 $this->campaignDonorsCount = $donations->collectDonors();
107
108 // Set subscriptions data
109 if (defined('GIVE_RECURRING_VERSION')) {
110 $subscriptions = CampaignsDataQuery::subscriptions($ids);
111
112 $this->campaignSubscriptionAmounts = $subscriptions->collectInitialAmounts();
113 $this->campaignSubscriptionDonationsCount = $subscriptions->collectDonations();
114 $this->campaignSubscriptionDonorsCount = $subscriptions->collectDonors();
115 }
116 }
117
118 /**
119 * @since 4.3.0
120 *
121 * Get revenue for form
122 *
123 * @param DonationForm $form
124 *
125 * @return int|float
126 */
127 public function getRevenue(DonationForm $form)
128 {
129 $data = $form->goalSettings->goalType->isAmountFromSubscriptions()
130 ? $this->{$form->goalSettings->goalSource . 'SubscriptionAmounts'}
131 : $this->{$form->goalSettings->goalSource . 'Amounts'};
132
133 $source = $this->getSourceData($form);
134
135 foreach ($data as $row) {
136 if (isset($row[$source['column']]) && $row[$source['column']] == $source['id']) {
137 return $row['sum'];
138 }
139 }
140
141 return 0;
142 }
143
144 /**
145 * @since 4.3.0
146 *
147 * Get donations count for form
148 *
149 * @param DonationForm $form
150 *
151 * @return int
152 */
153 public function getDonationsCount(DonationForm $form): int
154 {
155 $data = $form->goalSettings->goalType->isSubscriptions()
156 ? $this->{$form->goalSettings->goalSource . 'SubscriptionDonationsCount'}
157 : $this->{$form->goalSettings->goalSource . 'DonationsCount'};
158
159 $source = $this->getSourceData($form);
160
161 foreach ($data as $row) {
162 if (isset($row[$source['column']]) && $row[$source['column']] == $source['id']) {
163 return (int)$row['count'];
164 }
165 }
166
167 return 0;
168 }
169
170 /**
171 * @since 4.3.0
172 *
173 * Get donors count for form
174 *
175 * @param DonationForm $form
176 *
177 * @return int
178 */
179 public function getDonorsCount(DonationForm $form): int
180 {
181 $data = $form->goalSettings->goalType->isSubscriptions()
182 ? $this->{$form->goalSettings->goalSource . 'SubscriptionDonorsCount'}
183 : $this->{$form->goalSettings->goalSource . 'DonorsCount'};
184
185 $source = $this->getSourceData($form);
186
187 foreach ($data as $row) {
188 if (isset($row[$source['column']]) && $row[$source['column']] == $source['id']) {
189 return (int)$row['count'];
190 }
191 }
192
193 return 0;
194 }
195
196
197 /**
198 * @since 4.3.0
199 *
200 * Get goal data for form
201 *
202 * @param DonationForm $form
203 *
204 * @return array{actual: int, goal: int, actualFormatted: string, goalFormatted:string, percentage:float}
205 */
206 public function getGoalData(DonationForm $form): array
207 {
208 $actual = $this->getActualGoal($form);
209 $percentage = $form->goalSettings->goalAmount
210 ? $actual / $form->goalSettings->goalAmount
211 : 0;
212
213 $typeIsMoney = $form->goalSettings->goalType->isOneOf(
214 GoalType::AMOUNT(),
215 GoalType::AMOUNT_FROM_SUBSCRIPTIONS(),
216 );
217
218 return [
219 'actual' => $actual,
220 'goal' => $form->goalSettings->goalAmount,
221 'actualFormatted' => $typeIsMoney
222 ? give_currency_filter(give_format_amount($actual))
223 : $actual,
224 'goalFormatted' => $typeIsMoney
225 ? give_currency_filter(give_format_amount($form->goalSettings->goalAmount))
226 : $form->goalSettings->goalAmount,
227 'percentage' => round($percentage * 100, 2),
228 'typeIsMoney' => $typeIsMoney,
229 ];
230 }
231
232 /**
233 * @since 4.3.0
234 *
235 * @param DonationForm $form
236 *
237 * @return int|float
238 */
239 private function getActualGoal(DonationForm $form)
240 {
241 switch ($form->goalSettings->goalType->getValue()) {
242 case GoalType::DONATIONS():
243 case GoalType::SUBSCRIPTIONS():
244 return $this->getDonationsCount($form);
245 case GoalType::DONORS():
246 case GoalType::DONORS_FROM_SUBSCRIPTIONS():
247 return $this->getDonorsCount($form);
248 default:
249 return $this->getRevenue($form);
250 }
251 }
252
253 /**
254 * @param DonationForm $form
255 *
256 * @return array{id: int, column: string}
257 */
258 private function getSourceData(DonationForm $form): array
259 {
260 if ($form->goalSettings->goalSource === GoalSource::CAMPAIGN) {
261 return [
262 'id' => $form->campaignId,
263 'column' => 'campaign_id',
264 ];
265 }
266
267 return [
268 'id' => $form->id,
269 'column' => 'form_id',
270 ];
271 }
272 }
273