<?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; } }