<?php
namespace Give\DonationForms\DataTransferObjects;
use Exception;
use Give\DonationForms\Actions\GenerateDonationConfirmationReceiptUrl;
use Give\DonationForms\Actions\GenerateDonationConfirmationReceiptViewRouteUrl;
use Give\DonationForms\Models\DonationForm;
use Give\Donations\Models\Donation;
use Give\Donations\Properties\BillingAddress;
use Give\Donations\ValueObjects\DonationStatus;
use Give\Donations\ValueObjects\DonationType;
use Give\Framework\PaymentGateways\PaymentGateway;
use Give\Framework\PaymentGateways\PaymentGatewayRegister;
use Give\Framework\Support\ValueObjects\Money;
use Give\Subscriptions\Models\Subscription;
use Give\Subscriptions\ValueObjects\SubscriptionMode;
use Give\Subscriptions\ValueObjects\SubscriptionPeriod;
use Give\Subscriptions\ValueObjects\SubscriptionStatus;
class DonateControllerData
{
/**
* @var float
*/
public $amount;
/**
* @var bool|null
*/
public $anonymous;
/**
* @var string
*/
public $gatewayId;
/**
* @var string
*/
public $currency;
/**
* @var string
*/
public $firstName;
/**
* @var string
*/
public $lastName;
/**
* @var string
*/
public $email;
/**
* @var string|null
*/
public $phone;
/**
* @var int
*/
public $wpUserId;
/**
* @var int
*/
public $formId;
/**
* @var string
*/
public $formTitle;
/**
* @var string|null
*/
public $company;
/**
* @var string|null
*/
public $honorific;
/**
* @var string
*/
public $originUrl;
/**
* @var string|null
*/
public $embedId;
/**
* @var bool
*/
public $isEmbed;
/**
* @var DonationType
*/
public $donationType;
/**
* @var SubscriptionPeriod|null
*/
public $subscriptionPeriod;
/**
* @var int|null
*/
public $subscriptionFrequency;
/**
* @var int|null
*/
public $subscriptionInstallments;
/**
* @var string|null
*/
public $country;
/**
* @var string|null
*/
public $address1;
/**
* @var string|null
*/
public $address2;
/**
* @var string|null
*/
public $city;
/**
* @var string|null
*/
public $state;
/**
* @var string|null
*/
public $zip;
/**
* @var string|null
*/
public $comment;
/**
* @since 3.9.0 Added phone property
* @since 3.2.0 added honorific property
* @since 3.0.0
*/
public function toDonation(int $donorId): Donation
{
$form = $this->getDonationForm();
return new Donation([
'status' => DonationStatus::PENDING(),
'gatewayId' => $this->gatewayId,
'amount' => $this->amount(),
'anonymous' => $this->anonymous,
'donorId' => $donorId,
'honorific' => $this->honorific,
'firstName' => $this->firstName,
'lastName' => $this->lastName,
'email' => $this->email,
'phone' => $this->phone,
'formId' => $this->formId,
'formTitle' => $form->title,
'company' => $this->company,
'comment' => $this->comment,
'type' => DonationType::SINGLE(),
'billingAddress' => $this->getBillingAddress(),
]);
}
/**
* @since 3.9.0 Added phone property
* @since 3.0.0
*/
public function toInitialSubscriptionDonation(int $donorId, int $subscriptionId): Donation
{
$form = $this->getDonationForm();
return new Donation([
'status' => DonationStatus::PENDING(),
'gatewayId' => $this->gatewayId,
'amount' => $this->amount(),
'anonymous' => $this->anonymous,
'donorId' => $donorId,
'firstName' => $this->firstName,
'lastName' => $this->lastName,
'email' => $this->email,
'phone' => $this->phone,
'formId' => $this->formId,
'formTitle' => $form->title,
'company' => $this->company,
'comment' => $this->comment,
'type' => DonationType::SUBSCRIPTION(),
'subscriptionId' => $subscriptionId,
'billingAddress' => $this->getBillingAddress(),
]);
}
/**
* @since 3.16.0 Added "givewp_donation_confirmation_page_redirect_enabled" filter
* @since 3.0.0
*/
public function getSuccessUrl(Donation $donation): string
{
$form = $this->getDonationForm();
if (apply_filters('givewp_donation_confirmation_page_redirect_enabled', $form->settings->enableReceiptConfirmationPage, $donation->formId)) {
return $this->getDonationConfirmationPageFromSettings($donation);
}
return $this->isEmbed ?
$this->getDonationConfirmationReceiptUrl($donation) :
$this->getDonationConfirmationReceiptViewRouteUrl($donation);
}
/**
* @since 3.0.0
*
* TODO: add params to route for flash message
*/
public function getCancelUrl(): string
{
return $this->originUrl;
}
/**
* @since 3.0.0
*/
public function getDonationConfirmationReceiptViewRouteUrl(Donation $donation): string
{
return (new GenerateDonationConfirmationReceiptViewRouteUrl())($donation->purchaseKey);
}
/**
* @since 3.0.0
*/
public function getDonationConfirmationReceiptUrl(Donation $donation): string
{
return (new GenerateDonationConfirmationReceiptUrl())($donation, $this->originUrl, $this->embedId);
}
/**
* @since 3.16.0
*/
public function getDonationConfirmationPageFromSettings(Donation $donation): string
{
$settings = give_get_settings();
$page = isset($settings['success_page'])
? get_permalink(absint($settings['success_page']))
: get_bloginfo('url');
$page = apply_filters('givewp_donation_confirmation_page_redirect_permalink', $page, $donation->formId);
return esc_url_raw(add_query_arg(['receipt-id' => $donation->purchaseKey], $page));
}
/**
* @since 3.0.0
*/
public function getDonationForm(): DonationForm
{
return DonationForm::find($this->formId);
}
/**
* This is a hard-coded way of filtering through our dynamic properties
* and only returning custom fields.
*
* TODO: figure out a less static way of doing this
*
* @since 3.0.0
*/
public function getCustomFields(): array
{
$properties = get_object_vars($this);
return array_filter($properties, static function ($param) {
return !in_array(
$param,
array_merge(
Donation::propertyKeys(),
Subscription::propertyKeys(),
[
'currency',
'wpUserId',
'honorific',
'originUrl',
'isEmbed',
'embedId',
'donationType',
'subscriptionPeriod',
'subscriptionFrequency',
'subscriptionInstallments',
'country',
'address1',
'address2',
'city',
'state',
'zip',
]
),
true
);
}, ARRAY_FILTER_USE_KEY);
}
/**
* @since 3.0.0
*
* @throws Exception
*/
public function toSubscription(int $donorId): Subscription
{
return new Subscription([
'amount' => $this->amount(),
'period' => $this->subscriptionPeriod,
'frequency' => (int)$this->subscriptionFrequency,
'donorId' => $donorId,
'installments' => (int)$this->subscriptionInstallments,
'status' => SubscriptionStatus::PENDING(),
'mode' => give_is_test_mode() ? SubscriptionMode::TEST() : SubscriptionMode::LIVE(),
'donationFormId' => $this->formId,
]);
}
/**
* @return Money
*/
public function amount(): Money
{
return Money::fromDecimal($this->amount, $this->currency);
}
/**
* @since 3.0.0
*/
public function getGateway(): PaymentGateway
{
return give(PaymentGatewayRegister::class)->getPaymentGateway($this->gatewayId);
}
/**
* @since 3.0.0
*/
public function getBillingAddress(): BillingAddress
{
return BillingAddress::fromArray([
'country' => $this->country,
'address1' => $this->address1,
'address2' => $this->address2,
'city' => $this->city,
'state' => $this->state,
'zip' => $this->zip,
]);
}
/**
* @since 3.0.0
*/
public function has(string $name): bool
{
return isset($this->{$name});
}
/**
* @since 3.0.0
*
* @return mixed|null
*/
public function get(string $name)
{
return property_exists($this, $name) ? $this->{$name} : null;
}
}