PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.16.9
GiveWP – Donation Plugin and Fundraising Platform v4.16.9
4.16.9 4.16.8.1 4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 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 All 255 releases
← All changes | src/Subscriptions/Repositories/SubscriptionRepository.php +180 -14 2.30.04.16.9 View file →
@@ -2,9 +2,13 @@
2 2
3 3 namespace Give\Subscriptions\Repositories;
4 4
5 5 use Exception;
6 +use Give\Donations\Models\Donation;
6 7 use Give\Donations\ValueObjects\DonationMetaKeys;
8 +use Give\Donations\ValueObjects\DonationMode;
9 +use Give\Donations\ValueObjects\DonationStatus;
10 +use Give\Donations\ValueObjects\DonationType;
7 11 use Give\Framework\Database\DB;
8 12 use Give\Framework\Exceptions\Primitives\InvalidArgumentException;
9 13 use Give\Framework\Models\ModelQueryBuilder;
10 14 use Give\Framework\Support\Facades\DateTime\Temporal;
@@ -11,15 +15,22 @@
11 15 use Give\Helpers\Hooks;
12 16 use Give\Log\Log;
13 17 use Give\Subscriptions\Models\Subscription;
14 18 use Give\Subscriptions\ValueObjects\SubscriptionMode;
19 +use Give\Subscriptions\ValueObjects\SubscriptionStatus;
15 20
16 21 /**
22 + * @since 4.8.0 Add notes repository
17 23 * @since 2.19.6
18 24 */
19 25 class SubscriptionRepository
20 26 {
21 27 /**
28 + * @var SubscriptionNotesRepository
29 + */
30 + public $notes;
31 +
32 + /**
22 33 * @var string[]
23 34 */
24 35 private $requiredSubscriptionProperties = [
25 36 'donorId',
@@ -30,8 +41,16 @@
30 41 'donationFormId',
31 42 ];
32 43
33 44 /**
45 + * @since 4.8.0
46 + */
47 + public function __construct()
48 + {
49 + $this->notes = give(SubscriptionNotesRepository::class);
50 + }
51 +
52 + /**
34 53 * @since 2.19.6
35 54 *
36 55 * @return Subscription|null
37 56 */
@@ -66,16 +85,14 @@
66 85
67 86 /**
68 87 * @since 2.21.0
69 88 *
70 - * @param string $gatewayTransactionId
71 - *
72 89 * @return ModelQueryBuilder<Subscription>
73 90 */
74 - public function queryByGatewaySubscriptionId(string $gatewayTransactionId): ModelQueryBuilder
91 + public function queryByGatewaySubscriptionId(string $gatewaySubscriptionId): ModelQueryBuilder
75 92 {
76 93 return $this->prepareQuery()
77 - ->where('profile_id', $gatewayTransactionId);
94 + ->where('profile_id', $gatewaySubscriptionId);
78 95 }
79 96
80 97 /**
81 98 * @since 2.19.6
@@ -103,8 +120,22 @@
103 120 ->where('customer_id', $donorId);
104 121 }
105 122
106 123 /**
124 + * @since 4.11.0
125 + *
126 + * @param int $campaignId
127 + *
128 + * @return ModelQueryBuilder<Subscription>
129 + */
130 + public function queryByCampaignId(int $campaignId): ModelQueryBuilder
131 + {
132 + return $this->prepareQuery()
133 + ->where('campaign_id', $campaignId);
134 + }
135 +
136 + /**
137 + * @deprecated Use give()->subscriptions->notes()->queryBySubscriptionId()->getAll() instead.
107 138 * @since 2.19.6
108 139 *
109 140 * @return object[]
110 141 */
@@ -109,18 +140,20 @@
109 140 * @return object[]
110 141 */
111 142 public function getNotesBySubscriptionId(int $id): array
112 143 {
113 - $notes = DB::table('comments')
114 - ->select(
115 - ['comment_content', 'note'],
116 - ['comment_date', 'date']
117 - )
118 - ->where('comment_post_ID', $id)
119 - ->where('comment_type', 'give_sub_note')
120 - ->orderBy('comment_date', 'DESC')
121 - ->getAll();
144 + _give_deprecated_function(__METHOD__, '4.6.0', 'give()->subscriptions->notes()->queryBySubscriptionId()->getAll()');
122 145
146 + $notes = array_map(
147 + static function ($note) {
148 + return array_merge($note->toArray(), [
149 + 'note' => $note->comment_content,
150 + 'date' => $note->comment_date,
151 + ]);
152 + },
153 + $this->notes->queryBySubscriptionId($id)->getAll()
154 + );
155 +
123 156 if (!$notes) {
124 157 return [];
125 158 }
126 159
@@ -127,8 +160,9 @@
127 160 return $notes;
128 161 }
129 162
130 163 /**
164 + * @since 4.11.0 add campaign_id column to insert
131 165 * @since 2.24.0 add payment_mode column to insert
132 166 * @since 2.21.0 replace actions with givewp_subscription_creating and givewp_subscription_created
133 167 * @since 2.19.6
134 168 *
@@ -142,8 +176,14 @@
142 176 if ($subscription->renewsAt === null) {
143 177 $subscription->bumpRenewalDate();
144 178 }
145 179
180 + // If the subscription is not associated with a campaign, try to find the campaign ID by the form ID
181 + if (!$subscription->campaignId) {
182 + $campaign = give()->campaigns->getByFormId($subscription->donationFormId);
183 + $subscription->campaignId = $campaign ? $campaign->id : null;
184 + }
185 +
146 186 Hooks::doAction('givewp_subscription_creating', $subscription);
147 187
148 188 $dateCreated = Temporal::withoutMicroseconds($subscription->createdAt ?: Temporal::getCurrentDateTime());
149 189
@@ -164,8 +204,9 @@
164 204 ) : 0,
165 205 'bill_times' => $subscription->installments,
166 206 'transaction_id' => $subscription->transactionId ?? '',
167 207 'product_id' => $subscription->donationFormId,
208 + 'campaign_id' => $subscription->campaignId,
168 209 'payment_mode' => $subscription->mode->getValue(),
169 210 ]);
170 211 } catch (Exception $exception) {
171 212 DB::query('ROLLBACK');
@@ -185,8 +226,10 @@
185 226 Hooks::doAction('givewp_subscription_created', $subscription);
186 227 }
187 228
188 229 /**
230 + * @since 4.11.0 add campaign_id column to update
231 + * @since 3.17.0 add expiration column to update
189 232 * @since 2.24.0 add payment_mode column to update
190 233 * @since 2.21.0 replace actions with givewp_subscription_updating and givewp_subscription_updated
191 234 * @since 2.19.6
192 235 *
@@ -208,8 +251,9 @@
208 251 try {
209 252 DB::table('give_subscriptions')
210 253 ->where('id', $subscription->id)
211 254 ->update([
255 + 'expiration' => Temporal::getFormattedDateTime($subscription->renewsAt),
212 256 'status' => $subscription->status->getValue(),
213 257 'profile_id' => $subscription->gatewaySubscriptionId,
214 258 'customer_id' => $subscription->donorId,
215 259 'period' => $subscription->period->getValue(),
@@ -220,8 +264,9 @@
220 264 ) : 0,
221 265 'bill_times' => $subscription->installments,
222 266 'transaction_id' => $subscription->transactionId ?? '',
223 267 'product_id' => $subscription->donationFormId,
268 + 'campaign_id' => $subscription->campaignId,
224 269 'payment_mode' => $subscription->mode->getValue(),
225 270 ]);
226 271 } catch (Exception $exception) {
227 272 DB::query('ROLLBACK');
@@ -272,8 +317,82 @@
272 317 return true;
273 318 }
274 319
275 320 /**
321 + * @since 4.8.0
322 + *
323 + * @throws Exception
324 + */
325 + public function trash(Subscription $subscription): bool
326 + {
327 + DB::query('START TRANSACTION');
328 +
329 + Hooks::doAction('givewp_subscription_trashing', $subscription);
330 +
331 + try {
332 + $previousStatus = DB::table('give_subscriptions')
333 + ->where('id', $subscription->id)
334 + ->value('status');
335 +
336 + give()->subscription_meta->update_meta($subscription->id, '_wp_trash_meta_status', $previousStatus);
337 + give()->subscription_meta->update_meta($subscription->id, '_wp_trash_meta_time', time());
338 +
339 + DB::table('give_subscriptions')
340 + ->where('id', $subscription->id)
341 + ->update(['status' => SubscriptionStatus::TRASHED()->getValue()]);
342 + } catch (Exception $exception) {
343 + DB::query('ROLLBACK');
344 +
345 + Log::error('Failed trashing a subscription', compact('subscription'));
346 +
347 + throw new $exception('Failed trashing a subscription');
348 + }
349 +
350 + DB::query('COMMIT');
351 +
352 + Hooks::doAction('givewp_subscription_trashed', $subscription);
353 +
354 + return true;
355 + }
356 +
357 + /**
358 + * @since 4.12.0
359 + *
360 + * @throws Exception
361 + */
362 + public function unTrash(Subscription $subscription): bool
363 + {
364 + DB::query('START TRANSACTION');
365 +
366 + Hooks::doAction('givewp_subscription_untrashing', $subscription);
367 +
368 + try {
369 + $previousStatus = give()->subscription_meta->get_meta($subscription->id, '_wp_trash_meta_status', true);
370 +
371 + // If no previous status was saved, default to 'active'
372 + if (empty($previousStatus)) {
373 + $previousStatus = SubscriptionStatus::ACTIVE;
374 + }
375 +
376 + DB::table('give_subscriptions')
377 + ->where('id', $subscription->id)
378 + ->update(['status' => $previousStatus]);
379 + } catch (Exception $exception) {
380 + DB::query('ROLLBACK');
381 +
382 + Log::error('Failed untrashing a subscription', compact('subscription'));
383 +
384 + throw new $exception('Failed untrashing a subscription');
385 + }
386 +
387 + DB::query('COMMIT');
388 +
389 + Hooks::doAction('givewp_subscription_untrashed', $subscription);
390 +
391 + return true;
392 + }
393 +
394 + /**
276 395 * Up to this point the donation is created first and then the subscription, and the donation is stored as the
277 396 * parent_payment_id of the subscription. This is backwards and should not be the case. But legacy code depends on
278 397 * this value, so we still need to store it for now.
279 398 *
@@ -373,8 +492,53 @@
373 492 return (int)$query->ID;
374 493 }
375 494
376 495 /**
496 + * @since 4.11.0 add campaignId to renewal
497 + * @since 4.8.1 Remove campaignId from the attributes array since it is auto-generated based on the subscription's form.
498 + * @since 4.8.0 Add campaignId support.
499 + * @since 3.20.0
500 + * @throws Exception
501 + */
502 + public function createRenewal(Subscription $subscription, array $attributes = []): Donation
503 + {
504 + $initialDonation = $subscription->initialDonation();
505 +
506 + $donation = Donation::create(
507 + array_merge([
508 + 'subscriptionId' => $subscription->id,
509 + 'gatewayId' => $subscription->gatewayId,
510 + 'amount' => $subscription->amount,
511 + 'status' => DonationStatus::COMPLETE(),
512 + 'type' => DonationType::RENEWAL(),
513 + 'donorId' => $subscription->donorId,
514 + 'formId' => $subscription->donationFormId,
515 + 'honorific' => $initialDonation->honorific,
516 + 'firstName' => $initialDonation->firstName,
517 + 'lastName' => $initialDonation->lastName,
518 + 'email' => $initialDonation->email,
519 + 'phone' => $initialDonation->phone,
520 + 'anonymous' => $initialDonation->anonymous,
521 + 'levelId' => $initialDonation->levelId,
522 + 'company' => $initialDonation->company,
523 + 'comment' => $initialDonation->comment,
524 + 'billingAddress' => $initialDonation->billingAddress,
525 + 'feeAmountRecovered' => $subscription->feeAmountRecovered,
526 + 'exchangeRate' => $initialDonation->exchangeRate,
527 + 'formTitle' => $initialDonation->formTitle,
528 + 'mode' => $subscription->mode->isLive() ? DonationMode::LIVE() : DonationMode::TEST(),
529 + 'donorIp' => $initialDonation->donorIp,
530 + 'campaignId' => $subscription->campaignId,
531 + ], $attributes)
532 + );
533 +
534 + $subscription->bumpRenewalDate();
535 + $subscription->save();
536 +
537 + return $donation;
538 + }
539 +
540 + /**
377 541 * @since 2.19.6
378 542 *
379 543 * @return void
380 544 */
@@ -391,8 +555,9 @@
391 555 }
392 556 }
393 557
394 558 /**
559 + * @since 4.11.0 add campaign_id column to select
395 560 * @since 2.19.6
396 561 *
397 562 * @return ModelQueryBuilder<Subscription>
398 563 */
@@ -414,9 +579,10 @@
414 579 ['recurring_amount', 'amount'],
415 580 ['recurring_fee_amount', 'feeAmount'],
416 581 'status',
417 582 ['profile_id', 'gatewaySubscriptionId'],
418 - ['product_id', 'donationFormId']
583 + ['product_id', 'donationFormId'],
584 + ['campaign_id', 'campaignId']
419 585 )
420 586 ->attachMeta(
421 587 'give_donationmeta',
422 588 'parent_payment_id',